@naylence/runtime 0.4.0 → 0.4.2

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.
@@ -0,0 +1,161 @@
1
+ import { Expressions } from '@naylence/factory';
2
+ import { getLogger } from '../../util/logging.js';
3
+ import { AUTHORIZER_FACTORY_BASE_TYPE, AuthorizerFactory, } from './authorizer-factory.js';
4
+ const logger = getLogger('naylence.fame.security.auth.authorization_profile_factory');
5
+ export const PROFILE_NAME_DEFAULT = 'jwt';
6
+ export const PROFILE_NAME_OAUTH2 = 'oauth2';
7
+ export const PROFILE_NAME_OAUTH2_GATED = 'oauth2-gated';
8
+ export const PROFILE_NAME_OAUTH2_CALLBACK = 'oauth2-callback';
9
+ export const PROFILE_NAME_NOOP = 'noop';
10
+ export const ENV_VAR_JWT_TRUSTED_ISSUER = 'FAME_JWT_TRUSTED_ISSUER';
11
+ export const ENV_VAR_JWT_ALGORITHM = 'FAME_JWT_ALGORITHM';
12
+ export const ENV_VAR_JWT_AUDIENCE = 'FAME_JWT_AUDIENCE';
13
+ export const ENV_VAR_JWKS_URL = 'FAME_JWKS_URL';
14
+ export const ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY = 'FAME_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY';
15
+ export const ENV_VAR_TRUSTED_CLIENT_SCOPE = 'FAME_TRUSTED_CLIENT_SCOPE';
16
+ export const ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER = 'FAME_JWT_REVERSE_AUTH_TRUSTED_ISSUER';
17
+ export const ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE = 'FAME_JWT_REVERSE_AUTH_AUDIENCE';
18
+ export const ENV_VAR_HMAC_SECRET = 'FAME_HMAC_SECRET';
19
+ const DEFAULT_REVERSE_AUTH_ISSUER = 'reverse-auth.naylence.ai';
20
+ const DEFAULT_REVERSE_AUTH_AUDIENCE = 'dev.naylence.ai';
21
+ const DEFAULT_PROFILE = {
22
+ type: 'DefaultAuthorizer',
23
+ verifier: {
24
+ type: 'JWKSJWTTokenVerifier',
25
+ jwks_url: Expressions.env(ENV_VAR_JWKS_URL),
26
+ issuer: Expressions.env(ENV_VAR_JWT_TRUSTED_ISSUER),
27
+ },
28
+ };
29
+ const OAUTH2_PROFILE = {
30
+ type: 'OAuth2Authorizer',
31
+ issuer: Expressions.env(ENV_VAR_JWT_TRUSTED_ISSUER),
32
+ required_scopes: ['node.connect'],
33
+ require_scope: true,
34
+ default_ttl_sec: 3600,
35
+ max_ttl_sec: 86400,
36
+ algorithm: Expressions.env(ENV_VAR_JWT_ALGORITHM, 'RS256'),
37
+ audience: Expressions.env(ENV_VAR_JWT_AUDIENCE),
38
+ };
39
+ const OAUTH2_GATED_PROFILE = {
40
+ ...OAUTH2_PROFILE,
41
+ enforce_token_subject_node_identity: Expressions.env(ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY, 'false'),
42
+ trusted_client_scope: Expressions.env(ENV_VAR_TRUSTED_CLIENT_SCOPE, 'node.trusted'),
43
+ };
44
+ const OAUTH2_CALLBACK_PROFILE = {
45
+ type: 'OAuth2Authorizer',
46
+ issuer: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, DEFAULT_REVERSE_AUTH_ISSUER),
47
+ audience: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE),
48
+ require_scope: true,
49
+ default_ttl_sec: 3600,
50
+ max_ttl_sec: 86400,
51
+ reverse_auth_ttl_sec: 86400,
52
+ token_verifier_config: {
53
+ type: 'JWTTokenVerifier',
54
+ algorithm: 'HS256',
55
+ hmac_secret: Expressions.env(ENV_VAR_HMAC_SECRET),
56
+ issuer: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, DEFAULT_REVERSE_AUTH_ISSUER),
57
+ ttl_sec: 86400,
58
+ },
59
+ token_issuer_config: {
60
+ type: 'JWTTokenIssuer',
61
+ algorithm: 'HS256',
62
+ hmac_secret: Expressions.env(ENV_VAR_HMAC_SECRET),
63
+ kid: 'hmac-reverse-auth-key',
64
+ issuer: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, DEFAULT_REVERSE_AUTH_ISSUER),
65
+ ttl_sec: 86400,
66
+ audience: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE, DEFAULT_REVERSE_AUTH_AUDIENCE),
67
+ },
68
+ };
69
+ const NOOP_PROFILE = {
70
+ type: 'NoopAuthorizer',
71
+ };
72
+ const PROFILE_MAP = {
73
+ [PROFILE_NAME_DEFAULT]: DEFAULT_PROFILE,
74
+ [PROFILE_NAME_OAUTH2]: OAUTH2_PROFILE,
75
+ [PROFILE_NAME_OAUTH2_GATED]: OAUTH2_GATED_PROFILE,
76
+ [PROFILE_NAME_OAUTH2_CALLBACK]: OAUTH2_CALLBACK_PROFILE,
77
+ [PROFILE_NAME_NOOP]: NOOP_PROFILE,
78
+ };
79
+ const PROFILE_ALIASES = {
80
+ jwt: PROFILE_NAME_DEFAULT,
81
+ jwks: PROFILE_NAME_DEFAULT,
82
+ default: PROFILE_NAME_DEFAULT,
83
+ oauth2: PROFILE_NAME_OAUTH2,
84
+ oidc: PROFILE_NAME_OAUTH2,
85
+ 'oauth2-gated': PROFILE_NAME_OAUTH2_GATED,
86
+ oauth2_gated: PROFILE_NAME_OAUTH2_GATED,
87
+ 'oauth2-callback': PROFILE_NAME_OAUTH2_CALLBACK,
88
+ oauth2_callback: PROFILE_NAME_OAUTH2_CALLBACK,
89
+ 'reverse-auth': PROFILE_NAME_OAUTH2_CALLBACK,
90
+ noop: PROFILE_NAME_NOOP,
91
+ 'no-op': PROFILE_NAME_NOOP,
92
+ no_op: PROFILE_NAME_NOOP,
93
+ };
94
+ export const FACTORY_META = {
95
+ base: AUTHORIZER_FACTORY_BASE_TYPE,
96
+ key: 'AuthorizationProfile',
97
+ };
98
+ export class AuthorizationProfileFactory extends AuthorizerFactory {
99
+ constructor() {
100
+ super(...arguments);
101
+ this.type = 'AuthorizationProfile';
102
+ }
103
+ async create(config, ...factoryArgs) {
104
+ const normalized = normalizeConfig(config);
105
+ const profileConfig = resolveProfileConfig(normalized.profile);
106
+ logger.debug('enabling_authorization_profile', {
107
+ profile: normalized.profile,
108
+ });
109
+ const authorizer = await AuthorizerFactory.createAuthorizer(profileConfig, { factoryArgs });
110
+ if (!authorizer) {
111
+ throw new Error(`Failed to create authorizer for profile: ${normalized.profile}`);
112
+ }
113
+ return authorizer;
114
+ }
115
+ }
116
+ function normalizeConfig(config) {
117
+ if (!config) {
118
+ return { profile: PROFILE_NAME_OAUTH2 };
119
+ }
120
+ const candidate = config;
121
+ const profileValue = resolveProfileName(candidate);
122
+ const canonicalProfile = canonicalizeProfileName(profileValue);
123
+ candidate.profile = canonicalProfile;
124
+ return { profile: canonicalProfile };
125
+ }
126
+ function resolveProfileName(candidate) {
127
+ const direct = coerceProfileString(candidate.profile);
128
+ if (direct) {
129
+ return direct;
130
+ }
131
+ const legacyKeys = ['profile_name', 'profileName'];
132
+ for (const legacyKey of legacyKeys) {
133
+ const legacyValue = coerceProfileString(candidate[legacyKey]);
134
+ if (legacyValue) {
135
+ return legacyValue;
136
+ }
137
+ }
138
+ return PROFILE_NAME_OAUTH2;
139
+ }
140
+ function coerceProfileString(value) {
141
+ if (typeof value !== 'string') {
142
+ return null;
143
+ }
144
+ const trimmed = value.trim();
145
+ return trimmed.length > 0 ? trimmed : null;
146
+ }
147
+ function canonicalizeProfileName(value) {
148
+ const normalized = value.replace(/[\s_]+/g, '-').toLowerCase();
149
+ return PROFILE_ALIASES[normalized] ?? normalized;
150
+ }
151
+ function resolveProfileConfig(profileName) {
152
+ const profile = PROFILE_MAP[profileName];
153
+ if (!profile) {
154
+ throw new Error(`Unknown authorization profile: ${profileName}`);
155
+ }
156
+ return deepClone(profile);
157
+ }
158
+ function deepClone(value) {
159
+ return JSON.parse(JSON.stringify(value));
160
+ }
161
+ export default AuthorizationProfileFactory;
@@ -2,6 +2,7 @@ export * from './auth/authorizer.js';
2
2
  export * from './auth/auth-identity.js';
3
3
  export * from './auth/policy-authorizer.js';
4
4
  export { AUTHORIZER_FACTORY_BASE_TYPE, AuthorizerFactory, } from './auth/authorizer-factory.js';
5
+ export { AuthorizationProfileFactory, PROFILE_NAME_DEFAULT as AUTH_PROFILE_NAME_DEFAULT, PROFILE_NAME_OAUTH2 as AUTH_PROFILE_NAME_OAUTH2, PROFILE_NAME_OAUTH2_GATED as AUTH_PROFILE_NAME_OAUTH2_GATED, PROFILE_NAME_OAUTH2_CALLBACK as AUTH_PROFILE_NAME_OAUTH2_CALLBACK, PROFILE_NAME_NOOP as AUTH_PROFILE_NAME_NOOP, ENV_VAR_JWT_TRUSTED_ISSUER as AUTH_PROFILE_ENV_VAR_JWT_TRUSTED_ISSUER, ENV_VAR_JWT_ALGORITHM as AUTH_PROFILE_ENV_VAR_JWT_ALGORITHM, ENV_VAR_JWT_AUDIENCE as AUTH_PROFILE_ENV_VAR_JWT_AUDIENCE, ENV_VAR_JWKS_URL as AUTH_PROFILE_ENV_VAR_JWKS_URL, ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY as AUTH_PROFILE_ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY, ENV_VAR_TRUSTED_CLIENT_SCOPE as AUTH_PROFILE_ENV_VAR_TRUSTED_CLIENT_SCOPE, ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER as AUTH_PROFILE_ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE as AUTH_PROFILE_ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE, ENV_VAR_HMAC_SECRET as AUTH_PROFILE_ENV_VAR_HMAC_SECRET, } from './auth/authorization-profile-factory.js';
5
6
  export * from './auth/auth-injection-strategy.js';
6
7
  // Authorization policy exports
7
8
  export * from './auth/policy/index.js';
@@ -68,4 +69,4 @@ export * from './credential/browser-auto-key-credential-provider.js';
68
69
  export * from './credential/browser-wrapped-key-credential-provider.js';
69
70
  export * from './credential/session-key-credential-provider.js';
70
71
  export * from './credential/dev-fixed-key-credential-provider.js';
71
- export { ENV_VAR_JWT_TRUSTED_ISSUER, ENV_VAR_JWT_ALGORITHM, ENV_VAR_JWT_AUDIENCE, ENV_VAR_JWKS_URL, ENV_VAR_DEFAULT_ENCRYPTION_LEVEL, ENV_VAR_HMAC_SECRET, ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE, PROFILE_NAME_STRICT_OVERLAY, PROFILE_NAME_OVERLAY, PROFILE_NAME_OVERLAY_CALLBACK, PROFILE_NAME_GATED, PROFILE_NAME_GATED_CALLBACK, PROFILE_NAME_OPEN, } from './node-security-profile-factory.js';
72
+ export { ENV_VAR_JWT_TRUSTED_ISSUER, ENV_VAR_JWT_ALGORITHM, ENV_VAR_JWT_AUDIENCE, ENV_VAR_JWKS_URL, ENV_VAR_DEFAULT_ENCRYPTION_LEVEL, ENV_VAR_HMAC_SECRET, ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE, ENV_VAR_AUTHORIZATION_PROFILE, PROFILE_NAME_STRICT_OVERLAY, PROFILE_NAME_OVERLAY, PROFILE_NAME_OVERLAY_CALLBACK, PROFILE_NAME_GATED, PROFILE_NAME_GATED_CALLBACK, PROFILE_NAME_OPEN, } from './node-security-profile-factory.js';
@@ -12,14 +12,13 @@ export const ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER = 'FAME_JWT_REVERSE_AUTH_TR
12
12
  export const ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE = 'FAME_JWT_REVERSE_AUTH_AUDIENCE';
13
13
  export const ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY = 'FAME_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY';
14
14
  export const ENV_VAR_TRUSTED_CLIENT_SCOPE = 'FAME_TRUSTED_CLIENT_SCOPE';
15
+ export const ENV_VAR_AUTHORIZATION_PROFILE = 'FAME_AUTHORIZATION_PROFILE';
15
16
  export const PROFILE_NAME_STRICT_OVERLAY = 'strict-overlay';
16
17
  export const PROFILE_NAME_OVERLAY = 'overlay';
17
18
  export const PROFILE_NAME_OVERLAY_CALLBACK = 'overlay-callback';
18
19
  export const PROFILE_NAME_GATED = 'gated';
19
20
  export const PROFILE_NAME_GATED_CALLBACK = 'gated-callback';
20
21
  export const PROFILE_NAME_OPEN = 'open';
21
- const DEFAULT_REVERSE_AUTH_ISSUER = 'reverse-auth.naylence.ai';
22
- const DEFAULT_REVERSE_AUTH_AUDIENCE = 'dev.naylence.ai';
23
22
  const STRICT_OVERLAY_PROFILE = {
24
23
  type: 'DefaultSecurityManager',
25
24
  security_policy: {
@@ -65,12 +64,8 @@ const STRICT_OVERLAY_PROFILE = {
65
64
  },
66
65
  },
67
66
  authorizer: {
68
- type: 'DefaultAuthorizer',
69
- verifier: {
70
- type: 'JWKSJWTTokenVerifier',
71
- jwks_url: Expressions.env(ENV_VAR_JWKS_URL),
72
- issuer: Expressions.env(ENV_VAR_JWT_TRUSTED_ISSUER),
73
- },
67
+ type: 'AuthorizationProfile',
68
+ profile: Expressions.env(ENV_VAR_AUTHORIZATION_PROFILE, 'jwt'),
74
69
  },
75
70
  };
76
71
  const OVERLAY_PROFILE = {
@@ -117,14 +112,8 @@ const OVERLAY_PROFILE = {
117
112
  },
118
113
  },
119
114
  authorizer: {
120
- type: 'OAuth2Authorizer',
121
- issuer: Expressions.env(ENV_VAR_JWT_TRUSTED_ISSUER),
122
- required_scopes: ['node.connect'],
123
- require_scope: true,
124
- default_ttl_sec: 3600,
125
- max_ttl_sec: 86400,
126
- algorithm: Expressions.env(ENV_VAR_JWT_ALGORITHM, 'RS256'),
127
- audience: Expressions.env(ENV_VAR_JWT_AUDIENCE),
115
+ type: 'AuthorizationProfile',
116
+ profile: Expressions.env(ENV_VAR_AUTHORIZATION_PROFILE, 'oauth2'),
128
117
  },
129
118
  };
130
119
  const OVERLAY_CALLBACK_PROFILE = {
@@ -171,29 +160,8 @@ const OVERLAY_CALLBACK_PROFILE = {
171
160
  },
172
161
  },
173
162
  authorizer: {
174
- type: 'OAuth2Authorizer',
175
- issuer: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, DEFAULT_REVERSE_AUTH_ISSUER),
176
- audience: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE),
177
- require_scope: true,
178
- default_ttl_sec: 3600,
179
- max_ttl_sec: 86400,
180
- reverse_auth_ttl_sec: 86400,
181
- token_verifier_config: {
182
- type: 'JWTTokenVerifier',
183
- algorithm: 'HS256',
184
- hmac_secret: Expressions.env(ENV_VAR_HMAC_SECRET),
185
- issuer: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, DEFAULT_REVERSE_AUTH_ISSUER),
186
- ttl_sec: 86400,
187
- },
188
- token_issuer_config: {
189
- type: 'JWTTokenIssuer',
190
- algorithm: 'HS256',
191
- hmac_secret: Expressions.env(ENV_VAR_HMAC_SECRET),
192
- kid: 'hmac-reverse-auth-key',
193
- issuer: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, DEFAULT_REVERSE_AUTH_ISSUER),
194
- ttl_sec: 86400,
195
- audience: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE, DEFAULT_REVERSE_AUTH_AUDIENCE),
196
- },
163
+ type: 'AuthorizationProfile',
164
+ profile: Expressions.env(ENV_VAR_AUTHORIZATION_PROFILE, 'oauth2-callback'),
197
165
  },
198
166
  };
199
167
  const GATED_PROFILE = {
@@ -239,16 +207,8 @@ const GATED_PROFILE = {
239
207
  },
240
208
  },
241
209
  authorizer: {
242
- type: 'OAuth2Authorizer',
243
- issuer: Expressions.env(ENV_VAR_JWT_TRUSTED_ISSUER),
244
- required_scopes: ['node.connect'],
245
- require_scope: true,
246
- default_ttl_sec: 3600,
247
- max_ttl_sec: 86400,
248
- algorithm: Expressions.env(ENV_VAR_JWT_ALGORITHM, 'RS256'),
249
- audience: Expressions.env(ENV_VAR_JWT_AUDIENCE),
250
- enforce_token_subject_node_identity: Expressions.env(ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY, 'false'),
251
- trusted_client_scope: Expressions.env(ENV_VAR_TRUSTED_CLIENT_SCOPE, 'node.trusted'),
210
+ type: 'AuthorizationProfile',
211
+ profile: Expressions.env(ENV_VAR_AUTHORIZATION_PROFILE, 'oauth2-gated'),
252
212
  },
253
213
  };
254
214
  const GATED_CALLBACK_PROFILE = {
@@ -294,29 +254,8 @@ const GATED_CALLBACK_PROFILE = {
294
254
  },
295
255
  },
296
256
  authorizer: {
297
- type: 'OAuth2Authorizer',
298
- issuer: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, DEFAULT_REVERSE_AUTH_ISSUER),
299
- audience: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE),
300
- require_scope: true,
301
- default_ttl_sec: 3600,
302
- max_ttl_sec: 86400,
303
- reverse_auth_ttl_sec: 86400,
304
- token_verifier_config: {
305
- type: 'JWTTokenVerifier',
306
- algorithm: 'HS256',
307
- hmac_secret: Expressions.env(ENV_VAR_HMAC_SECRET),
308
- issuer: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, DEFAULT_REVERSE_AUTH_ISSUER),
309
- ttl_sec: 86400,
310
- },
311
- token_issuer_config: {
312
- type: 'JWTTokenIssuer',
313
- algorithm: 'HS256',
314
- hmac_secret: Expressions.env(ENV_VAR_HMAC_SECRET),
315
- kid: 'hmac-reverse-auth-key',
316
- issuer: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER, DEFAULT_REVERSE_AUTH_ISSUER),
317
- ttl_sec: 86400,
318
- audience: Expressions.env(ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE, DEFAULT_REVERSE_AUTH_AUDIENCE),
319
- },
257
+ type: 'AuthorizationProfile',
258
+ profile: Expressions.env(ENV_VAR_AUTHORIZATION_PROFILE, 'oauth2-callback'),
320
259
  },
321
260
  };
322
261
  const OPEN_PROFILE = {
@@ -325,7 +264,8 @@ const OPEN_PROFILE = {
325
264
  type: 'NoSecurityPolicy',
326
265
  },
327
266
  authorizer: {
328
- type: 'NoopAuthorizer',
267
+ type: 'AuthorizationProfile',
268
+ profile: Expressions.env(ENV_VAR_AUTHORIZATION_PROFILE, 'noop'),
329
269
  },
330
270
  };
331
271
  const PROFILE_MAP = {
@@ -1,7 +1,7 @@
1
1
  // This file is auto-generated during build - do not edit manually
2
- // Generated from package.json version: 0.4.0
2
+ // Generated from package.json version: 0.4.2
3
3
  /**
4
4
  * The package version, injected at build time.
5
5
  * @internal
6
6
  */
7
- export const VERSION = '0.4.0';
7
+ export const VERSION = '0.4.2';