@naylence/runtime 0.4.2 → 0.4.4

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.
@@ -4436,12 +4436,12 @@ async function ensureRuntimeFactoriesRegistered(registry = factory.Registry) {
4436
4436
  }
4437
4437
 
4438
4438
  // This file is auto-generated during build - do not edit manually
4439
- // Generated from package.json version: 0.4.2
4439
+ // Generated from package.json version: 0.4.4
4440
4440
  /**
4441
4441
  * The package version, injected at build time.
4442
4442
  * @internal
4443
4443
  */
4444
- const VERSION = '0.4.2';
4444
+ const VERSION = '0.4.4';
4445
4445
 
4446
4446
  let initialized = false;
4447
4447
  const runtimePlugin = {
@@ -23018,6 +23018,7 @@ const PROFILE_NAME_DEFAULT = 'jwt';
23018
23018
  const PROFILE_NAME_OAUTH2 = 'oauth2';
23019
23019
  const PROFILE_NAME_OAUTH2_GATED = 'oauth2-gated';
23020
23020
  const PROFILE_NAME_OAUTH2_CALLBACK = 'oauth2-callback';
23021
+ const PROFILE_NAME_POLICY_LOCALFILE = 'policy-localfile';
23021
23022
  const PROFILE_NAME_NOOP$2 = 'noop';
23022
23023
  const ENV_VAR_JWT_TRUSTED_ISSUER$1 = 'FAME_JWT_TRUSTED_ISSUER';
23023
23024
  const ENV_VAR_JWT_ALGORITHM$3 = 'FAME_JWT_ALGORITHM';
@@ -23025,18 +23026,21 @@ const ENV_VAR_JWT_AUDIENCE$3 = 'FAME_JWT_AUDIENCE';
23025
23026
  const ENV_VAR_JWKS_URL$1 = 'FAME_JWKS_URL';
23026
23027
  const ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY$1 = 'FAME_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY';
23027
23028
  const ENV_VAR_TRUSTED_CLIENT_SCOPE$1 = 'FAME_TRUSTED_CLIENT_SCOPE';
23029
+ const ENV_VAR_AUTH_POLICY_PATH = 'FAME_AUTH_POLICY_PATH';
23030
+ const ENV_VAR_AUTH_POLICY_FORMAT = 'FAME_AUTH_POLICY_FORMAT';
23028
23031
  const ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER$1 = 'FAME_JWT_REVERSE_AUTH_TRUSTED_ISSUER';
23029
23032
  const ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE$1 = 'FAME_JWT_REVERSE_AUTH_AUDIENCE';
23030
23033
  const ENV_VAR_HMAC_SECRET$1 = 'FAME_HMAC_SECRET';
23031
23034
  const DEFAULT_REVERSE_AUTH_ISSUER = 'reverse-auth.naylence.ai';
23032
23035
  const DEFAULT_REVERSE_AUTH_AUDIENCE = 'dev.naylence.ai';
23036
+ const DEFAULT_VERIFIER_CONFIG = {
23037
+ type: 'JWKSJWTTokenVerifier',
23038
+ jwks_url: factory.Expressions.env(ENV_VAR_JWKS_URL$1),
23039
+ issuer: factory.Expressions.env(ENV_VAR_JWT_TRUSTED_ISSUER$1),
23040
+ };
23033
23041
  const DEFAULT_PROFILE = {
23034
23042
  type: 'DefaultAuthorizer',
23035
- verifier: {
23036
- type: 'JWKSJWTTokenVerifier',
23037
- jwks_url: factory.Expressions.env(ENV_VAR_JWKS_URL$1),
23038
- issuer: factory.Expressions.env(ENV_VAR_JWT_TRUSTED_ISSUER$1),
23039
- },
23043
+ verifier: DEFAULT_VERIFIER_CONFIG,
23040
23044
  };
23041
23045
  const OAUTH2_PROFILE = {
23042
23046
  type: 'OAuth2Authorizer',
@@ -23081,11 +23085,22 @@ const OAUTH2_CALLBACK_PROFILE = {
23081
23085
  const NOOP_PROFILE$2 = {
23082
23086
  type: 'NoopAuthorizer',
23083
23087
  };
23088
+ const DEFAULT_POLICY_SOURCE = {
23089
+ type: 'LocalFileAuthorizationPolicySource',
23090
+ path: factory.Expressions.env(ENV_VAR_AUTH_POLICY_PATH, './auth-policy.yaml'),
23091
+ format: factory.Expressions.env(ENV_VAR_AUTH_POLICY_FORMAT, 'auto'),
23092
+ };
23093
+ const POLICY_LOCALFILE_PROFILE = {
23094
+ type: 'PolicyAuthorizer',
23095
+ verifier: DEFAULT_VERIFIER_CONFIG,
23096
+ policySource: DEFAULT_POLICY_SOURCE,
23097
+ };
23084
23098
  const PROFILE_MAP$5 = {
23085
23099
  [PROFILE_NAME_DEFAULT]: DEFAULT_PROFILE,
23086
23100
  [PROFILE_NAME_OAUTH2]: OAUTH2_PROFILE,
23087
23101
  [PROFILE_NAME_OAUTH2_GATED]: OAUTH2_GATED_PROFILE,
23088
23102
  [PROFILE_NAME_OAUTH2_CALLBACK]: OAUTH2_CALLBACK_PROFILE,
23103
+ [PROFILE_NAME_POLICY_LOCALFILE]: POLICY_LOCALFILE_PROFILE,
23089
23104
  [PROFILE_NAME_NOOP$2]: NOOP_PROFILE$2,
23090
23105
  };
23091
23106
  const PROFILE_ALIASES$1 = {
@@ -23099,6 +23114,9 @@ const PROFILE_ALIASES$1 = {
23099
23114
  'oauth2-callback': PROFILE_NAME_OAUTH2_CALLBACK,
23100
23115
  oauth2_callback: PROFILE_NAME_OAUTH2_CALLBACK,
23101
23116
  'reverse-auth': PROFILE_NAME_OAUTH2_CALLBACK,
23117
+ policy: PROFILE_NAME_POLICY_LOCALFILE,
23118
+ 'policy-localfile': PROFILE_NAME_POLICY_LOCALFILE,
23119
+ policy_localfile: PROFILE_NAME_POLICY_LOCALFILE,
23102
23120
  noop: PROFILE_NAME_NOOP$2,
23103
23121
  'no-op': PROFILE_NAME_NOOP$2,
23104
23122
  no_op: PROFILE_NAME_NOOP$2,
@@ -23174,6 +23192,8 @@ function deepClone$4(value) {
23174
23192
  var authorizationProfileFactory = /*#__PURE__*/Object.freeze({
23175
23193
  __proto__: null,
23176
23194
  AuthorizationProfileFactory: AuthorizationProfileFactory,
23195
+ ENV_VAR_AUTH_POLICY_FORMAT: ENV_VAR_AUTH_POLICY_FORMAT,
23196
+ ENV_VAR_AUTH_POLICY_PATH: ENV_VAR_AUTH_POLICY_PATH,
23177
23197
  ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY: ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY$1,
23178
23198
  ENV_VAR_HMAC_SECRET: ENV_VAR_HMAC_SECRET$1,
23179
23199
  ENV_VAR_JWKS_URL: ENV_VAR_JWKS_URL$1,
@@ -23189,6 +23209,7 @@ var authorizationProfileFactory = /*#__PURE__*/Object.freeze({
23189
23209
  PROFILE_NAME_OAUTH2: PROFILE_NAME_OAUTH2,
23190
23210
  PROFILE_NAME_OAUTH2_CALLBACK: PROFILE_NAME_OAUTH2_CALLBACK,
23191
23211
  PROFILE_NAME_OAUTH2_GATED: PROFILE_NAME_OAUTH2_GATED,
23212
+ PROFILE_NAME_POLICY_LOCALFILE: PROFILE_NAME_POLICY_LOCALFILE,
23192
23213
  default: AuthorizationProfileFactory
23193
23214
  });
23194
23215
 
@@ -23754,6 +23775,7 @@ class BasicAuthorizationPolicy {
23754
23775
  // Action must be explicitly provided; default to wildcard if omitted
23755
23776
  // for backward compatibility during transition
23756
23777
  const resolvedAction = action ?? '*';
23778
+ const resolvedActionNormalized = this.normalizeActionToken(resolvedAction) ?? resolvedAction;
23757
23779
  const address = extractAddress(envelope);
23758
23780
  const grantedScopes = extractGrantedScopes(context);
23759
23781
  const rawFrameType = envelope.frame
@@ -23763,8 +23785,8 @@ class BasicAuthorizationPolicy {
23763
23785
  : '';
23764
23786
  // Extract and normalize origin type for rule matching
23765
23787
  const rawOriginType = context?.originType;
23766
- const originTypeNormalized = typeof rawOriginType === 'string' && rawOriginType.trim().length > 0
23767
- ? rawOriginType.trim().toLowerCase()
23788
+ const originTypeNormalized = typeof rawOriginType === 'string'
23789
+ ? this.normalizeOriginTypeToken(rawOriginType) ?? undefined
23768
23790
  : undefined;
23769
23791
  const evaluationTrace = [];
23770
23792
  // Evaluate rules in order (first match wins)
@@ -23811,8 +23833,8 @@ class BasicAuthorizationPolicy {
23811
23833
  }
23812
23834
  }
23813
23835
  // Check action match
23814
- if (!rule.actions.has('*') && !rule.actions.has(resolvedAction)) {
23815
- step.expression = `action: ${resolvedAction} not in [${Array.from(rule.actions).join(', ')}]`;
23836
+ if (!rule.actions.has('*') && !rule.actions.has(resolvedActionNormalized)) {
23837
+ step.expression = `action: ${resolvedActionNormalized} not in [${Array.from(rule.actions).join(', ')}]`;
23816
23838
  step.result = false;
23817
23839
  evaluationTrace.push(step);
23818
23840
  continue;
@@ -23879,6 +23901,9 @@ class BasicAuthorizationPolicy {
23879
23901
  };
23880
23902
  }
23881
23903
  validateDefaultEffect(effect) {
23904
+ if (effect === undefined || effect === null) {
23905
+ return 'deny';
23906
+ }
23882
23907
  if (effect !== 'allow' && effect !== 'deny') {
23883
23908
  throw new Error(`Invalid default_effect: "${String(effect)}". Must be "allow" or "deny"`);
23884
23909
  }
@@ -23951,10 +23976,11 @@ class BasicAuthorizationPolicy {
23951
23976
  }
23952
23977
  // Handle single action
23953
23978
  if (typeof action === 'string') {
23954
- if (!VALID_ACTIONS.includes(action)) {
23979
+ const normalized = this.normalizeActionToken(action);
23980
+ if (!normalized) {
23955
23981
  throw new Error(`Invalid action in rule "${ruleId}": "${action}". Must be one of: ${VALID_ACTIONS.join(', ')}`);
23956
23982
  }
23957
- return new Set([action]);
23983
+ return new Set([normalized]);
23958
23984
  }
23959
23985
  // Handle array of actions
23960
23986
  if (!Array.isArray(action)) {
@@ -23968,10 +23994,11 @@ class BasicAuthorizationPolicy {
23968
23994
  if (typeof a !== 'string') {
23969
23995
  throw new Error(`Invalid action in rule "${ruleId}": all values must be strings`);
23970
23996
  }
23971
- if (!VALID_ACTIONS.includes(a)) {
23997
+ const normalized = this.normalizeActionToken(a);
23998
+ if (!normalized) {
23972
23999
  throw new Error(`Invalid action in rule "${ruleId}": "${a}". Must be one of: ${VALID_ACTIONS.join(', ')}`);
23973
24000
  }
23974
- actions.add(a);
24001
+ actions.add(normalized);
23975
24002
  }
23976
24003
  return actions;
23977
24004
  }
@@ -24074,11 +24101,12 @@ class BasicAuthorizationPolicy {
24074
24101
  }
24075
24102
  // Handle single origin type
24076
24103
  if (typeof originType === 'string') {
24077
- const normalized = originType.trim().toLowerCase();
24078
- if (!normalized) {
24104
+ const trimmed = originType.trim();
24105
+ if (!trimmed) {
24079
24106
  throw new Error(`Invalid origin_type in rule "${ruleId}": value must not be empty`);
24080
24107
  }
24081
- if (!VALID_ORIGIN_TYPES.includes(normalized)) {
24108
+ const normalized = this.normalizeOriginTypeToken(trimmed);
24109
+ if (!normalized) {
24082
24110
  throw new Error(`Invalid origin_type in rule "${ruleId}": "${originType}". Must be one of: ${VALID_ORIGIN_TYPES.join(', ')}`);
24083
24111
  }
24084
24112
  return new Set([normalized]);
@@ -24095,17 +24123,50 @@ class BasicAuthorizationPolicy {
24095
24123
  if (typeof ot !== 'string') {
24096
24124
  throw new Error(`Invalid origin_type in rule "${ruleId}": all values must be strings`);
24097
24125
  }
24098
- const normalized = ot.trim().toLowerCase();
24099
- if (!normalized) {
24126
+ const trimmed = ot.trim();
24127
+ if (!trimmed) {
24100
24128
  throw new Error(`Invalid origin_type in rule "${ruleId}": values must not be empty`);
24101
24129
  }
24102
- if (!VALID_ORIGIN_TYPES.includes(normalized)) {
24130
+ const normalized = this.normalizeOriginTypeToken(trimmed);
24131
+ if (!normalized) {
24103
24132
  throw new Error(`Invalid origin_type in rule "${ruleId}": "${ot}". Must be one of: ${VALID_ORIGIN_TYPES.join(', ')}`);
24104
24133
  }
24105
24134
  originTypes.add(normalized);
24106
24135
  }
24107
24136
  return originTypes;
24108
24137
  }
24138
+ normalizeActionToken(value) {
24139
+ const trimmed = value.trim();
24140
+ if (!trimmed) {
24141
+ return null;
24142
+ }
24143
+ if (trimmed === '*') {
24144
+ return '*';
24145
+ }
24146
+ const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
24147
+ const map = {
24148
+ connect: 'Connect',
24149
+ forwardupstream: 'ForwardUpstream',
24150
+ forwarddownstream: 'ForwardDownstream',
24151
+ forwardpeer: 'ForwardPeer',
24152
+ deliverlocal: 'DeliverLocal',
24153
+ };
24154
+ return map[normalized] ?? null;
24155
+ }
24156
+ normalizeOriginTypeToken(value) {
24157
+ const trimmed = value.trim();
24158
+ if (!trimmed) {
24159
+ return null;
24160
+ }
24161
+ const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
24162
+ const map = {
24163
+ downstream: 'downstream',
24164
+ upstream: 'upstream',
24165
+ peer: 'peer',
24166
+ local: 'local',
24167
+ };
24168
+ return map[normalized] ?? null;
24169
+ }
24109
24170
  }
24110
24171
 
24111
24172
  var basicAuthorizationPolicy = /*#__PURE__*/Object.freeze({
@@ -44907,16 +44968,22 @@ class LocalFileAuthorizationPolicySource {
44907
44968
  const factoryConfig = this.policyFactoryConfig ?? policyDefinition;
44908
44969
  // Ensure we have a type field for the factory
44909
44970
  if (!('type' in factoryConfig) || typeof factoryConfig.type !== 'string') {
44910
- throw new Error(`Policy definition at ${this.path} must have a 'type' field, ` +
44911
- `or policyFactory config must be provided`);
44971
+ logger$1.warning('policy_type_missing_defaulting_to_basic', {
44972
+ path: this.path,
44973
+ });
44974
+ factoryConfig.type =
44975
+ 'BasicAuthorizationPolicy';
44912
44976
  }
44913
44977
  // Build the factory config with the policy definition
44914
44978
  // The file content IS the policy definition, so we extract the type
44915
44979
  // and wrap the remaining content as the policyDefinition
44916
- const { type, ...restOfFile } = policyDefinition;
44980
+ const { type: fileType, ...restOfFile } = policyDefinition;
44981
+ const resolvedType = typeof fileType === 'string' && fileType.trim().length > 0
44982
+ ? fileType
44983
+ : factoryConfig.type;
44917
44984
  const mergedConfig = this.policyFactoryConfig != null
44918
44985
  ? { ...this.policyFactoryConfig, policyDefinition }
44919
- : { type: factoryConfig.type, policyDefinition: restOfFile };
44986
+ : { type: resolvedType, policyDefinition: restOfFile };
44920
44987
  // Create the policy using the factory system
44921
44988
  const policy = await AuthorizationPolicyFactory.createAuthorizationPolicy(mergedConfig);
44922
44989
  if (!policy) {
@@ -4435,12 +4435,12 @@ async function ensureRuntimeFactoriesRegistered(registry = Registry) {
4435
4435
  }
4436
4436
 
4437
4437
  // This file is auto-generated during build - do not edit manually
4438
- // Generated from package.json version: 0.4.2
4438
+ // Generated from package.json version: 0.4.4
4439
4439
  /**
4440
4440
  * The package version, injected at build time.
4441
4441
  * @internal
4442
4442
  */
4443
- const VERSION = '0.4.2';
4443
+ const VERSION = '0.4.4';
4444
4444
 
4445
4445
  let initialized = false;
4446
4446
  const runtimePlugin = {
@@ -23017,6 +23017,7 @@ const PROFILE_NAME_DEFAULT = 'jwt';
23017
23017
  const PROFILE_NAME_OAUTH2 = 'oauth2';
23018
23018
  const PROFILE_NAME_OAUTH2_GATED = 'oauth2-gated';
23019
23019
  const PROFILE_NAME_OAUTH2_CALLBACK = 'oauth2-callback';
23020
+ const PROFILE_NAME_POLICY_LOCALFILE = 'policy-localfile';
23020
23021
  const PROFILE_NAME_NOOP$2 = 'noop';
23021
23022
  const ENV_VAR_JWT_TRUSTED_ISSUER$1 = 'FAME_JWT_TRUSTED_ISSUER';
23022
23023
  const ENV_VAR_JWT_ALGORITHM$3 = 'FAME_JWT_ALGORITHM';
@@ -23024,18 +23025,21 @@ const ENV_VAR_JWT_AUDIENCE$3 = 'FAME_JWT_AUDIENCE';
23024
23025
  const ENV_VAR_JWKS_URL$1 = 'FAME_JWKS_URL';
23025
23026
  const ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY$1 = 'FAME_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY';
23026
23027
  const ENV_VAR_TRUSTED_CLIENT_SCOPE$1 = 'FAME_TRUSTED_CLIENT_SCOPE';
23028
+ const ENV_VAR_AUTH_POLICY_PATH = 'FAME_AUTH_POLICY_PATH';
23029
+ const ENV_VAR_AUTH_POLICY_FORMAT = 'FAME_AUTH_POLICY_FORMAT';
23027
23030
  const ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER$1 = 'FAME_JWT_REVERSE_AUTH_TRUSTED_ISSUER';
23028
23031
  const ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE$1 = 'FAME_JWT_REVERSE_AUTH_AUDIENCE';
23029
23032
  const ENV_VAR_HMAC_SECRET$1 = 'FAME_HMAC_SECRET';
23030
23033
  const DEFAULT_REVERSE_AUTH_ISSUER = 'reverse-auth.naylence.ai';
23031
23034
  const DEFAULT_REVERSE_AUTH_AUDIENCE = 'dev.naylence.ai';
23035
+ const DEFAULT_VERIFIER_CONFIG = {
23036
+ type: 'JWKSJWTTokenVerifier',
23037
+ jwks_url: Expressions.env(ENV_VAR_JWKS_URL$1),
23038
+ issuer: Expressions.env(ENV_VAR_JWT_TRUSTED_ISSUER$1),
23039
+ };
23032
23040
  const DEFAULT_PROFILE = {
23033
23041
  type: 'DefaultAuthorizer',
23034
- verifier: {
23035
- type: 'JWKSJWTTokenVerifier',
23036
- jwks_url: Expressions.env(ENV_VAR_JWKS_URL$1),
23037
- issuer: Expressions.env(ENV_VAR_JWT_TRUSTED_ISSUER$1),
23038
- },
23042
+ verifier: DEFAULT_VERIFIER_CONFIG,
23039
23043
  };
23040
23044
  const OAUTH2_PROFILE = {
23041
23045
  type: 'OAuth2Authorizer',
@@ -23080,11 +23084,22 @@ const OAUTH2_CALLBACK_PROFILE = {
23080
23084
  const NOOP_PROFILE$2 = {
23081
23085
  type: 'NoopAuthorizer',
23082
23086
  };
23087
+ const DEFAULT_POLICY_SOURCE = {
23088
+ type: 'LocalFileAuthorizationPolicySource',
23089
+ path: Expressions.env(ENV_VAR_AUTH_POLICY_PATH, './auth-policy.yaml'),
23090
+ format: Expressions.env(ENV_VAR_AUTH_POLICY_FORMAT, 'auto'),
23091
+ };
23092
+ const POLICY_LOCALFILE_PROFILE = {
23093
+ type: 'PolicyAuthorizer',
23094
+ verifier: DEFAULT_VERIFIER_CONFIG,
23095
+ policySource: DEFAULT_POLICY_SOURCE,
23096
+ };
23083
23097
  const PROFILE_MAP$5 = {
23084
23098
  [PROFILE_NAME_DEFAULT]: DEFAULT_PROFILE,
23085
23099
  [PROFILE_NAME_OAUTH2]: OAUTH2_PROFILE,
23086
23100
  [PROFILE_NAME_OAUTH2_GATED]: OAUTH2_GATED_PROFILE,
23087
23101
  [PROFILE_NAME_OAUTH2_CALLBACK]: OAUTH2_CALLBACK_PROFILE,
23102
+ [PROFILE_NAME_POLICY_LOCALFILE]: POLICY_LOCALFILE_PROFILE,
23088
23103
  [PROFILE_NAME_NOOP$2]: NOOP_PROFILE$2,
23089
23104
  };
23090
23105
  const PROFILE_ALIASES$1 = {
@@ -23098,6 +23113,9 @@ const PROFILE_ALIASES$1 = {
23098
23113
  'oauth2-callback': PROFILE_NAME_OAUTH2_CALLBACK,
23099
23114
  oauth2_callback: PROFILE_NAME_OAUTH2_CALLBACK,
23100
23115
  'reverse-auth': PROFILE_NAME_OAUTH2_CALLBACK,
23116
+ policy: PROFILE_NAME_POLICY_LOCALFILE,
23117
+ 'policy-localfile': PROFILE_NAME_POLICY_LOCALFILE,
23118
+ policy_localfile: PROFILE_NAME_POLICY_LOCALFILE,
23101
23119
  noop: PROFILE_NAME_NOOP$2,
23102
23120
  'no-op': PROFILE_NAME_NOOP$2,
23103
23121
  no_op: PROFILE_NAME_NOOP$2,
@@ -23173,6 +23191,8 @@ function deepClone$4(value) {
23173
23191
  var authorizationProfileFactory = /*#__PURE__*/Object.freeze({
23174
23192
  __proto__: null,
23175
23193
  AuthorizationProfileFactory: AuthorizationProfileFactory,
23194
+ ENV_VAR_AUTH_POLICY_FORMAT: ENV_VAR_AUTH_POLICY_FORMAT,
23195
+ ENV_VAR_AUTH_POLICY_PATH: ENV_VAR_AUTH_POLICY_PATH,
23176
23196
  ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY: ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY$1,
23177
23197
  ENV_VAR_HMAC_SECRET: ENV_VAR_HMAC_SECRET$1,
23178
23198
  ENV_VAR_JWKS_URL: ENV_VAR_JWKS_URL$1,
@@ -23188,6 +23208,7 @@ var authorizationProfileFactory = /*#__PURE__*/Object.freeze({
23188
23208
  PROFILE_NAME_OAUTH2: PROFILE_NAME_OAUTH2,
23189
23209
  PROFILE_NAME_OAUTH2_CALLBACK: PROFILE_NAME_OAUTH2_CALLBACK,
23190
23210
  PROFILE_NAME_OAUTH2_GATED: PROFILE_NAME_OAUTH2_GATED,
23211
+ PROFILE_NAME_POLICY_LOCALFILE: PROFILE_NAME_POLICY_LOCALFILE,
23191
23212
  default: AuthorizationProfileFactory
23192
23213
  });
23193
23214
 
@@ -23753,6 +23774,7 @@ class BasicAuthorizationPolicy {
23753
23774
  // Action must be explicitly provided; default to wildcard if omitted
23754
23775
  // for backward compatibility during transition
23755
23776
  const resolvedAction = action ?? '*';
23777
+ const resolvedActionNormalized = this.normalizeActionToken(resolvedAction) ?? resolvedAction;
23756
23778
  const address = extractAddress(envelope);
23757
23779
  const grantedScopes = extractGrantedScopes(context);
23758
23780
  const rawFrameType = envelope.frame
@@ -23762,8 +23784,8 @@ class BasicAuthorizationPolicy {
23762
23784
  : '';
23763
23785
  // Extract and normalize origin type for rule matching
23764
23786
  const rawOriginType = context?.originType;
23765
- const originTypeNormalized = typeof rawOriginType === 'string' && rawOriginType.trim().length > 0
23766
- ? rawOriginType.trim().toLowerCase()
23787
+ const originTypeNormalized = typeof rawOriginType === 'string'
23788
+ ? this.normalizeOriginTypeToken(rawOriginType) ?? undefined
23767
23789
  : undefined;
23768
23790
  const evaluationTrace = [];
23769
23791
  // Evaluate rules in order (first match wins)
@@ -23810,8 +23832,8 @@ class BasicAuthorizationPolicy {
23810
23832
  }
23811
23833
  }
23812
23834
  // Check action match
23813
- if (!rule.actions.has('*') && !rule.actions.has(resolvedAction)) {
23814
- step.expression = `action: ${resolvedAction} not in [${Array.from(rule.actions).join(', ')}]`;
23835
+ if (!rule.actions.has('*') && !rule.actions.has(resolvedActionNormalized)) {
23836
+ step.expression = `action: ${resolvedActionNormalized} not in [${Array.from(rule.actions).join(', ')}]`;
23815
23837
  step.result = false;
23816
23838
  evaluationTrace.push(step);
23817
23839
  continue;
@@ -23878,6 +23900,9 @@ class BasicAuthorizationPolicy {
23878
23900
  };
23879
23901
  }
23880
23902
  validateDefaultEffect(effect) {
23903
+ if (effect === undefined || effect === null) {
23904
+ return 'deny';
23905
+ }
23881
23906
  if (effect !== 'allow' && effect !== 'deny') {
23882
23907
  throw new Error(`Invalid default_effect: "${String(effect)}". Must be "allow" or "deny"`);
23883
23908
  }
@@ -23950,10 +23975,11 @@ class BasicAuthorizationPolicy {
23950
23975
  }
23951
23976
  // Handle single action
23952
23977
  if (typeof action === 'string') {
23953
- if (!VALID_ACTIONS.includes(action)) {
23978
+ const normalized = this.normalizeActionToken(action);
23979
+ if (!normalized) {
23954
23980
  throw new Error(`Invalid action in rule "${ruleId}": "${action}". Must be one of: ${VALID_ACTIONS.join(', ')}`);
23955
23981
  }
23956
- return new Set([action]);
23982
+ return new Set([normalized]);
23957
23983
  }
23958
23984
  // Handle array of actions
23959
23985
  if (!Array.isArray(action)) {
@@ -23967,10 +23993,11 @@ class BasicAuthorizationPolicy {
23967
23993
  if (typeof a !== 'string') {
23968
23994
  throw new Error(`Invalid action in rule "${ruleId}": all values must be strings`);
23969
23995
  }
23970
- if (!VALID_ACTIONS.includes(a)) {
23996
+ const normalized = this.normalizeActionToken(a);
23997
+ if (!normalized) {
23971
23998
  throw new Error(`Invalid action in rule "${ruleId}": "${a}". Must be one of: ${VALID_ACTIONS.join(', ')}`);
23972
23999
  }
23973
- actions.add(a);
24000
+ actions.add(normalized);
23974
24001
  }
23975
24002
  return actions;
23976
24003
  }
@@ -24073,11 +24100,12 @@ class BasicAuthorizationPolicy {
24073
24100
  }
24074
24101
  // Handle single origin type
24075
24102
  if (typeof originType === 'string') {
24076
- const normalized = originType.trim().toLowerCase();
24077
- if (!normalized) {
24103
+ const trimmed = originType.trim();
24104
+ if (!trimmed) {
24078
24105
  throw new Error(`Invalid origin_type in rule "${ruleId}": value must not be empty`);
24079
24106
  }
24080
- if (!VALID_ORIGIN_TYPES.includes(normalized)) {
24107
+ const normalized = this.normalizeOriginTypeToken(trimmed);
24108
+ if (!normalized) {
24081
24109
  throw new Error(`Invalid origin_type in rule "${ruleId}": "${originType}". Must be one of: ${VALID_ORIGIN_TYPES.join(', ')}`);
24082
24110
  }
24083
24111
  return new Set([normalized]);
@@ -24094,17 +24122,50 @@ class BasicAuthorizationPolicy {
24094
24122
  if (typeof ot !== 'string') {
24095
24123
  throw new Error(`Invalid origin_type in rule "${ruleId}": all values must be strings`);
24096
24124
  }
24097
- const normalized = ot.trim().toLowerCase();
24098
- if (!normalized) {
24125
+ const trimmed = ot.trim();
24126
+ if (!trimmed) {
24099
24127
  throw new Error(`Invalid origin_type in rule "${ruleId}": values must not be empty`);
24100
24128
  }
24101
- if (!VALID_ORIGIN_TYPES.includes(normalized)) {
24129
+ const normalized = this.normalizeOriginTypeToken(trimmed);
24130
+ if (!normalized) {
24102
24131
  throw new Error(`Invalid origin_type in rule "${ruleId}": "${ot}". Must be one of: ${VALID_ORIGIN_TYPES.join(', ')}`);
24103
24132
  }
24104
24133
  originTypes.add(normalized);
24105
24134
  }
24106
24135
  return originTypes;
24107
24136
  }
24137
+ normalizeActionToken(value) {
24138
+ const trimmed = value.trim();
24139
+ if (!trimmed) {
24140
+ return null;
24141
+ }
24142
+ if (trimmed === '*') {
24143
+ return '*';
24144
+ }
24145
+ const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
24146
+ const map = {
24147
+ connect: 'Connect',
24148
+ forwardupstream: 'ForwardUpstream',
24149
+ forwarddownstream: 'ForwardDownstream',
24150
+ forwardpeer: 'ForwardPeer',
24151
+ deliverlocal: 'DeliverLocal',
24152
+ };
24153
+ return map[normalized] ?? null;
24154
+ }
24155
+ normalizeOriginTypeToken(value) {
24156
+ const trimmed = value.trim();
24157
+ if (!trimmed) {
24158
+ return null;
24159
+ }
24160
+ const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
24161
+ const map = {
24162
+ downstream: 'downstream',
24163
+ upstream: 'upstream',
24164
+ peer: 'peer',
24165
+ local: 'local',
24166
+ };
24167
+ return map[normalized] ?? null;
24168
+ }
24108
24169
  }
24109
24170
 
24110
24171
  var basicAuthorizationPolicy = /*#__PURE__*/Object.freeze({
@@ -44906,16 +44967,22 @@ class LocalFileAuthorizationPolicySource {
44906
44967
  const factoryConfig = this.policyFactoryConfig ?? policyDefinition;
44907
44968
  // Ensure we have a type field for the factory
44908
44969
  if (!('type' in factoryConfig) || typeof factoryConfig.type !== 'string') {
44909
- throw new Error(`Policy definition at ${this.path} must have a 'type' field, ` +
44910
- `or policyFactory config must be provided`);
44970
+ logger$1.warning('policy_type_missing_defaulting_to_basic', {
44971
+ path: this.path,
44972
+ });
44973
+ factoryConfig.type =
44974
+ 'BasicAuthorizationPolicy';
44911
44975
  }
44912
44976
  // Build the factory config with the policy definition
44913
44977
  // The file content IS the policy definition, so we extract the type
44914
44978
  // and wrap the remaining content as the policyDefinition
44915
- const { type, ...restOfFile } = policyDefinition;
44979
+ const { type: fileType, ...restOfFile } = policyDefinition;
44980
+ const resolvedType = typeof fileType === 'string' && fileType.trim().length > 0
44981
+ ? fileType
44982
+ : factoryConfig.type;
44916
44983
  const mergedConfig = this.policyFactoryConfig != null
44917
44984
  ? { ...this.policyFactoryConfig, policyDefinition }
44918
- : { type: factoryConfig.type, policyDefinition: restOfFile };
44985
+ : { type: resolvedType, policyDefinition: restOfFile };
44919
44986
  // Create the policy using the factory system
44920
44987
  const policy = await AuthorizationPolicyFactory.createAuthorizationPolicy(mergedConfig);
44921
44988
  if (!policy) {
@@ -8,6 +8,7 @@ export declare const PROFILE_NAME_DEFAULT = "jwt";
8
8
  export declare const PROFILE_NAME_OAUTH2 = "oauth2";
9
9
  export declare const PROFILE_NAME_OAUTH2_GATED = "oauth2-gated";
10
10
  export declare const PROFILE_NAME_OAUTH2_CALLBACK = "oauth2-callback";
11
+ export declare const PROFILE_NAME_POLICY_LOCALFILE = "policy-localfile";
11
12
  export declare const PROFILE_NAME_NOOP = "noop";
12
13
  export declare const ENV_VAR_JWT_TRUSTED_ISSUER = "FAME_JWT_TRUSTED_ISSUER";
13
14
  export declare const ENV_VAR_JWT_ALGORITHM = "FAME_JWT_ALGORITHM";
@@ -15,6 +16,8 @@ export declare const ENV_VAR_JWT_AUDIENCE = "FAME_JWT_AUDIENCE";
15
16
  export declare const ENV_VAR_JWKS_URL = "FAME_JWKS_URL";
16
17
  export declare const ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY = "FAME_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY";
17
18
  export declare const ENV_VAR_TRUSTED_CLIENT_SCOPE = "FAME_TRUSTED_CLIENT_SCOPE";
19
+ export declare const ENV_VAR_AUTH_POLICY_PATH = "FAME_AUTH_POLICY_PATH";
20
+ export declare const ENV_VAR_AUTH_POLICY_FORMAT = "FAME_AUTH_POLICY_FORMAT";
18
21
  export declare const ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER = "FAME_JWT_REVERSE_AUTH_TRUSTED_ISSUER";
19
22
  export declare const ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE = "FAME_JWT_REVERSE_AUTH_AUDIENCE";
20
23
  export declare const ENV_VAR_HMAC_SECRET = "FAME_HMAC_SECRET";
@@ -20,6 +20,11 @@ export type RuleEffect = 'allow' | 'deny';
20
20
  * - '*': Matches all actions (wildcard)
21
21
  */
22
22
  export type RuleAction = 'Connect' | 'ForwardUpstream' | 'ForwardDownstream' | 'ForwardPeer' | 'DeliverLocal' | '*';
23
+ /**
24
+ * Action input tokens accepted in policy definitions.
25
+ * Values are normalized case-insensitively and support snake_case.
26
+ */
27
+ export type RuleActionInput = RuleAction | string;
23
28
  /**
24
29
  * Scope requirement using logical operators.
25
30
  *
@@ -68,9 +73,10 @@ export interface AuthorizationRuleDefinition {
68
73
  /**
69
74
  * The action type this rule applies to.
70
75
  * Can be a single action or an array of actions (implicit any-of).
76
+ * Values are matched case-insensitively and support snake_case equivalents.
71
77
  * @default '*' (all actions)
72
78
  */
73
- action?: RuleAction | RuleAction[];
79
+ action?: RuleActionInput | RuleActionInput[];
74
80
  /**
75
81
  * Address pattern(s) to match using glob syntax.
76
82
  * Can be a single pattern or an array (implicit any-of).
@@ -128,7 +134,7 @@ export interface AuthorizationPolicyDefinition {
128
134
  /**
129
135
  * Default effect when no rule matches.
130
136
  */
131
- default_effect: RuleEffect;
137
+ default_effect?: RuleEffect;
132
138
  /**
133
139
  * List of authorization rules, evaluated in order.
134
140
  * First matching rule determines the outcome.
@@ -75,4 +75,6 @@ export declare class BasicAuthorizationPolicy implements AuthorizationPolicy {
75
75
  * Valid values: 'downstream', 'upstream', 'peer', 'local' (case-insensitive).
76
76
  */
77
77
  private compileOriginTypes;
78
+ private normalizeActionToken;
79
+ private normalizeOriginTypeToken;
78
80
  }
@@ -2,4 +2,4 @@
2
2
  * The package version, injected at build time.
3
3
  * @internal
4
4
  */
5
- export declare const VERSION = "0.4.2";
5
+ export declare const VERSION = "0.4.4";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naylence/runtime",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "type": "module",
5
5
  "description": "Naylence Runtime - Complete TypeScript runtime",
6
6
  "author": "Naylence Dev <naylencedev@gmail.com>",