@naylence/runtime 0.3.21 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.cjs +3368 -1393
- package/dist/browser/index.mjs +3324 -1387
- package/dist/cjs/naylence/fame/factory-manifest.js +8 -0
- package/dist/cjs/naylence/fame/node/node-event-listener.js +4 -0
- package/dist/cjs/naylence/fame/security/auth/authorization-profile-factory.js +165 -0
- package/dist/cjs/naylence/fame/security/auth/default-policy-authorizer-factory.js +147 -0
- package/dist/cjs/naylence/fame/security/auth/default-policy-authorizer.js +291 -0
- package/dist/cjs/naylence/fame/security/auth/oauth2-authorizer-factory.js +7 -0
- package/dist/cjs/naylence/fame/security/auth/oauth2-authorizer.js +19 -4
- package/dist/cjs/naylence/fame/security/auth/policy/authorization-policy-definition.js +60 -0
- package/dist/cjs/naylence/fame/security/auth/policy/authorization-policy-factory.js +35 -0
- package/dist/cjs/naylence/fame/security/auth/policy/authorization-policy-source-factory.js +35 -0
- package/dist/cjs/naylence/fame/security/auth/policy/authorization-policy-source.js +2 -0
- package/dist/cjs/naylence/fame/security/auth/policy/authorization-policy.js +2 -0
- package/dist/cjs/naylence/fame/security/auth/policy/basic-authorization-policy-factory.js +99 -0
- package/dist/cjs/naylence/fame/security/auth/policy/basic-authorization-policy.js +449 -0
- package/dist/cjs/naylence/fame/security/auth/policy/index.js +40 -0
- package/dist/cjs/naylence/fame/security/auth/policy/local-file-authorization-policy-source-factory.js +101 -0
- package/dist/cjs/naylence/fame/security/auth/policy/local-file-authorization-policy-source.js +164 -0
- package/dist/cjs/naylence/fame/security/auth/policy/pattern-matcher.js +195 -0
- package/dist/cjs/naylence/fame/security/auth/policy/scope-matcher.js +169 -0
- package/dist/cjs/naylence/fame/security/auth/policy-authorizer.js +2 -0
- package/dist/cjs/naylence/fame/security/default-security-manager.js +94 -0
- package/dist/cjs/naylence/fame/security/index.js +22 -1
- package/dist/cjs/naylence/fame/security/node-security-profile-factory.js +15 -73
- package/dist/cjs/naylence/fame/sentinel/router.js +67 -1
- package/dist/cjs/naylence/fame/sentinel/sentinel.js +46 -2
- package/dist/cjs/naylence/fame/util/register-runtime-factories.js +2 -0
- package/dist/cjs/version.js +2 -2
- package/dist/esm/naylence/fame/factory-manifest.js +8 -0
- package/dist/esm/naylence/fame/node/node-event-listener.js +4 -0
- package/dist/esm/naylence/fame/security/auth/authorization-profile-factory.js +161 -0
- package/dist/esm/naylence/fame/security/auth/default-policy-authorizer-factory.js +110 -0
- package/dist/esm/naylence/fame/security/auth/default-policy-authorizer.js +287 -0
- package/dist/esm/naylence/fame/security/auth/oauth2-authorizer-factory.js +7 -0
- package/dist/esm/naylence/fame/security/auth/oauth2-authorizer.js +19 -4
- package/dist/esm/naylence/fame/security/auth/policy/authorization-policy-definition.js +57 -0
- package/dist/esm/naylence/fame/security/auth/policy/authorization-policy-factory.js +31 -0
- package/dist/esm/naylence/fame/security/auth/policy/authorization-policy-source-factory.js +31 -0
- package/dist/esm/naylence/fame/security/auth/policy/authorization-policy-source.js +1 -0
- package/dist/esm/naylence/fame/security/auth/policy/authorization-policy.js +1 -0
- package/dist/esm/naylence/fame/security/auth/policy/basic-authorization-policy-factory.js +62 -0
- package/dist/esm/naylence/fame/security/auth/policy/basic-authorization-policy.js +445 -0
- package/dist/esm/naylence/fame/security/auth/policy/index.js +20 -0
- package/dist/esm/naylence/fame/security/auth/policy/local-file-authorization-policy-source-factory.js +64 -0
- package/dist/esm/naylence/fame/security/auth/policy/local-file-authorization-policy-source.js +127 -0
- package/dist/esm/naylence/fame/security/auth/policy/pattern-matcher.js +185 -0
- package/dist/esm/naylence/fame/security/auth/policy/scope-matcher.js +162 -0
- package/dist/esm/naylence/fame/security/auth/policy-authorizer.js +1 -0
- package/dist/esm/naylence/fame/security/default-security-manager.js +94 -0
- package/dist/esm/naylence/fame/security/index.js +5 -1
- package/dist/esm/naylence/fame/security/node-security-profile-factory.js +14 -72
- package/dist/esm/naylence/fame/sentinel/router.js +64 -0
- package/dist/esm/naylence/fame/sentinel/sentinel.js +47 -3
- package/dist/esm/naylence/fame/util/register-runtime-factories.js +2 -0
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +3364 -1389
- package/dist/node/index.mjs +3324 -1387
- package/dist/node/node.cjs +3416 -1425
- package/dist/node/node.mjs +3376 -1423
- package/dist/types/naylence/fame/factory-manifest.d.ts +1 -1
- package/dist/types/naylence/fame/node/node-event-listener.d.ts +31 -0
- package/dist/types/naylence/fame/security/auth/authorization-profile-factory.d.ts +29 -0
- package/dist/types/naylence/fame/security/auth/authorizer.d.ts +37 -0
- package/dist/types/naylence/fame/security/auth/default-policy-authorizer-factory.d.ts +55 -0
- package/dist/types/naylence/fame/security/auth/default-policy-authorizer.d.ts +99 -0
- package/dist/types/naylence/fame/security/auth/oauth2-authorizer-factory.d.ts +2 -0
- package/dist/types/naylence/fame/security/auth/oauth2-authorizer.d.ts +2 -0
- package/dist/types/naylence/fame/security/auth/policy/authorization-policy-definition.d.ts +166 -0
- package/dist/types/naylence/fame/security/auth/policy/authorization-policy-factory.d.ts +38 -0
- package/dist/types/naylence/fame/security/auth/policy/authorization-policy-source-factory.d.ts +38 -0
- package/dist/types/naylence/fame/security/auth/policy/authorization-policy-source.d.ts +20 -0
- package/dist/types/naylence/fame/security/auth/policy/authorization-policy.d.ts +55 -0
- package/dist/types/naylence/fame/security/auth/policy/basic-authorization-policy-factory.d.ts +42 -0
- package/dist/types/naylence/fame/security/auth/policy/basic-authorization-policy.d.ts +78 -0
- package/dist/types/naylence/fame/security/auth/policy/index.d.ts +19 -0
- package/dist/types/naylence/fame/security/auth/policy/local-file-authorization-policy-source-factory.d.ts +51 -0
- package/dist/types/naylence/fame/security/auth/policy/local-file-authorization-policy-source.d.ts +67 -0
- package/dist/types/naylence/fame/security/auth/policy/pattern-matcher.d.ts +84 -0
- package/dist/types/naylence/fame/security/auth/policy/scope-matcher.d.ts +61 -0
- package/dist/types/naylence/fame/security/auth/policy-authorizer.d.ts +12 -0
- package/dist/types/naylence/fame/security/default-security-manager.d.ts +22 -0
- package/dist/types/naylence/fame/security/index.d.ts +5 -1
- package/dist/types/naylence/fame/security/node-security-profile-factory.d.ts +2 -0
- package/dist/types/naylence/fame/sentinel/router.d.ts +68 -0
- package/dist/types/naylence/fame/sentinel/sentinel.d.ts +16 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -63,8 +63,10 @@ exports.MODULES = [
|
|
|
63
63
|
"./node/node-identity-policy-profile-factory.js",
|
|
64
64
|
"./node/token-subject-node-identity-policy-factory.js",
|
|
65
65
|
"./placement/static-node-placement-strategy-factory.js",
|
|
66
|
+
"./security/auth/authorization-profile-factory.js",
|
|
66
67
|
"./security/auth/bearer-token-header-auth-injection-strategy-factory.js",
|
|
67
68
|
"./security/auth/default-authorizer-factory.js",
|
|
69
|
+
"./security/auth/default-policy-authorizer-factory.js",
|
|
68
70
|
"./security/auth/jwks-jwt-token-verifier-factory.js",
|
|
69
71
|
"./security/auth/jwt-token-issuer-factory.js",
|
|
70
72
|
"./security/auth/jwt-token-verifier-factory.js",
|
|
@@ -76,6 +78,8 @@ exports.MODULES = [
|
|
|
76
78
|
"./security/auth/oauth2-authorizer-factory.js",
|
|
77
79
|
"./security/auth/oauth2-client-credentials-token-provider-factory.js",
|
|
78
80
|
"./security/auth/oauth2-pkce-token-provider-factory.js",
|
|
81
|
+
"./security/auth/policy/basic-authorization-policy-factory.js",
|
|
82
|
+
"./security/auth/policy/local-file-authorization-policy-source-factory.js",
|
|
79
83
|
"./security/auth/query-param-auth-injection-strategy-factory.js",
|
|
80
84
|
"./security/auth/shared-secret-authorizer-factory.js",
|
|
81
85
|
"./security/auth/shared-secret-token-provider-factory.js",
|
|
@@ -142,8 +146,10 @@ exports.MODULE_LOADERS = {
|
|
|
142
146
|
"./node/node-identity-policy-profile-factory.js": () => Promise.resolve().then(() => __importStar(require("./node/node-identity-policy-profile-factory.js"))),
|
|
143
147
|
"./node/token-subject-node-identity-policy-factory.js": () => Promise.resolve().then(() => __importStar(require("./node/token-subject-node-identity-policy-factory.js"))),
|
|
144
148
|
"./placement/static-node-placement-strategy-factory.js": () => Promise.resolve().then(() => __importStar(require("./placement/static-node-placement-strategy-factory.js"))),
|
|
149
|
+
"./security/auth/authorization-profile-factory.js": () => Promise.resolve().then(() => __importStar(require("./security/auth/authorization-profile-factory.js"))),
|
|
145
150
|
"./security/auth/bearer-token-header-auth-injection-strategy-factory.js": () => Promise.resolve().then(() => __importStar(require("./security/auth/bearer-token-header-auth-injection-strategy-factory.js"))),
|
|
146
151
|
"./security/auth/default-authorizer-factory.js": () => Promise.resolve().then(() => __importStar(require("./security/auth/default-authorizer-factory.js"))),
|
|
152
|
+
"./security/auth/default-policy-authorizer-factory.js": () => Promise.resolve().then(() => __importStar(require(/* webpackIgnore: true */ /* @vite-ignore */ "./security/auth/default-policy-authorizer-factory.js"))),
|
|
147
153
|
"./security/auth/jwks-jwt-token-verifier-factory.js": () => Promise.resolve().then(() => __importStar(require("./security/auth/jwks-jwt-token-verifier-factory.js"))),
|
|
148
154
|
"./security/auth/jwt-token-issuer-factory.js": () => Promise.resolve().then(() => __importStar(require("./security/auth/jwt-token-issuer-factory.js"))),
|
|
149
155
|
"./security/auth/jwt-token-verifier-factory.js": () => Promise.resolve().then(() => __importStar(require("./security/auth/jwt-token-verifier-factory.js"))),
|
|
@@ -155,6 +161,8 @@ exports.MODULE_LOADERS = {
|
|
|
155
161
|
"./security/auth/oauth2-authorizer-factory.js": () => Promise.resolve().then(() => __importStar(require("./security/auth/oauth2-authorizer-factory.js"))),
|
|
156
162
|
"./security/auth/oauth2-client-credentials-token-provider-factory.js": () => Promise.resolve().then(() => __importStar(require("./security/auth/oauth2-client-credentials-token-provider-factory.js"))),
|
|
157
163
|
"./security/auth/oauth2-pkce-token-provider-factory.js": () => Promise.resolve().then(() => __importStar(require("./security/auth/oauth2-pkce-token-provider-factory.js"))),
|
|
164
|
+
"./security/auth/policy/basic-authorization-policy-factory.js": () => Promise.resolve().then(() => __importStar(require("./security/auth/policy/basic-authorization-policy-factory.js"))),
|
|
165
|
+
"./security/auth/policy/local-file-authorization-policy-source-factory.js": () => Promise.resolve().then(() => __importStar(require(/* webpackIgnore: true */ /* @vite-ignore */ "./security/auth/policy/local-file-authorization-policy-source-factory.js"))),
|
|
158
166
|
"./security/auth/query-param-auth-injection-strategy-factory.js": () => Promise.resolve().then(() => __importStar(require("./security/auth/query-param-auth-injection-strategy-factory.js"))),
|
|
159
167
|
"./security/auth/shared-secret-authorizer-factory.js": () => Promise.resolve().then(() => __importStar(require("./security/auth/shared-secret-authorizer-factory.js"))),
|
|
160
168
|
"./security/auth/shared-secret-token-provider-factory.js": () => Promise.resolve().then(() => __importStar(require("./security/auth/shared-secret-token-provider-factory.js"))),
|
|
@@ -48,6 +48,10 @@ class BaseNodeEventListener {
|
|
|
48
48
|
// Default implementation passes envelope through unchanged
|
|
49
49
|
return envelope;
|
|
50
50
|
}
|
|
51
|
+
async onRoutingActionSelected(_node, _envelope, selected, _state, _context) {
|
|
52
|
+
// Default implementation returns the selected action unchanged
|
|
53
|
+
return selected;
|
|
54
|
+
}
|
|
51
55
|
async onForwardUpstream(_node, envelope, _context) {
|
|
52
56
|
// Default implementation passes envelope through unchanged
|
|
53
57
|
return envelope;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthorizationProfileFactory = exports.FACTORY_META = exports.ENV_VAR_HMAC_SECRET = exports.ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE = exports.ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER = exports.ENV_VAR_TRUSTED_CLIENT_SCOPE = exports.ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY = exports.ENV_VAR_JWKS_URL = exports.ENV_VAR_JWT_AUDIENCE = exports.ENV_VAR_JWT_ALGORITHM = exports.ENV_VAR_JWT_TRUSTED_ISSUER = exports.PROFILE_NAME_NOOP = exports.PROFILE_NAME_OAUTH2_CALLBACK = exports.PROFILE_NAME_OAUTH2_GATED = exports.PROFILE_NAME_OAUTH2 = exports.PROFILE_NAME_DEFAULT = void 0;
|
|
4
|
+
const factory_1 = require("@naylence/factory");
|
|
5
|
+
const logging_js_1 = require("../../util/logging.js");
|
|
6
|
+
const authorizer_factory_js_1 = require("./authorizer-factory.js");
|
|
7
|
+
const logger = (0, logging_js_1.getLogger)('naylence.fame.security.auth.authorization_profile_factory');
|
|
8
|
+
exports.PROFILE_NAME_DEFAULT = 'jwt';
|
|
9
|
+
exports.PROFILE_NAME_OAUTH2 = 'oauth2';
|
|
10
|
+
exports.PROFILE_NAME_OAUTH2_GATED = 'oauth2-gated';
|
|
11
|
+
exports.PROFILE_NAME_OAUTH2_CALLBACK = 'oauth2-callback';
|
|
12
|
+
exports.PROFILE_NAME_NOOP = 'noop';
|
|
13
|
+
exports.ENV_VAR_JWT_TRUSTED_ISSUER = 'FAME_JWT_TRUSTED_ISSUER';
|
|
14
|
+
exports.ENV_VAR_JWT_ALGORITHM = 'FAME_JWT_ALGORITHM';
|
|
15
|
+
exports.ENV_VAR_JWT_AUDIENCE = 'FAME_JWT_AUDIENCE';
|
|
16
|
+
exports.ENV_VAR_JWKS_URL = 'FAME_JWKS_URL';
|
|
17
|
+
exports.ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY = 'FAME_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY';
|
|
18
|
+
exports.ENV_VAR_TRUSTED_CLIENT_SCOPE = 'FAME_TRUSTED_CLIENT_SCOPE';
|
|
19
|
+
exports.ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER = 'FAME_JWT_REVERSE_AUTH_TRUSTED_ISSUER';
|
|
20
|
+
exports.ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE = 'FAME_JWT_REVERSE_AUTH_AUDIENCE';
|
|
21
|
+
exports.ENV_VAR_HMAC_SECRET = 'FAME_HMAC_SECRET';
|
|
22
|
+
const DEFAULT_REVERSE_AUTH_ISSUER = 'reverse-auth.naylence.ai';
|
|
23
|
+
const DEFAULT_REVERSE_AUTH_AUDIENCE = 'dev.naylence.ai';
|
|
24
|
+
const DEFAULT_PROFILE = {
|
|
25
|
+
type: 'DefaultAuthorizer',
|
|
26
|
+
verifier: {
|
|
27
|
+
type: 'JWKSJWTTokenVerifier',
|
|
28
|
+
jwks_url: factory_1.Expressions.env(exports.ENV_VAR_JWKS_URL),
|
|
29
|
+
issuer: factory_1.Expressions.env(exports.ENV_VAR_JWT_TRUSTED_ISSUER),
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
const OAUTH2_PROFILE = {
|
|
33
|
+
type: 'OAuth2Authorizer',
|
|
34
|
+
issuer: factory_1.Expressions.env(exports.ENV_VAR_JWT_TRUSTED_ISSUER),
|
|
35
|
+
required_scopes: ['node.connect'],
|
|
36
|
+
require_scope: true,
|
|
37
|
+
default_ttl_sec: 3600,
|
|
38
|
+
max_ttl_sec: 86400,
|
|
39
|
+
algorithm: factory_1.Expressions.env(exports.ENV_VAR_JWT_ALGORITHM, 'RS256'),
|
|
40
|
+
audience: factory_1.Expressions.env(exports.ENV_VAR_JWT_AUDIENCE),
|
|
41
|
+
};
|
|
42
|
+
const OAUTH2_GATED_PROFILE = {
|
|
43
|
+
...OAUTH2_PROFILE,
|
|
44
|
+
enforce_token_subject_node_identity: factory_1.Expressions.env(exports.ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY, 'false'),
|
|
45
|
+
trusted_client_scope: factory_1.Expressions.env(exports.ENV_VAR_TRUSTED_CLIENT_SCOPE, 'node.trusted'),
|
|
46
|
+
};
|
|
47
|
+
const OAUTH2_CALLBACK_PROFILE = {
|
|
48
|
+
type: 'OAuth2Authorizer',
|
|
49
|
+
issuer: factory_1.Expressions.env(exports.ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, DEFAULT_REVERSE_AUTH_ISSUER),
|
|
50
|
+
audience: factory_1.Expressions.env(exports.ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE),
|
|
51
|
+
require_scope: true,
|
|
52
|
+
default_ttl_sec: 3600,
|
|
53
|
+
max_ttl_sec: 86400,
|
|
54
|
+
reverse_auth_ttl_sec: 86400,
|
|
55
|
+
token_verifier_config: {
|
|
56
|
+
type: 'JWTTokenVerifier',
|
|
57
|
+
algorithm: 'HS256',
|
|
58
|
+
hmac_secret: factory_1.Expressions.env(exports.ENV_VAR_HMAC_SECRET),
|
|
59
|
+
issuer: factory_1.Expressions.env(exports.ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, DEFAULT_REVERSE_AUTH_ISSUER),
|
|
60
|
+
ttl_sec: 86400,
|
|
61
|
+
},
|
|
62
|
+
token_issuer_config: {
|
|
63
|
+
type: 'JWTTokenIssuer',
|
|
64
|
+
algorithm: 'HS256',
|
|
65
|
+
hmac_secret: factory_1.Expressions.env(exports.ENV_VAR_HMAC_SECRET),
|
|
66
|
+
kid: 'hmac-reverse-auth-key',
|
|
67
|
+
issuer: factory_1.Expressions.env(exports.ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, DEFAULT_REVERSE_AUTH_ISSUER),
|
|
68
|
+
ttl_sec: 86400,
|
|
69
|
+
audience: factory_1.Expressions.env(exports.ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE, DEFAULT_REVERSE_AUTH_AUDIENCE),
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
const NOOP_PROFILE = {
|
|
73
|
+
type: 'NoopAuthorizer',
|
|
74
|
+
};
|
|
75
|
+
const PROFILE_MAP = {
|
|
76
|
+
[exports.PROFILE_NAME_DEFAULT]: DEFAULT_PROFILE,
|
|
77
|
+
[exports.PROFILE_NAME_OAUTH2]: OAUTH2_PROFILE,
|
|
78
|
+
[exports.PROFILE_NAME_OAUTH2_GATED]: OAUTH2_GATED_PROFILE,
|
|
79
|
+
[exports.PROFILE_NAME_OAUTH2_CALLBACK]: OAUTH2_CALLBACK_PROFILE,
|
|
80
|
+
[exports.PROFILE_NAME_NOOP]: NOOP_PROFILE,
|
|
81
|
+
};
|
|
82
|
+
const PROFILE_ALIASES = {
|
|
83
|
+
jwt: exports.PROFILE_NAME_DEFAULT,
|
|
84
|
+
jwks: exports.PROFILE_NAME_DEFAULT,
|
|
85
|
+
default: exports.PROFILE_NAME_DEFAULT,
|
|
86
|
+
oauth2: exports.PROFILE_NAME_OAUTH2,
|
|
87
|
+
oidc: exports.PROFILE_NAME_OAUTH2,
|
|
88
|
+
'oauth2-gated': exports.PROFILE_NAME_OAUTH2_GATED,
|
|
89
|
+
oauth2_gated: exports.PROFILE_NAME_OAUTH2_GATED,
|
|
90
|
+
'oauth2-callback': exports.PROFILE_NAME_OAUTH2_CALLBACK,
|
|
91
|
+
oauth2_callback: exports.PROFILE_NAME_OAUTH2_CALLBACK,
|
|
92
|
+
'reverse-auth': exports.PROFILE_NAME_OAUTH2_CALLBACK,
|
|
93
|
+
noop: exports.PROFILE_NAME_NOOP,
|
|
94
|
+
'no-op': exports.PROFILE_NAME_NOOP,
|
|
95
|
+
no_op: exports.PROFILE_NAME_NOOP,
|
|
96
|
+
};
|
|
97
|
+
exports.FACTORY_META = {
|
|
98
|
+
base: authorizer_factory_js_1.AUTHORIZER_FACTORY_BASE_TYPE,
|
|
99
|
+
key: 'AuthorizationProfile',
|
|
100
|
+
};
|
|
101
|
+
class AuthorizationProfileFactory extends authorizer_factory_js_1.AuthorizerFactory {
|
|
102
|
+
constructor() {
|
|
103
|
+
super(...arguments);
|
|
104
|
+
this.type = 'AuthorizationProfile';
|
|
105
|
+
}
|
|
106
|
+
async create(config, ...factoryArgs) {
|
|
107
|
+
const normalized = normalizeConfig(config);
|
|
108
|
+
const profileConfig = resolveProfileConfig(normalized.profile);
|
|
109
|
+
logger.debug('enabling_authorization_profile', {
|
|
110
|
+
profile: normalized.profile,
|
|
111
|
+
});
|
|
112
|
+
const authorizer = await authorizer_factory_js_1.AuthorizerFactory.createAuthorizer(profileConfig, { factoryArgs });
|
|
113
|
+
if (!authorizer) {
|
|
114
|
+
throw new Error(`Failed to create authorizer for profile: ${normalized.profile}`);
|
|
115
|
+
}
|
|
116
|
+
return authorizer;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.AuthorizationProfileFactory = AuthorizationProfileFactory;
|
|
120
|
+
function normalizeConfig(config) {
|
|
121
|
+
if (!config) {
|
|
122
|
+
return { profile: exports.PROFILE_NAME_OAUTH2 };
|
|
123
|
+
}
|
|
124
|
+
const candidate = config;
|
|
125
|
+
const profileValue = resolveProfileName(candidate);
|
|
126
|
+
const canonicalProfile = canonicalizeProfileName(profileValue);
|
|
127
|
+
candidate.profile = canonicalProfile;
|
|
128
|
+
return { profile: canonicalProfile };
|
|
129
|
+
}
|
|
130
|
+
function resolveProfileName(candidate) {
|
|
131
|
+
const direct = coerceProfileString(candidate.profile);
|
|
132
|
+
if (direct) {
|
|
133
|
+
return direct;
|
|
134
|
+
}
|
|
135
|
+
const legacyKeys = ['profile_name', 'profileName'];
|
|
136
|
+
for (const legacyKey of legacyKeys) {
|
|
137
|
+
const legacyValue = coerceProfileString(candidate[legacyKey]);
|
|
138
|
+
if (legacyValue) {
|
|
139
|
+
return legacyValue;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return exports.PROFILE_NAME_OAUTH2;
|
|
143
|
+
}
|
|
144
|
+
function coerceProfileString(value) {
|
|
145
|
+
if (typeof value !== 'string') {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
const trimmed = value.trim();
|
|
149
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
150
|
+
}
|
|
151
|
+
function canonicalizeProfileName(value) {
|
|
152
|
+
const normalized = value.replace(/[\s_]+/g, '-').toLowerCase();
|
|
153
|
+
return PROFILE_ALIASES[normalized] ?? normalized;
|
|
154
|
+
}
|
|
155
|
+
function resolveProfileConfig(profileName) {
|
|
156
|
+
const profile = PROFILE_MAP[profileName];
|
|
157
|
+
if (!profile) {
|
|
158
|
+
throw new Error(`Unknown authorization profile: ${profileName}`);
|
|
159
|
+
}
|
|
160
|
+
return deepClone(profile);
|
|
161
|
+
}
|
|
162
|
+
function deepClone(value) {
|
|
163
|
+
return JSON.parse(JSON.stringify(value));
|
|
164
|
+
}
|
|
165
|
+
exports.default = AuthorizationProfileFactory;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.DefaultPolicyAuthorizerFactory = exports.FACTORY_META = void 0;
|
|
37
|
+
const lazy_import_js_1 = require("../../util/lazy-import.js");
|
|
38
|
+
const authorizer_factory_js_1 = require("./authorizer-factory.js");
|
|
39
|
+
const token_verifier_factory_js_1 = require("./token-verifier-factory.js");
|
|
40
|
+
const authorization_policy_source_factory_js_1 = require("./policy/authorization-policy-source-factory.js");
|
|
41
|
+
const authorization_policy_factory_js_1 = require("./policy/authorization-policy-factory.js");
|
|
42
|
+
let defaultPolicyAuthorizerModulePromise = null;
|
|
43
|
+
async function getDefaultPolicyAuthorizerModule() {
|
|
44
|
+
if (!defaultPolicyAuthorizerModulePromise) {
|
|
45
|
+
defaultPolicyAuthorizerModulePromise = (0, lazy_import_js_1.safeImport)(() => Promise.resolve().then(() => __importStar(require('./default-policy-authorizer.js'))), 'default-policy-authorizer');
|
|
46
|
+
}
|
|
47
|
+
return defaultPolicyAuthorizerModulePromise;
|
|
48
|
+
}
|
|
49
|
+
function normalizeConfig(config) {
|
|
50
|
+
if (!config) {
|
|
51
|
+
return {};
|
|
52
|
+
}
|
|
53
|
+
const candidate = config;
|
|
54
|
+
const verifierConfig = candidate.verifier ?? null;
|
|
55
|
+
if (verifierConfig && typeof verifierConfig !== 'object') {
|
|
56
|
+
throw new Error('PolicyAuthorizer verifier configuration must be an object');
|
|
57
|
+
}
|
|
58
|
+
const policyConfig = candidate.policy ?? null;
|
|
59
|
+
if (policyConfig && typeof policyConfig !== 'object') {
|
|
60
|
+
throw new Error('PolicyAuthorizer policy configuration must be an object');
|
|
61
|
+
}
|
|
62
|
+
const policySourceConfig = candidate.policySource ?? candidate.policy_source ?? null;
|
|
63
|
+
if (policySourceConfig && typeof policySourceConfig !== 'object') {
|
|
64
|
+
throw new Error('PolicyAuthorizer policySource configuration must be an object');
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
verifier: verifierConfig,
|
|
68
|
+
policy: policyConfig,
|
|
69
|
+
policySource: policySourceConfig,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function isTokenVerifier(candidate) {
|
|
73
|
+
return Boolean(candidate && typeof candidate.verify === 'function');
|
|
74
|
+
}
|
|
75
|
+
function isAuthorizationPolicy(candidate) {
|
|
76
|
+
return Boolean(candidate &&
|
|
77
|
+
typeof candidate.evaluateRequest === 'function');
|
|
78
|
+
}
|
|
79
|
+
function isAuthorizationPolicySource(candidate) {
|
|
80
|
+
return Boolean(candidate &&
|
|
81
|
+
typeof candidate.loadPolicy === 'function');
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Factory metadata for registration.
|
|
85
|
+
*/
|
|
86
|
+
exports.FACTORY_META = {
|
|
87
|
+
base: authorizer_factory_js_1.AUTHORIZER_FACTORY_BASE_TYPE,
|
|
88
|
+
key: 'PolicyAuthorizer',
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Factory for creating DefaultPolicyAuthorizer instances.
|
|
92
|
+
*
|
|
93
|
+
* This factory uses lazy loading to avoid pulling in Node.js-specific
|
|
94
|
+
* code in browser environments.
|
|
95
|
+
*/
|
|
96
|
+
class DefaultPolicyAuthorizerFactory extends authorizer_factory_js_1.AuthorizerFactory {
|
|
97
|
+
constructor() {
|
|
98
|
+
super(...arguments);
|
|
99
|
+
this.type = 'PolicyAuthorizer';
|
|
100
|
+
this.isDefault = true;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Creates a DefaultPolicyAuthorizer from the given configuration.
|
|
104
|
+
*
|
|
105
|
+
* @param config - Configuration for the authorizer
|
|
106
|
+
* @param factoryArgs - Additional factory arguments:
|
|
107
|
+
* - TokenVerifier instance
|
|
108
|
+
* - AuthorizationPolicy instance
|
|
109
|
+
* - AuthorizationPolicySource instance
|
|
110
|
+
* @returns The created authorizer
|
|
111
|
+
*/
|
|
112
|
+
async create(config, ...factoryArgs) {
|
|
113
|
+
const normalized = normalizeConfig(config);
|
|
114
|
+
// Resolve token verifier
|
|
115
|
+
let tokenVerifier = factoryArgs.find(isTokenVerifier);
|
|
116
|
+
if (!tokenVerifier && normalized.verifier) {
|
|
117
|
+
tokenVerifier = await token_verifier_factory_js_1.TokenVerifierFactory.createTokenVerifier(normalized.verifier);
|
|
118
|
+
}
|
|
119
|
+
if (!tokenVerifier) {
|
|
120
|
+
throw new Error('PolicyAuthorizer requires a verifier configuration or instance');
|
|
121
|
+
}
|
|
122
|
+
// Resolve policy or policy source
|
|
123
|
+
let policy = factoryArgs.find(isAuthorizationPolicy);
|
|
124
|
+
let policySource = factoryArgs.find(isAuthorizationPolicySource);
|
|
125
|
+
// Create policy from config if not provided as argument
|
|
126
|
+
if (!policy && normalized.policy) {
|
|
127
|
+
policy = await authorization_policy_factory_js_1.AuthorizationPolicyFactory.createAuthorizationPolicy(normalized.policy);
|
|
128
|
+
}
|
|
129
|
+
// Create policy source from config if not provided as argument
|
|
130
|
+
if (!policySource && normalized.policySource) {
|
|
131
|
+
policySource =
|
|
132
|
+
await authorization_policy_source_factory_js_1.AuthorizationPolicySourceFactory.createAuthorizationPolicySource(normalized.policySource);
|
|
133
|
+
}
|
|
134
|
+
// Validate that we have either policy or policy source
|
|
135
|
+
if (!policy && !policySource) {
|
|
136
|
+
throw new Error('PolicyAuthorizer requires either a policy or policySource configuration');
|
|
137
|
+
}
|
|
138
|
+
const { DefaultPolicyAuthorizer } = await getDefaultPolicyAuthorizerModule();
|
|
139
|
+
return new DefaultPolicyAuthorizer({
|
|
140
|
+
tokenVerifier,
|
|
141
|
+
policy,
|
|
142
|
+
policySource,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
exports.DefaultPolicyAuthorizerFactory = DefaultPolicyAuthorizerFactory;
|
|
147
|
+
exports.default = DefaultPolicyAuthorizerFactory;
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DefaultPolicyAuthorizer = void 0;
|
|
4
|
+
const core_1 = require("@naylence/core");
|
|
5
|
+
const logging_js_1 = require("../../util/logging.js");
|
|
6
|
+
const logger = (0, logging_js_1.getLogger)('naylence.fame.security.auth.default_policy_authorizer');
|
|
7
|
+
function decodeCredentials(credentials) {
|
|
8
|
+
if (typeof TextDecoder !== 'undefined') {
|
|
9
|
+
return new TextDecoder().decode(credentials);
|
|
10
|
+
}
|
|
11
|
+
if (typeof Buffer !== 'undefined') {
|
|
12
|
+
return Buffer.from(credentials).toString('utf-8');
|
|
13
|
+
}
|
|
14
|
+
throw new Error('Unable to decode credential bytes without TextDecoder support');
|
|
15
|
+
}
|
|
16
|
+
function normalizeToken(credentials) {
|
|
17
|
+
const raw = typeof credentials === 'string'
|
|
18
|
+
? credentials
|
|
19
|
+
: decodeCredentials(credentials);
|
|
20
|
+
const trimmed = raw.trim();
|
|
21
|
+
if (trimmed.length === 0) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
if (trimmed.toLowerCase().startsWith('bearer ')) {
|
|
25
|
+
const candidate = trimmed.slice(7).trim();
|
|
26
|
+
return candidate.length > 0 ? candidate : undefined;
|
|
27
|
+
}
|
|
28
|
+
return trimmed;
|
|
29
|
+
}
|
|
30
|
+
function normalizeOptions(options) {
|
|
31
|
+
if (options === undefined || options === null) {
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
if (typeof options !== 'object') {
|
|
35
|
+
throw new TypeError('DefaultPolicyAuthorizer options must be an object');
|
|
36
|
+
}
|
|
37
|
+
const candidate = options;
|
|
38
|
+
return {
|
|
39
|
+
tokenVerifier: candidate.tokenVerifier ?? candidate.token_verifier,
|
|
40
|
+
policy: candidate.policy,
|
|
41
|
+
policySource: candidate.policySource ?? candidate.policy_source,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* An authorizer that delegates authorization decisions to a pluggable policy.
|
|
46
|
+
*
|
|
47
|
+
* This authorizer combines token-based authentication with policy-based
|
|
48
|
+
* authorization. The token verifier handles authentication (validating
|
|
49
|
+
* credentials), while the authorization policy handles authorization
|
|
50
|
+
* decisions (allow/deny based on the request context).
|
|
51
|
+
*/
|
|
52
|
+
class DefaultPolicyAuthorizer {
|
|
53
|
+
constructor(options = {}) {
|
|
54
|
+
this.policyLoaded = false;
|
|
55
|
+
const normalized = normalizeOptions(options);
|
|
56
|
+
if (normalized.tokenVerifier) {
|
|
57
|
+
this.tokenVerifierImpl = normalized.tokenVerifier;
|
|
58
|
+
}
|
|
59
|
+
if (normalized.policy) {
|
|
60
|
+
this.policyImpl = normalized.policy;
|
|
61
|
+
this.policyLoaded = true;
|
|
62
|
+
}
|
|
63
|
+
if (normalized.policySource) {
|
|
64
|
+
this.policySource = normalized.policySource;
|
|
65
|
+
}
|
|
66
|
+
// Validate that we have either a policy or a policy source
|
|
67
|
+
if (!normalized.policy && !normalized.policySource) {
|
|
68
|
+
throw new Error('DefaultPolicyAuthorizer requires either a policy or a policySource');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The currently active authorization policy.
|
|
73
|
+
*/
|
|
74
|
+
get policy() {
|
|
75
|
+
if (!this.policyImpl) {
|
|
76
|
+
throw new Error('Authorization policy not loaded. Call ensurePolicyLoaded() first.');
|
|
77
|
+
}
|
|
78
|
+
return this.policyImpl;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The token verifier used for authentication.
|
|
82
|
+
*/
|
|
83
|
+
get tokenVerifier() {
|
|
84
|
+
if (!this.tokenVerifierImpl) {
|
|
85
|
+
throw new Error('DefaultPolicyAuthorizer is not initialized properly, missing tokenVerifier');
|
|
86
|
+
}
|
|
87
|
+
return this.tokenVerifierImpl;
|
|
88
|
+
}
|
|
89
|
+
set tokenVerifier(verifier) {
|
|
90
|
+
this.tokenVerifierImpl = verifier;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Ensures the authorization policy is loaded.
|
|
94
|
+
* If using a policy source, loads the policy from it.
|
|
95
|
+
*/
|
|
96
|
+
async ensurePolicyLoaded() {
|
|
97
|
+
if (this.policyLoaded && this.policyImpl) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (!this.policySource) {
|
|
101
|
+
throw new Error('No policy source configured and no policy provided');
|
|
102
|
+
}
|
|
103
|
+
logger.debug('loading_policy_from_source');
|
|
104
|
+
this.policyImpl = await this.policySource.loadPolicy();
|
|
105
|
+
this.policyLoaded = true;
|
|
106
|
+
logger.info('policy_loaded_from_source');
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Reloads the authorization policy from the policy source.
|
|
110
|
+
* Only works if a policy source was configured.
|
|
111
|
+
*/
|
|
112
|
+
async reloadPolicy() {
|
|
113
|
+
if (!this.policySource) {
|
|
114
|
+
throw new Error('Cannot reload policy: no policy source configured');
|
|
115
|
+
}
|
|
116
|
+
logger.debug('reloading_policy_from_source');
|
|
117
|
+
this.policyImpl = await this.policySource.loadPolicy();
|
|
118
|
+
this.policyLoaded = true;
|
|
119
|
+
logger.info('policy_reloaded_from_source');
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Authenticates credentials and returns an authorization context.
|
|
123
|
+
*
|
|
124
|
+
* @param credentials - The credentials to authenticate (token string or bytes)
|
|
125
|
+
* @returns The authorization context if authentication succeeds, undefined otherwise
|
|
126
|
+
*/
|
|
127
|
+
async authenticate(credentials) {
|
|
128
|
+
const token = normalizeToken(credentials);
|
|
129
|
+
if (!token) {
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
const verifier = this.tokenVerifier;
|
|
134
|
+
const context = await verifier.verify(token);
|
|
135
|
+
return (0, core_1.createAuthorizationContext)({
|
|
136
|
+
...context,
|
|
137
|
+
authenticated: true,
|
|
138
|
+
authorized: false, // Authorization happens in authorize()
|
|
139
|
+
authMethod: context.authMethod ?? 'jwt',
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
logger.warning('token_verification_failed', {
|
|
144
|
+
error: error instanceof Error ? error.message : String(error),
|
|
145
|
+
});
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Authorizes a request using the configured authorization policy.
|
|
151
|
+
*
|
|
152
|
+
* For NodeAttach frames, evaluates policy with action='Connect'.
|
|
153
|
+
* For other frames, this method performs basic authentication validation
|
|
154
|
+
* but does NOT infer send/receive actions. Route-level authorization
|
|
155
|
+
* is handled separately via authorizeRoute().
|
|
156
|
+
*
|
|
157
|
+
* @param node - The node handling the request
|
|
158
|
+
* @param envelope - The FAME envelope being authorized
|
|
159
|
+
* @param context - Optional delivery context
|
|
160
|
+
* @returns The authorization context if authorized, undefined if denied
|
|
161
|
+
*/
|
|
162
|
+
async authorize(node, envelope, context) {
|
|
163
|
+
const authorization = context?.security?.authorization;
|
|
164
|
+
// Must be authenticated first
|
|
165
|
+
if (!authorization || !authorization.authenticated) {
|
|
166
|
+
logger.debug('authorization_denied_not_authenticated');
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
// Ensure policy is loaded
|
|
170
|
+
await this.ensurePolicyLoaded();
|
|
171
|
+
// For NodeAttach frames, evaluate policy with 'Connect' action
|
|
172
|
+
const frameType = envelope.frame?.type;
|
|
173
|
+
if (frameType === 'NodeAttach') {
|
|
174
|
+
let decision;
|
|
175
|
+
try {
|
|
176
|
+
decision = await this.policy.evaluateRequest(node, envelope, context, 'Connect');
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
logger.error('policy_evaluation_failed', {
|
|
180
|
+
error: error instanceof Error ? error.message : String(error),
|
|
181
|
+
action: 'Connect',
|
|
182
|
+
});
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
if (decision.effect === 'allow') {
|
|
186
|
+
logger.debug('authorization_allowed', {
|
|
187
|
+
matchedRule: decision.matchedRule,
|
|
188
|
+
reason: decision.reason,
|
|
189
|
+
action: 'Connect',
|
|
190
|
+
});
|
|
191
|
+
return (0, core_1.createAuthorizationContext)({
|
|
192
|
+
...authorization,
|
|
193
|
+
authorized: true,
|
|
194
|
+
authMethod: authorization.authMethod ?? 'policy',
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
logger.debug('authorization_denied', {
|
|
199
|
+
matchedRule: decision.matchedRule,
|
|
200
|
+
reason: decision.reason,
|
|
201
|
+
action: 'Connect',
|
|
202
|
+
});
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// For non-NodeAttach frames, authentication is sufficient at this stage.
|
|
207
|
+
// Route-level authorization is performed via authorizeRoute() after
|
|
208
|
+
// the routing decision is made.
|
|
209
|
+
logger.debug('authorization_passed_authentication_only', {
|
|
210
|
+
envp_id: envelope.id,
|
|
211
|
+
frame_type: frameType,
|
|
212
|
+
});
|
|
213
|
+
return (0, core_1.createAuthorizationContext)({
|
|
214
|
+
...authorization,
|
|
215
|
+
authorized: true,
|
|
216
|
+
authMethod: authorization.authMethod ?? 'policy',
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Authorizes a routing action after the routing decision has been made.
|
|
221
|
+
*
|
|
222
|
+
* This method evaluates the authorization policy with the explicitly
|
|
223
|
+
* provided action token (ForwardUpstream, ForwardDownstream, ForwardPeer,
|
|
224
|
+
* DeliverLocal).
|
|
225
|
+
*
|
|
226
|
+
* @param node - The node handling the request
|
|
227
|
+
* @param envelope - The FAME envelope being routed
|
|
228
|
+
* @param action - The authorization action token from the routing decision
|
|
229
|
+
* @param context - Optional delivery context
|
|
230
|
+
* @returns RouteAuthorizationResult with authorization decision
|
|
231
|
+
*/
|
|
232
|
+
async authorizeRoute(node, envelope, action, context) {
|
|
233
|
+
const authorization = context?.security?.authorization;
|
|
234
|
+
// If not authenticated, deny route authorization
|
|
235
|
+
if (!authorization || !authorization.authenticated) {
|
|
236
|
+
logger.debug('route_authorization_denied_not_authenticated', {
|
|
237
|
+
action,
|
|
238
|
+
});
|
|
239
|
+
return {
|
|
240
|
+
authorized: false,
|
|
241
|
+
denialReason: 'not_authenticated',
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
// Ensure policy is loaded
|
|
245
|
+
await this.ensurePolicyLoaded();
|
|
246
|
+
// Evaluate the policy with the provided action
|
|
247
|
+
let decision;
|
|
248
|
+
try {
|
|
249
|
+
decision = await this.policy.evaluateRequest(node, envelope, context, action);
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
logger.error('route_policy_evaluation_failed', {
|
|
253
|
+
error: error instanceof Error ? error.message : String(error),
|
|
254
|
+
action,
|
|
255
|
+
});
|
|
256
|
+
return {
|
|
257
|
+
authorized: false,
|
|
258
|
+
denialReason: 'policy_evaluation_error',
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
if (decision.effect === 'allow') {
|
|
262
|
+
logger.debug('route_authorization_allowed', {
|
|
263
|
+
matchedRule: decision.matchedRule,
|
|
264
|
+
reason: decision.reason,
|
|
265
|
+
action,
|
|
266
|
+
});
|
|
267
|
+
return {
|
|
268
|
+
authorized: true,
|
|
269
|
+
authContext: (0, core_1.createAuthorizationContext)({
|
|
270
|
+
...authorization,
|
|
271
|
+
authorized: true,
|
|
272
|
+
authMethod: authorization.authMethod ?? 'policy',
|
|
273
|
+
}),
|
|
274
|
+
matchedRule: decision.matchedRule,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
logger.debug('route_authorization_denied', {
|
|
279
|
+
matchedRule: decision.matchedRule,
|
|
280
|
+
reason: decision.reason,
|
|
281
|
+
action,
|
|
282
|
+
});
|
|
283
|
+
return {
|
|
284
|
+
authorized: false,
|
|
285
|
+
denialReason: decision.reason ?? 'policy_denied',
|
|
286
|
+
matchedRule: decision.matchedRule,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
exports.DefaultPolicyAuthorizer = DefaultPolicyAuthorizer;
|