@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.
@@ -525,12 +525,12 @@ async function ensureRuntimeFactoriesRegistered(registry = factory.Registry) {
525
525
  }
526
526
 
527
527
  // This file is auto-generated during build - do not edit manually
528
- // Generated from package.json version: 0.4.2
528
+ // Generated from package.json version: 0.4.4
529
529
  /**
530
530
  * The package version, injected at build time.
531
531
  * @internal
532
532
  */
533
- const VERSION = '0.4.2';
533
+ const VERSION = '0.4.4';
534
534
 
535
535
  let initialized = false;
536
536
  const runtimePlugin = {
@@ -21926,6 +21926,7 @@ const PROFILE_NAME_DEFAULT = 'jwt';
21926
21926
  const PROFILE_NAME_OAUTH2 = 'oauth2';
21927
21927
  const PROFILE_NAME_OAUTH2_GATED = 'oauth2-gated';
21928
21928
  const PROFILE_NAME_OAUTH2_CALLBACK = 'oauth2-callback';
21929
+ const PROFILE_NAME_POLICY_LOCALFILE = 'policy-localfile';
21929
21930
  const PROFILE_NAME_NOOP$2 = 'noop';
21930
21931
  const ENV_VAR_JWT_TRUSTED_ISSUER$1 = 'FAME_JWT_TRUSTED_ISSUER';
21931
21932
  const ENV_VAR_JWT_ALGORITHM$1 = 'FAME_JWT_ALGORITHM';
@@ -21933,18 +21934,21 @@ const ENV_VAR_JWT_AUDIENCE$2 = 'FAME_JWT_AUDIENCE';
21933
21934
  const ENV_VAR_JWKS_URL$1 = 'FAME_JWKS_URL';
21934
21935
  const ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY$1 = 'FAME_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY';
21935
21936
  const ENV_VAR_TRUSTED_CLIENT_SCOPE$1 = 'FAME_TRUSTED_CLIENT_SCOPE';
21937
+ const ENV_VAR_AUTH_POLICY_PATH = 'FAME_AUTH_POLICY_PATH';
21938
+ const ENV_VAR_AUTH_POLICY_FORMAT = 'FAME_AUTH_POLICY_FORMAT';
21936
21939
  const ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER$1 = 'FAME_JWT_REVERSE_AUTH_TRUSTED_ISSUER';
21937
21940
  const ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE$1 = 'FAME_JWT_REVERSE_AUTH_AUDIENCE';
21938
21941
  const ENV_VAR_HMAC_SECRET$1 = 'FAME_HMAC_SECRET';
21939
21942
  const DEFAULT_REVERSE_AUTH_ISSUER = 'reverse-auth.naylence.ai';
21940
21943
  const DEFAULT_REVERSE_AUTH_AUDIENCE = 'dev.naylence.ai';
21944
+ const DEFAULT_VERIFIER_CONFIG = {
21945
+ type: 'JWKSJWTTokenVerifier',
21946
+ jwks_url: factory.Expressions.env(ENV_VAR_JWKS_URL$1),
21947
+ issuer: factory.Expressions.env(ENV_VAR_JWT_TRUSTED_ISSUER$1),
21948
+ };
21941
21949
  const DEFAULT_PROFILE = {
21942
21950
  type: 'DefaultAuthorizer',
21943
- verifier: {
21944
- type: 'JWKSJWTTokenVerifier',
21945
- jwks_url: factory.Expressions.env(ENV_VAR_JWKS_URL$1),
21946
- issuer: factory.Expressions.env(ENV_VAR_JWT_TRUSTED_ISSUER$1),
21947
- },
21951
+ verifier: DEFAULT_VERIFIER_CONFIG,
21948
21952
  };
21949
21953
  const OAUTH2_PROFILE = {
21950
21954
  type: 'OAuth2Authorizer',
@@ -21989,11 +21993,22 @@ const OAUTH2_CALLBACK_PROFILE = {
21989
21993
  const NOOP_PROFILE$2 = {
21990
21994
  type: 'NoopAuthorizer',
21991
21995
  };
21996
+ const DEFAULT_POLICY_SOURCE = {
21997
+ type: 'LocalFileAuthorizationPolicySource',
21998
+ path: factory.Expressions.env(ENV_VAR_AUTH_POLICY_PATH, './auth-policy.yaml'),
21999
+ format: factory.Expressions.env(ENV_VAR_AUTH_POLICY_FORMAT, 'auto'),
22000
+ };
22001
+ const POLICY_LOCALFILE_PROFILE = {
22002
+ type: 'PolicyAuthorizer',
22003
+ verifier: DEFAULT_VERIFIER_CONFIG,
22004
+ policySource: DEFAULT_POLICY_SOURCE,
22005
+ };
21992
22006
  const PROFILE_MAP$5 = {
21993
22007
  [PROFILE_NAME_DEFAULT]: DEFAULT_PROFILE,
21994
22008
  [PROFILE_NAME_OAUTH2]: OAUTH2_PROFILE,
21995
22009
  [PROFILE_NAME_OAUTH2_GATED]: OAUTH2_GATED_PROFILE,
21996
22010
  [PROFILE_NAME_OAUTH2_CALLBACK]: OAUTH2_CALLBACK_PROFILE,
22011
+ [PROFILE_NAME_POLICY_LOCALFILE]: POLICY_LOCALFILE_PROFILE,
21997
22012
  [PROFILE_NAME_NOOP$2]: NOOP_PROFILE$2,
21998
22013
  };
21999
22014
  const PROFILE_ALIASES$1 = {
@@ -22007,6 +22022,9 @@ const PROFILE_ALIASES$1 = {
22007
22022
  'oauth2-callback': PROFILE_NAME_OAUTH2_CALLBACK,
22008
22023
  oauth2_callback: PROFILE_NAME_OAUTH2_CALLBACK,
22009
22024
  'reverse-auth': PROFILE_NAME_OAUTH2_CALLBACK,
22025
+ policy: PROFILE_NAME_POLICY_LOCALFILE,
22026
+ 'policy-localfile': PROFILE_NAME_POLICY_LOCALFILE,
22027
+ policy_localfile: PROFILE_NAME_POLICY_LOCALFILE,
22010
22028
  noop: PROFILE_NAME_NOOP$2,
22011
22029
  'no-op': PROFILE_NAME_NOOP$2,
22012
22030
  no_op: PROFILE_NAME_NOOP$2,
@@ -22082,6 +22100,8 @@ function deepClone$4(value) {
22082
22100
  var authorizationProfileFactory = /*#__PURE__*/Object.freeze({
22083
22101
  __proto__: null,
22084
22102
  AuthorizationProfileFactory: AuthorizationProfileFactory,
22103
+ ENV_VAR_AUTH_POLICY_FORMAT: ENV_VAR_AUTH_POLICY_FORMAT,
22104
+ ENV_VAR_AUTH_POLICY_PATH: ENV_VAR_AUTH_POLICY_PATH,
22085
22105
  ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY: ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY$1,
22086
22106
  ENV_VAR_HMAC_SECRET: ENV_VAR_HMAC_SECRET$1,
22087
22107
  ENV_VAR_JWKS_URL: ENV_VAR_JWKS_URL$1,
@@ -22097,6 +22117,7 @@ var authorizationProfileFactory = /*#__PURE__*/Object.freeze({
22097
22117
  PROFILE_NAME_OAUTH2: PROFILE_NAME_OAUTH2,
22098
22118
  PROFILE_NAME_OAUTH2_CALLBACK: PROFILE_NAME_OAUTH2_CALLBACK,
22099
22119
  PROFILE_NAME_OAUTH2_GATED: PROFILE_NAME_OAUTH2_GATED,
22120
+ PROFILE_NAME_POLICY_LOCALFILE: PROFILE_NAME_POLICY_LOCALFILE,
22100
22121
  default: AuthorizationProfileFactory
22101
22122
  });
22102
22123
 
@@ -22655,6 +22676,7 @@ class BasicAuthorizationPolicy {
22655
22676
  // Action must be explicitly provided; default to wildcard if omitted
22656
22677
  // for backward compatibility during transition
22657
22678
  const resolvedAction = action ?? '*';
22679
+ const resolvedActionNormalized = this.normalizeActionToken(resolvedAction) ?? resolvedAction;
22658
22680
  const address = extractAddress(envelope);
22659
22681
  const grantedScopes = extractGrantedScopes(context);
22660
22682
  const rawFrameType = envelope.frame
@@ -22664,8 +22686,8 @@ class BasicAuthorizationPolicy {
22664
22686
  : '';
22665
22687
  // Extract and normalize origin type for rule matching
22666
22688
  const rawOriginType = context?.originType;
22667
- const originTypeNormalized = typeof rawOriginType === 'string' && rawOriginType.trim().length > 0
22668
- ? rawOriginType.trim().toLowerCase()
22689
+ const originTypeNormalized = typeof rawOriginType === 'string'
22690
+ ? this.normalizeOriginTypeToken(rawOriginType) ?? undefined
22669
22691
  : undefined;
22670
22692
  const evaluationTrace = [];
22671
22693
  // Evaluate rules in order (first match wins)
@@ -22712,8 +22734,8 @@ class BasicAuthorizationPolicy {
22712
22734
  }
22713
22735
  }
22714
22736
  // Check action match
22715
- if (!rule.actions.has('*') && !rule.actions.has(resolvedAction)) {
22716
- step.expression = `action: ${resolvedAction} not in [${Array.from(rule.actions).join(', ')}]`;
22737
+ if (!rule.actions.has('*') && !rule.actions.has(resolvedActionNormalized)) {
22738
+ step.expression = `action: ${resolvedActionNormalized} not in [${Array.from(rule.actions).join(', ')}]`;
22717
22739
  step.result = false;
22718
22740
  evaluationTrace.push(step);
22719
22741
  continue;
@@ -22780,6 +22802,9 @@ class BasicAuthorizationPolicy {
22780
22802
  };
22781
22803
  }
22782
22804
  validateDefaultEffect(effect) {
22805
+ if (effect === undefined || effect === null) {
22806
+ return 'deny';
22807
+ }
22783
22808
  if (effect !== 'allow' && effect !== 'deny') {
22784
22809
  throw new Error(`Invalid default_effect: "${String(effect)}". Must be "allow" or "deny"`);
22785
22810
  }
@@ -22852,10 +22877,11 @@ class BasicAuthorizationPolicy {
22852
22877
  }
22853
22878
  // Handle single action
22854
22879
  if (typeof action === 'string') {
22855
- if (!VALID_ACTIONS.includes(action)) {
22880
+ const normalized = this.normalizeActionToken(action);
22881
+ if (!normalized) {
22856
22882
  throw new Error(`Invalid action in rule "${ruleId}": "${action}". Must be one of: ${VALID_ACTIONS.join(', ')}`);
22857
22883
  }
22858
- return new Set([action]);
22884
+ return new Set([normalized]);
22859
22885
  }
22860
22886
  // Handle array of actions
22861
22887
  if (!Array.isArray(action)) {
@@ -22869,10 +22895,11 @@ class BasicAuthorizationPolicy {
22869
22895
  if (typeof a !== 'string') {
22870
22896
  throw new Error(`Invalid action in rule "${ruleId}": all values must be strings`);
22871
22897
  }
22872
- if (!VALID_ACTIONS.includes(a)) {
22898
+ const normalized = this.normalizeActionToken(a);
22899
+ if (!normalized) {
22873
22900
  throw new Error(`Invalid action in rule "${ruleId}": "${a}". Must be one of: ${VALID_ACTIONS.join(', ')}`);
22874
22901
  }
22875
- actions.add(a);
22902
+ actions.add(normalized);
22876
22903
  }
22877
22904
  return actions;
22878
22905
  }
@@ -22975,11 +23002,12 @@ class BasicAuthorizationPolicy {
22975
23002
  }
22976
23003
  // Handle single origin type
22977
23004
  if (typeof originType === 'string') {
22978
- const normalized = originType.trim().toLowerCase();
22979
- if (!normalized) {
23005
+ const trimmed = originType.trim();
23006
+ if (!trimmed) {
22980
23007
  throw new Error(`Invalid origin_type in rule "${ruleId}": value must not be empty`);
22981
23008
  }
22982
- if (!VALID_ORIGIN_TYPES.includes(normalized)) {
23009
+ const normalized = this.normalizeOriginTypeToken(trimmed);
23010
+ if (!normalized) {
22983
23011
  throw new Error(`Invalid origin_type in rule "${ruleId}": "${originType}". Must be one of: ${VALID_ORIGIN_TYPES.join(', ')}`);
22984
23012
  }
22985
23013
  return new Set([normalized]);
@@ -22996,17 +23024,50 @@ class BasicAuthorizationPolicy {
22996
23024
  if (typeof ot !== 'string') {
22997
23025
  throw new Error(`Invalid origin_type in rule "${ruleId}": all values must be strings`);
22998
23026
  }
22999
- const normalized = ot.trim().toLowerCase();
23000
- if (!normalized) {
23027
+ const trimmed = ot.trim();
23028
+ if (!trimmed) {
23001
23029
  throw new Error(`Invalid origin_type in rule "${ruleId}": values must not be empty`);
23002
23030
  }
23003
- if (!VALID_ORIGIN_TYPES.includes(normalized)) {
23031
+ const normalized = this.normalizeOriginTypeToken(trimmed);
23032
+ if (!normalized) {
23004
23033
  throw new Error(`Invalid origin_type in rule "${ruleId}": "${ot}". Must be one of: ${VALID_ORIGIN_TYPES.join(', ')}`);
23005
23034
  }
23006
23035
  originTypes.add(normalized);
23007
23036
  }
23008
23037
  return originTypes;
23009
23038
  }
23039
+ normalizeActionToken(value) {
23040
+ const trimmed = value.trim();
23041
+ if (!trimmed) {
23042
+ return null;
23043
+ }
23044
+ if (trimmed === '*') {
23045
+ return '*';
23046
+ }
23047
+ const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
23048
+ const map = {
23049
+ connect: 'Connect',
23050
+ forwardupstream: 'ForwardUpstream',
23051
+ forwarddownstream: 'ForwardDownstream',
23052
+ forwardpeer: 'ForwardPeer',
23053
+ deliverlocal: 'DeliverLocal',
23054
+ };
23055
+ return map[normalized] ?? null;
23056
+ }
23057
+ normalizeOriginTypeToken(value) {
23058
+ const trimmed = value.trim();
23059
+ if (!trimmed) {
23060
+ return null;
23061
+ }
23062
+ const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
23063
+ const map = {
23064
+ downstream: 'downstream',
23065
+ upstream: 'upstream',
23066
+ peer: 'peer',
23067
+ local: 'local',
23068
+ };
23069
+ return map[normalized] ?? null;
23070
+ }
23010
23071
  }
23011
23072
 
23012
23073
  var basicAuthorizationPolicy = /*#__PURE__*/Object.freeze({
@@ -42755,16 +42816,22 @@ class LocalFileAuthorizationPolicySource {
42755
42816
  const factoryConfig = this.policyFactoryConfig ?? policyDefinition;
42756
42817
  // Ensure we have a type field for the factory
42757
42818
  if (!('type' in factoryConfig) || typeof factoryConfig.type !== 'string') {
42758
- throw new Error(`Policy definition at ${this.path} must have a 'type' field, ` +
42759
- `or policyFactory config must be provided`);
42819
+ logger$1.warning('policy_type_missing_defaulting_to_basic', {
42820
+ path: this.path,
42821
+ });
42822
+ factoryConfig.type =
42823
+ 'BasicAuthorizationPolicy';
42760
42824
  }
42761
42825
  // Build the factory config with the policy definition
42762
42826
  // The file content IS the policy definition, so we extract the type
42763
42827
  // and wrap the remaining content as the policyDefinition
42764
- const { type, ...restOfFile } = policyDefinition;
42828
+ const { type: fileType, ...restOfFile } = policyDefinition;
42829
+ const resolvedType = typeof fileType === 'string' && fileType.trim().length > 0
42830
+ ? fileType
42831
+ : factoryConfig.type;
42765
42832
  const mergedConfig = this.policyFactoryConfig != null
42766
42833
  ? { ...this.policyFactoryConfig, policyDefinition }
42767
- : { type: factoryConfig.type, policyDefinition: restOfFile };
42834
+ : { type: resolvedType, policyDefinition: restOfFile };
42768
42835
  // Create the policy using the factory system
42769
42836
  const policy = await AuthorizationPolicyFactory.createAuthorizationPolicy(mergedConfig);
42770
42837
  if (!policy) {
@@ -523,12 +523,12 @@ async function ensureRuntimeFactoriesRegistered(registry = Registry) {
523
523
  }
524
524
 
525
525
  // This file is auto-generated during build - do not edit manually
526
- // Generated from package.json version: 0.4.2
526
+ // Generated from package.json version: 0.4.4
527
527
  /**
528
528
  * The package version, injected at build time.
529
529
  * @internal
530
530
  */
531
- const VERSION = '0.4.2';
531
+ const VERSION = '0.4.4';
532
532
 
533
533
  let initialized = false;
534
534
  const runtimePlugin = {
@@ -21924,6 +21924,7 @@ const PROFILE_NAME_DEFAULT = 'jwt';
21924
21924
  const PROFILE_NAME_OAUTH2 = 'oauth2';
21925
21925
  const PROFILE_NAME_OAUTH2_GATED = 'oauth2-gated';
21926
21926
  const PROFILE_NAME_OAUTH2_CALLBACK = 'oauth2-callback';
21927
+ const PROFILE_NAME_POLICY_LOCALFILE = 'policy-localfile';
21927
21928
  const PROFILE_NAME_NOOP$2 = 'noop';
21928
21929
  const ENV_VAR_JWT_TRUSTED_ISSUER$1 = 'FAME_JWT_TRUSTED_ISSUER';
21929
21930
  const ENV_VAR_JWT_ALGORITHM$1 = 'FAME_JWT_ALGORITHM';
@@ -21931,18 +21932,21 @@ const ENV_VAR_JWT_AUDIENCE$2 = 'FAME_JWT_AUDIENCE';
21931
21932
  const ENV_VAR_JWKS_URL$1 = 'FAME_JWKS_URL';
21932
21933
  const ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY$1 = 'FAME_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY';
21933
21934
  const ENV_VAR_TRUSTED_CLIENT_SCOPE$1 = 'FAME_TRUSTED_CLIENT_SCOPE';
21935
+ const ENV_VAR_AUTH_POLICY_PATH = 'FAME_AUTH_POLICY_PATH';
21936
+ const ENV_VAR_AUTH_POLICY_FORMAT = 'FAME_AUTH_POLICY_FORMAT';
21934
21937
  const ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER$1 = 'FAME_JWT_REVERSE_AUTH_TRUSTED_ISSUER';
21935
21938
  const ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE$1 = 'FAME_JWT_REVERSE_AUTH_AUDIENCE';
21936
21939
  const ENV_VAR_HMAC_SECRET$1 = 'FAME_HMAC_SECRET';
21937
21940
  const DEFAULT_REVERSE_AUTH_ISSUER = 'reverse-auth.naylence.ai';
21938
21941
  const DEFAULT_REVERSE_AUTH_AUDIENCE = 'dev.naylence.ai';
21942
+ const DEFAULT_VERIFIER_CONFIG = {
21943
+ type: 'JWKSJWTTokenVerifier',
21944
+ jwks_url: Expressions.env(ENV_VAR_JWKS_URL$1),
21945
+ issuer: Expressions.env(ENV_VAR_JWT_TRUSTED_ISSUER$1),
21946
+ };
21939
21947
  const DEFAULT_PROFILE = {
21940
21948
  type: 'DefaultAuthorizer',
21941
- verifier: {
21942
- type: 'JWKSJWTTokenVerifier',
21943
- jwks_url: Expressions.env(ENV_VAR_JWKS_URL$1),
21944
- issuer: Expressions.env(ENV_VAR_JWT_TRUSTED_ISSUER$1),
21945
- },
21949
+ verifier: DEFAULT_VERIFIER_CONFIG,
21946
21950
  };
21947
21951
  const OAUTH2_PROFILE = {
21948
21952
  type: 'OAuth2Authorizer',
@@ -21987,11 +21991,22 @@ const OAUTH2_CALLBACK_PROFILE = {
21987
21991
  const NOOP_PROFILE$2 = {
21988
21992
  type: 'NoopAuthorizer',
21989
21993
  };
21994
+ const DEFAULT_POLICY_SOURCE = {
21995
+ type: 'LocalFileAuthorizationPolicySource',
21996
+ path: Expressions.env(ENV_VAR_AUTH_POLICY_PATH, './auth-policy.yaml'),
21997
+ format: Expressions.env(ENV_VAR_AUTH_POLICY_FORMAT, 'auto'),
21998
+ };
21999
+ const POLICY_LOCALFILE_PROFILE = {
22000
+ type: 'PolicyAuthorizer',
22001
+ verifier: DEFAULT_VERIFIER_CONFIG,
22002
+ policySource: DEFAULT_POLICY_SOURCE,
22003
+ };
21990
22004
  const PROFILE_MAP$5 = {
21991
22005
  [PROFILE_NAME_DEFAULT]: DEFAULT_PROFILE,
21992
22006
  [PROFILE_NAME_OAUTH2]: OAUTH2_PROFILE,
21993
22007
  [PROFILE_NAME_OAUTH2_GATED]: OAUTH2_GATED_PROFILE,
21994
22008
  [PROFILE_NAME_OAUTH2_CALLBACK]: OAUTH2_CALLBACK_PROFILE,
22009
+ [PROFILE_NAME_POLICY_LOCALFILE]: POLICY_LOCALFILE_PROFILE,
21995
22010
  [PROFILE_NAME_NOOP$2]: NOOP_PROFILE$2,
21996
22011
  };
21997
22012
  const PROFILE_ALIASES$1 = {
@@ -22005,6 +22020,9 @@ const PROFILE_ALIASES$1 = {
22005
22020
  'oauth2-callback': PROFILE_NAME_OAUTH2_CALLBACK,
22006
22021
  oauth2_callback: PROFILE_NAME_OAUTH2_CALLBACK,
22007
22022
  'reverse-auth': PROFILE_NAME_OAUTH2_CALLBACK,
22023
+ policy: PROFILE_NAME_POLICY_LOCALFILE,
22024
+ 'policy-localfile': PROFILE_NAME_POLICY_LOCALFILE,
22025
+ policy_localfile: PROFILE_NAME_POLICY_LOCALFILE,
22008
22026
  noop: PROFILE_NAME_NOOP$2,
22009
22027
  'no-op': PROFILE_NAME_NOOP$2,
22010
22028
  no_op: PROFILE_NAME_NOOP$2,
@@ -22080,6 +22098,8 @@ function deepClone$4(value) {
22080
22098
  var authorizationProfileFactory = /*#__PURE__*/Object.freeze({
22081
22099
  __proto__: null,
22082
22100
  AuthorizationProfileFactory: AuthorizationProfileFactory,
22101
+ ENV_VAR_AUTH_POLICY_FORMAT: ENV_VAR_AUTH_POLICY_FORMAT,
22102
+ ENV_VAR_AUTH_POLICY_PATH: ENV_VAR_AUTH_POLICY_PATH,
22083
22103
  ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY: ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY$1,
22084
22104
  ENV_VAR_HMAC_SECRET: ENV_VAR_HMAC_SECRET$1,
22085
22105
  ENV_VAR_JWKS_URL: ENV_VAR_JWKS_URL$1,
@@ -22095,6 +22115,7 @@ var authorizationProfileFactory = /*#__PURE__*/Object.freeze({
22095
22115
  PROFILE_NAME_OAUTH2: PROFILE_NAME_OAUTH2,
22096
22116
  PROFILE_NAME_OAUTH2_CALLBACK: PROFILE_NAME_OAUTH2_CALLBACK,
22097
22117
  PROFILE_NAME_OAUTH2_GATED: PROFILE_NAME_OAUTH2_GATED,
22118
+ PROFILE_NAME_POLICY_LOCALFILE: PROFILE_NAME_POLICY_LOCALFILE,
22098
22119
  default: AuthorizationProfileFactory
22099
22120
  });
22100
22121
 
@@ -22653,6 +22674,7 @@ class BasicAuthorizationPolicy {
22653
22674
  // Action must be explicitly provided; default to wildcard if omitted
22654
22675
  // for backward compatibility during transition
22655
22676
  const resolvedAction = action ?? '*';
22677
+ const resolvedActionNormalized = this.normalizeActionToken(resolvedAction) ?? resolvedAction;
22656
22678
  const address = extractAddress(envelope);
22657
22679
  const grantedScopes = extractGrantedScopes(context);
22658
22680
  const rawFrameType = envelope.frame
@@ -22662,8 +22684,8 @@ class BasicAuthorizationPolicy {
22662
22684
  : '';
22663
22685
  // Extract and normalize origin type for rule matching
22664
22686
  const rawOriginType = context?.originType;
22665
- const originTypeNormalized = typeof rawOriginType === 'string' && rawOriginType.trim().length > 0
22666
- ? rawOriginType.trim().toLowerCase()
22687
+ const originTypeNormalized = typeof rawOriginType === 'string'
22688
+ ? this.normalizeOriginTypeToken(rawOriginType) ?? undefined
22667
22689
  : undefined;
22668
22690
  const evaluationTrace = [];
22669
22691
  // Evaluate rules in order (first match wins)
@@ -22710,8 +22732,8 @@ class BasicAuthorizationPolicy {
22710
22732
  }
22711
22733
  }
22712
22734
  // Check action match
22713
- if (!rule.actions.has('*') && !rule.actions.has(resolvedAction)) {
22714
- step.expression = `action: ${resolvedAction} not in [${Array.from(rule.actions).join(', ')}]`;
22735
+ if (!rule.actions.has('*') && !rule.actions.has(resolvedActionNormalized)) {
22736
+ step.expression = `action: ${resolvedActionNormalized} not in [${Array.from(rule.actions).join(', ')}]`;
22715
22737
  step.result = false;
22716
22738
  evaluationTrace.push(step);
22717
22739
  continue;
@@ -22778,6 +22800,9 @@ class BasicAuthorizationPolicy {
22778
22800
  };
22779
22801
  }
22780
22802
  validateDefaultEffect(effect) {
22803
+ if (effect === undefined || effect === null) {
22804
+ return 'deny';
22805
+ }
22781
22806
  if (effect !== 'allow' && effect !== 'deny') {
22782
22807
  throw new Error(`Invalid default_effect: "${String(effect)}". Must be "allow" or "deny"`);
22783
22808
  }
@@ -22850,10 +22875,11 @@ class BasicAuthorizationPolicy {
22850
22875
  }
22851
22876
  // Handle single action
22852
22877
  if (typeof action === 'string') {
22853
- if (!VALID_ACTIONS.includes(action)) {
22878
+ const normalized = this.normalizeActionToken(action);
22879
+ if (!normalized) {
22854
22880
  throw new Error(`Invalid action in rule "${ruleId}": "${action}". Must be one of: ${VALID_ACTIONS.join(', ')}`);
22855
22881
  }
22856
- return new Set([action]);
22882
+ return new Set([normalized]);
22857
22883
  }
22858
22884
  // Handle array of actions
22859
22885
  if (!Array.isArray(action)) {
@@ -22867,10 +22893,11 @@ class BasicAuthorizationPolicy {
22867
22893
  if (typeof a !== 'string') {
22868
22894
  throw new Error(`Invalid action in rule "${ruleId}": all values must be strings`);
22869
22895
  }
22870
- if (!VALID_ACTIONS.includes(a)) {
22896
+ const normalized = this.normalizeActionToken(a);
22897
+ if (!normalized) {
22871
22898
  throw new Error(`Invalid action in rule "${ruleId}": "${a}". Must be one of: ${VALID_ACTIONS.join(', ')}`);
22872
22899
  }
22873
- actions.add(a);
22900
+ actions.add(normalized);
22874
22901
  }
22875
22902
  return actions;
22876
22903
  }
@@ -22973,11 +23000,12 @@ class BasicAuthorizationPolicy {
22973
23000
  }
22974
23001
  // Handle single origin type
22975
23002
  if (typeof originType === 'string') {
22976
- const normalized = originType.trim().toLowerCase();
22977
- if (!normalized) {
23003
+ const trimmed = originType.trim();
23004
+ if (!trimmed) {
22978
23005
  throw new Error(`Invalid origin_type in rule "${ruleId}": value must not be empty`);
22979
23006
  }
22980
- if (!VALID_ORIGIN_TYPES.includes(normalized)) {
23007
+ const normalized = this.normalizeOriginTypeToken(trimmed);
23008
+ if (!normalized) {
22981
23009
  throw new Error(`Invalid origin_type in rule "${ruleId}": "${originType}". Must be one of: ${VALID_ORIGIN_TYPES.join(', ')}`);
22982
23010
  }
22983
23011
  return new Set([normalized]);
@@ -22994,17 +23022,50 @@ class BasicAuthorizationPolicy {
22994
23022
  if (typeof ot !== 'string') {
22995
23023
  throw new Error(`Invalid origin_type in rule "${ruleId}": all values must be strings`);
22996
23024
  }
22997
- const normalized = ot.trim().toLowerCase();
22998
- if (!normalized) {
23025
+ const trimmed = ot.trim();
23026
+ if (!trimmed) {
22999
23027
  throw new Error(`Invalid origin_type in rule "${ruleId}": values must not be empty`);
23000
23028
  }
23001
- if (!VALID_ORIGIN_TYPES.includes(normalized)) {
23029
+ const normalized = this.normalizeOriginTypeToken(trimmed);
23030
+ if (!normalized) {
23002
23031
  throw new Error(`Invalid origin_type in rule "${ruleId}": "${ot}". Must be one of: ${VALID_ORIGIN_TYPES.join(', ')}`);
23003
23032
  }
23004
23033
  originTypes.add(normalized);
23005
23034
  }
23006
23035
  return originTypes;
23007
23036
  }
23037
+ normalizeActionToken(value) {
23038
+ const trimmed = value.trim();
23039
+ if (!trimmed) {
23040
+ return null;
23041
+ }
23042
+ if (trimmed === '*') {
23043
+ return '*';
23044
+ }
23045
+ const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
23046
+ const map = {
23047
+ connect: 'Connect',
23048
+ forwardupstream: 'ForwardUpstream',
23049
+ forwarddownstream: 'ForwardDownstream',
23050
+ forwardpeer: 'ForwardPeer',
23051
+ deliverlocal: 'DeliverLocal',
23052
+ };
23053
+ return map[normalized] ?? null;
23054
+ }
23055
+ normalizeOriginTypeToken(value) {
23056
+ const trimmed = value.trim();
23057
+ if (!trimmed) {
23058
+ return null;
23059
+ }
23060
+ const normalized = trimmed.replace(/[\s_-]+/g, '').toLowerCase();
23061
+ const map = {
23062
+ downstream: 'downstream',
23063
+ upstream: 'upstream',
23064
+ peer: 'peer',
23065
+ local: 'local',
23066
+ };
23067
+ return map[normalized] ?? null;
23068
+ }
23008
23069
  }
23009
23070
 
23010
23071
  var basicAuthorizationPolicy = /*#__PURE__*/Object.freeze({
@@ -42753,16 +42814,22 @@ class LocalFileAuthorizationPolicySource {
42753
42814
  const factoryConfig = this.policyFactoryConfig ?? policyDefinition;
42754
42815
  // Ensure we have a type field for the factory
42755
42816
  if (!('type' in factoryConfig) || typeof factoryConfig.type !== 'string') {
42756
- throw new Error(`Policy definition at ${this.path} must have a 'type' field, ` +
42757
- `or policyFactory config must be provided`);
42817
+ logger$1.warning('policy_type_missing_defaulting_to_basic', {
42818
+ path: this.path,
42819
+ });
42820
+ factoryConfig.type =
42821
+ 'BasicAuthorizationPolicy';
42758
42822
  }
42759
42823
  // Build the factory config with the policy definition
42760
42824
  // The file content IS the policy definition, so we extract the type
42761
42825
  // and wrap the remaining content as the policyDefinition
42762
- const { type, ...restOfFile } = policyDefinition;
42826
+ const { type: fileType, ...restOfFile } = policyDefinition;
42827
+ const resolvedType = typeof fileType === 'string' && fileType.trim().length > 0
42828
+ ? fileType
42829
+ : factoryConfig.type;
42763
42830
  const mergedConfig = this.policyFactoryConfig != null
42764
42831
  ? { ...this.policyFactoryConfig, policyDefinition }
42765
- : { type: factoryConfig.type, policyDefinition: restOfFile };
42832
+ : { type: resolvedType, policyDefinition: restOfFile };
42766
42833
  // Create the policy using the factory system
42767
42834
  const policy = await AuthorizationPolicyFactory.createAuthorizationPolicy(mergedConfig);
42768
42835
  if (!policy) {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
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;
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_AUTH_POLICY_FORMAT = exports.ENV_VAR_AUTH_POLICY_PATH = 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_POLICY_LOCALFILE = exports.PROFILE_NAME_OAUTH2_CALLBACK = exports.PROFILE_NAME_OAUTH2_GATED = exports.PROFILE_NAME_OAUTH2 = exports.PROFILE_NAME_DEFAULT = void 0;
4
4
  const factory_1 = require("@naylence/factory");
5
5
  const logging_js_1 = require("../../util/logging.js");
6
6
  const authorizer_factory_js_1 = require("./authorizer-factory.js");
@@ -9,6 +9,7 @@ exports.PROFILE_NAME_DEFAULT = 'jwt';
9
9
  exports.PROFILE_NAME_OAUTH2 = 'oauth2';
10
10
  exports.PROFILE_NAME_OAUTH2_GATED = 'oauth2-gated';
11
11
  exports.PROFILE_NAME_OAUTH2_CALLBACK = 'oauth2-callback';
12
+ exports.PROFILE_NAME_POLICY_LOCALFILE = 'policy-localfile';
12
13
  exports.PROFILE_NAME_NOOP = 'noop';
13
14
  exports.ENV_VAR_JWT_TRUSTED_ISSUER = 'FAME_JWT_TRUSTED_ISSUER';
14
15
  exports.ENV_VAR_JWT_ALGORITHM = 'FAME_JWT_ALGORITHM';
@@ -16,18 +17,21 @@ exports.ENV_VAR_JWT_AUDIENCE = 'FAME_JWT_AUDIENCE';
16
17
  exports.ENV_VAR_JWKS_URL = 'FAME_JWKS_URL';
17
18
  exports.ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY = 'FAME_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY';
18
19
  exports.ENV_VAR_TRUSTED_CLIENT_SCOPE = 'FAME_TRUSTED_CLIENT_SCOPE';
20
+ exports.ENV_VAR_AUTH_POLICY_PATH = 'FAME_AUTH_POLICY_PATH';
21
+ exports.ENV_VAR_AUTH_POLICY_FORMAT = 'FAME_AUTH_POLICY_FORMAT';
19
22
  exports.ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER = 'FAME_JWT_REVERSE_AUTH_TRUSTED_ISSUER';
20
23
  exports.ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE = 'FAME_JWT_REVERSE_AUTH_AUDIENCE';
21
24
  exports.ENV_VAR_HMAC_SECRET = 'FAME_HMAC_SECRET';
22
25
  const DEFAULT_REVERSE_AUTH_ISSUER = 'reverse-auth.naylence.ai';
23
26
  const DEFAULT_REVERSE_AUTH_AUDIENCE = 'dev.naylence.ai';
27
+ const DEFAULT_VERIFIER_CONFIG = {
28
+ type: 'JWKSJWTTokenVerifier',
29
+ jwks_url: factory_1.Expressions.env(exports.ENV_VAR_JWKS_URL),
30
+ issuer: factory_1.Expressions.env(exports.ENV_VAR_JWT_TRUSTED_ISSUER),
31
+ };
24
32
  const DEFAULT_PROFILE = {
25
33
  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
- },
34
+ verifier: DEFAULT_VERIFIER_CONFIG,
31
35
  };
32
36
  const OAUTH2_PROFILE = {
33
37
  type: 'OAuth2Authorizer',
@@ -72,11 +76,22 @@ const OAUTH2_CALLBACK_PROFILE = {
72
76
  const NOOP_PROFILE = {
73
77
  type: 'NoopAuthorizer',
74
78
  };
79
+ const DEFAULT_POLICY_SOURCE = {
80
+ type: 'LocalFileAuthorizationPolicySource',
81
+ path: factory_1.Expressions.env(exports.ENV_VAR_AUTH_POLICY_PATH, './auth-policy.yaml'),
82
+ format: factory_1.Expressions.env(exports.ENV_VAR_AUTH_POLICY_FORMAT, 'auto'),
83
+ };
84
+ const POLICY_LOCALFILE_PROFILE = {
85
+ type: 'PolicyAuthorizer',
86
+ verifier: DEFAULT_VERIFIER_CONFIG,
87
+ policySource: DEFAULT_POLICY_SOURCE,
88
+ };
75
89
  const PROFILE_MAP = {
76
90
  [exports.PROFILE_NAME_DEFAULT]: DEFAULT_PROFILE,
77
91
  [exports.PROFILE_NAME_OAUTH2]: OAUTH2_PROFILE,
78
92
  [exports.PROFILE_NAME_OAUTH2_GATED]: OAUTH2_GATED_PROFILE,
79
93
  [exports.PROFILE_NAME_OAUTH2_CALLBACK]: OAUTH2_CALLBACK_PROFILE,
94
+ [exports.PROFILE_NAME_POLICY_LOCALFILE]: POLICY_LOCALFILE_PROFILE,
80
95
  [exports.PROFILE_NAME_NOOP]: NOOP_PROFILE,
81
96
  };
82
97
  const PROFILE_ALIASES = {
@@ -90,6 +105,9 @@ const PROFILE_ALIASES = {
90
105
  'oauth2-callback': exports.PROFILE_NAME_OAUTH2_CALLBACK,
91
106
  oauth2_callback: exports.PROFILE_NAME_OAUTH2_CALLBACK,
92
107
  'reverse-auth': exports.PROFILE_NAME_OAUTH2_CALLBACK,
108
+ policy: exports.PROFILE_NAME_POLICY_LOCALFILE,
109
+ 'policy-localfile': exports.PROFILE_NAME_POLICY_LOCALFILE,
110
+ policy_localfile: exports.PROFILE_NAME_POLICY_LOCALFILE,
93
111
  noop: exports.PROFILE_NAME_NOOP,
94
112
  'no-op': exports.PROFILE_NAME_NOOP,
95
113
  no_op: exports.PROFILE_NAME_NOOP,