@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.
Files changed (88) hide show
  1. package/dist/browser/index.cjs +3368 -1393
  2. package/dist/browser/index.mjs +3324 -1387
  3. package/dist/cjs/naylence/fame/factory-manifest.js +8 -0
  4. package/dist/cjs/naylence/fame/node/node-event-listener.js +4 -0
  5. package/dist/cjs/naylence/fame/security/auth/authorization-profile-factory.js +165 -0
  6. package/dist/cjs/naylence/fame/security/auth/default-policy-authorizer-factory.js +147 -0
  7. package/dist/cjs/naylence/fame/security/auth/default-policy-authorizer.js +291 -0
  8. package/dist/cjs/naylence/fame/security/auth/oauth2-authorizer-factory.js +7 -0
  9. package/dist/cjs/naylence/fame/security/auth/oauth2-authorizer.js +19 -4
  10. package/dist/cjs/naylence/fame/security/auth/policy/authorization-policy-definition.js +60 -0
  11. package/dist/cjs/naylence/fame/security/auth/policy/authorization-policy-factory.js +35 -0
  12. package/dist/cjs/naylence/fame/security/auth/policy/authorization-policy-source-factory.js +35 -0
  13. package/dist/cjs/naylence/fame/security/auth/policy/authorization-policy-source.js +2 -0
  14. package/dist/cjs/naylence/fame/security/auth/policy/authorization-policy.js +2 -0
  15. package/dist/cjs/naylence/fame/security/auth/policy/basic-authorization-policy-factory.js +99 -0
  16. package/dist/cjs/naylence/fame/security/auth/policy/basic-authorization-policy.js +449 -0
  17. package/dist/cjs/naylence/fame/security/auth/policy/index.js +40 -0
  18. package/dist/cjs/naylence/fame/security/auth/policy/local-file-authorization-policy-source-factory.js +101 -0
  19. package/dist/cjs/naylence/fame/security/auth/policy/local-file-authorization-policy-source.js +164 -0
  20. package/dist/cjs/naylence/fame/security/auth/policy/pattern-matcher.js +195 -0
  21. package/dist/cjs/naylence/fame/security/auth/policy/scope-matcher.js +169 -0
  22. package/dist/cjs/naylence/fame/security/auth/policy-authorizer.js +2 -0
  23. package/dist/cjs/naylence/fame/security/default-security-manager.js +94 -0
  24. package/dist/cjs/naylence/fame/security/index.js +22 -1
  25. package/dist/cjs/naylence/fame/security/node-security-profile-factory.js +15 -73
  26. package/dist/cjs/naylence/fame/sentinel/router.js +67 -1
  27. package/dist/cjs/naylence/fame/sentinel/sentinel.js +46 -2
  28. package/dist/cjs/naylence/fame/util/register-runtime-factories.js +2 -0
  29. package/dist/cjs/version.js +2 -2
  30. package/dist/esm/naylence/fame/factory-manifest.js +8 -0
  31. package/dist/esm/naylence/fame/node/node-event-listener.js +4 -0
  32. package/dist/esm/naylence/fame/security/auth/authorization-profile-factory.js +161 -0
  33. package/dist/esm/naylence/fame/security/auth/default-policy-authorizer-factory.js +110 -0
  34. package/dist/esm/naylence/fame/security/auth/default-policy-authorizer.js +287 -0
  35. package/dist/esm/naylence/fame/security/auth/oauth2-authorizer-factory.js +7 -0
  36. package/dist/esm/naylence/fame/security/auth/oauth2-authorizer.js +19 -4
  37. package/dist/esm/naylence/fame/security/auth/policy/authorization-policy-definition.js +57 -0
  38. package/dist/esm/naylence/fame/security/auth/policy/authorization-policy-factory.js +31 -0
  39. package/dist/esm/naylence/fame/security/auth/policy/authorization-policy-source-factory.js +31 -0
  40. package/dist/esm/naylence/fame/security/auth/policy/authorization-policy-source.js +1 -0
  41. package/dist/esm/naylence/fame/security/auth/policy/authorization-policy.js +1 -0
  42. package/dist/esm/naylence/fame/security/auth/policy/basic-authorization-policy-factory.js +62 -0
  43. package/dist/esm/naylence/fame/security/auth/policy/basic-authorization-policy.js +445 -0
  44. package/dist/esm/naylence/fame/security/auth/policy/index.js +20 -0
  45. package/dist/esm/naylence/fame/security/auth/policy/local-file-authorization-policy-source-factory.js +64 -0
  46. package/dist/esm/naylence/fame/security/auth/policy/local-file-authorization-policy-source.js +127 -0
  47. package/dist/esm/naylence/fame/security/auth/policy/pattern-matcher.js +185 -0
  48. package/dist/esm/naylence/fame/security/auth/policy/scope-matcher.js +162 -0
  49. package/dist/esm/naylence/fame/security/auth/policy-authorizer.js +1 -0
  50. package/dist/esm/naylence/fame/security/default-security-manager.js +94 -0
  51. package/dist/esm/naylence/fame/security/index.js +5 -1
  52. package/dist/esm/naylence/fame/security/node-security-profile-factory.js +14 -72
  53. package/dist/esm/naylence/fame/sentinel/router.js +64 -0
  54. package/dist/esm/naylence/fame/sentinel/sentinel.js +47 -3
  55. package/dist/esm/naylence/fame/util/register-runtime-factories.js +2 -0
  56. package/dist/esm/version.js +2 -2
  57. package/dist/node/index.cjs +3364 -1389
  58. package/dist/node/index.mjs +3324 -1387
  59. package/dist/node/node.cjs +3416 -1425
  60. package/dist/node/node.mjs +3376 -1423
  61. package/dist/types/naylence/fame/factory-manifest.d.ts +1 -1
  62. package/dist/types/naylence/fame/node/node-event-listener.d.ts +31 -0
  63. package/dist/types/naylence/fame/security/auth/authorization-profile-factory.d.ts +29 -0
  64. package/dist/types/naylence/fame/security/auth/authorizer.d.ts +37 -0
  65. package/dist/types/naylence/fame/security/auth/default-policy-authorizer-factory.d.ts +55 -0
  66. package/dist/types/naylence/fame/security/auth/default-policy-authorizer.d.ts +99 -0
  67. package/dist/types/naylence/fame/security/auth/oauth2-authorizer-factory.d.ts +2 -0
  68. package/dist/types/naylence/fame/security/auth/oauth2-authorizer.d.ts +2 -0
  69. package/dist/types/naylence/fame/security/auth/policy/authorization-policy-definition.d.ts +166 -0
  70. package/dist/types/naylence/fame/security/auth/policy/authorization-policy-factory.d.ts +38 -0
  71. package/dist/types/naylence/fame/security/auth/policy/authorization-policy-source-factory.d.ts +38 -0
  72. package/dist/types/naylence/fame/security/auth/policy/authorization-policy-source.d.ts +20 -0
  73. package/dist/types/naylence/fame/security/auth/policy/authorization-policy.d.ts +55 -0
  74. package/dist/types/naylence/fame/security/auth/policy/basic-authorization-policy-factory.d.ts +42 -0
  75. package/dist/types/naylence/fame/security/auth/policy/basic-authorization-policy.d.ts +78 -0
  76. package/dist/types/naylence/fame/security/auth/policy/index.d.ts +19 -0
  77. package/dist/types/naylence/fame/security/auth/policy/local-file-authorization-policy-source-factory.d.ts +51 -0
  78. package/dist/types/naylence/fame/security/auth/policy/local-file-authorization-policy-source.d.ts +67 -0
  79. package/dist/types/naylence/fame/security/auth/policy/pattern-matcher.d.ts +84 -0
  80. package/dist/types/naylence/fame/security/auth/policy/scope-matcher.d.ts +61 -0
  81. package/dist/types/naylence/fame/security/auth/policy-authorizer.d.ts +12 -0
  82. package/dist/types/naylence/fame/security/default-security-manager.d.ts +22 -0
  83. package/dist/types/naylence/fame/security/index.d.ts +5 -1
  84. package/dist/types/naylence/fame/security/node-security-profile-factory.d.ts +2 -0
  85. package/dist/types/naylence/fame/sentinel/router.d.ts +68 -0
  86. package/dist/types/naylence/fame/sentinel/sentinel.d.ts +16 -0
  87. package/dist/types/version.d.ts +1 -1
  88. package/package.json +1 -1
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Factory for creating BasicAuthorizationPolicy instances.
3
+ */
4
+ import type { AuthorizationPolicyDefinition } from './authorization-policy-definition.js';
5
+ import type { AuthorizationPolicy } from './authorization-policy.js';
6
+ import { AuthorizationPolicyFactory, type AuthorizationPolicyConfig } from './authorization-policy-factory.js';
7
+ /**
8
+ * Configuration for creating a BasicAuthorizationPolicy via factory.
9
+ */
10
+ export interface BasicAuthorizationPolicyConfig extends AuthorizationPolicyConfig {
11
+ type: 'BasicAuthorizationPolicy';
12
+ /**
13
+ * The policy definition to evaluate.
14
+ */
15
+ policyDefinition: AuthorizationPolicyDefinition;
16
+ /**
17
+ * Whether to log warnings for unknown fields.
18
+ * @default true
19
+ */
20
+ warnOnUnknownFields?: boolean;
21
+ }
22
+ /**
23
+ * Factory metadata for registration.
24
+ */
25
+ export declare const FACTORY_META: {
26
+ readonly base: "AuthorizationPolicyFactory";
27
+ readonly key: "BasicAuthorizationPolicy";
28
+ };
29
+ /**
30
+ * Factory for creating BasicAuthorizationPolicy instances.
31
+ */
32
+ export declare class BasicAuthorizationPolicyFactory extends AuthorizationPolicyFactory<BasicAuthorizationPolicyConfig> {
33
+ readonly type = "BasicAuthorizationPolicy";
34
+ /**
35
+ * Creates a BasicAuthorizationPolicy from the given configuration.
36
+ *
37
+ * @param config - Configuration with policyDefinition
38
+ * @returns The created authorization policy
39
+ */
40
+ create(config?: BasicAuthorizationPolicyConfig | Record<string, unknown> | null): Promise<AuthorizationPolicy>;
41
+ }
42
+ export default BasicAuthorizationPolicyFactory;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Basic authorization policy implementation.
3
+ *
4
+ * Evaluates authorization rules defined in YAML/JSON policy files.
5
+ * Uses first-match-wins semantics with glob/regex pattern matching.
6
+ */
7
+ import type { FameDeliveryContext, FameEnvelope } from '@naylence/core';
8
+ import type { NodeLike } from '../../../node/node-like.js';
9
+ import type { AuthorizationPolicy, AuthorizationDecision } from './authorization-policy.js';
10
+ import type { AuthorizationPolicyDefinition, RuleAction } from './authorization-policy-definition.js';
11
+ /**
12
+ * Options for creating a BasicAuthorizationPolicy.
13
+ */
14
+ export interface BasicAuthorizationPolicyOptions {
15
+ /**
16
+ * The policy definition to evaluate.
17
+ */
18
+ policyDefinition: AuthorizationPolicyDefinition;
19
+ /**
20
+ * Whether to log warnings for unknown fields.
21
+ * @default true
22
+ */
23
+ warnOnUnknownFields?: boolean;
24
+ }
25
+ /**
26
+ * Basic authorization policy that evaluates rules from a policy definition.
27
+ *
28
+ * Features:
29
+ * - First-match-wins rule evaluation
30
+ * - Glob and regex pattern matching for addresses
31
+ * - Scope matching with any_of/all_of/none_of operators
32
+ * - Action-based filtering (connect, send, receive)
33
+ */
34
+ export declare class BasicAuthorizationPolicy implements AuthorizationPolicy {
35
+ private readonly defaultEffect;
36
+ private readonly compiledRules;
37
+ constructor(options: BasicAuthorizationPolicyOptions);
38
+ /**
39
+ * Evaluates the policy against a request with an explicitly provided action.
40
+ *
41
+ * @param _node - The node handling the request (unused in basic policy)
42
+ * @param envelope - The FAME envelope being authorized
43
+ * @param context - Optional delivery context with authorization info
44
+ * @param action - The authorization action token (required, no inference)
45
+ * @returns Authorization decision indicating allow/deny
46
+ */
47
+ evaluateRequest(_node: NodeLike, envelope: FameEnvelope, context?: FameDeliveryContext, action?: RuleAction): Promise<AuthorizationDecision>;
48
+ private validateDefaultEffect;
49
+ private warnUnknownPolicyFields;
50
+ private compileRules;
51
+ private compileRule;
52
+ /**
53
+ * Compiles action field into a Set of valid actions.
54
+ * Supports single RuleAction or array of RuleAction (implicit any-of).
55
+ */
56
+ private compileActions;
57
+ /**
58
+ * Compiles address field into an array of glob matchers.
59
+ * Supports single string or array of strings (implicit any-of).
60
+ * Returns undefined if not specified (no address gating).
61
+ *
62
+ * All patterns are treated as globs - `^` prefix is rejected as an error.
63
+ */
64
+ private compileAddress;
65
+ /**
66
+ * Compiles frame_type field into a Set of normalized frame types.
67
+ * Supports single string or array of strings (implicit any-of).
68
+ * Returns undefined if not specified (no frame type gating).
69
+ */
70
+ private compileFrameTypes;
71
+ /**
72
+ * Compiles origin_type field into a Set of normalized origin types.
73
+ * Supports single string or array of strings (implicit any-of).
74
+ * Returns undefined if not specified (no origin type gating).
75
+ * Valid values: 'downstream', 'upstream', 'peer', 'local' (case-insensitive).
76
+ */
77
+ private compileOriginTypes;
78
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Authorization policy module exports.
3
+ *
4
+ * This module provides interfaces and factories for pluggable authorization policies.
5
+ */
6
+ export * from './authorization-policy.js';
7
+ export * from './authorization-policy-source.js';
8
+ export * from './authorization-policy-definition.js';
9
+ export { compilePattern, compileGlobPattern, getCompiledGlobPattern, matchPattern, isRegexPattern, assertNotRegexPattern, } from './pattern-matcher.js';
10
+ export type { CompiledPattern } from './pattern-matcher.js';
11
+ export { evaluateScopeRequirement, compileScopeRequirement, normalizeScopeRequirement, compileGlobOnlyScopeRequirement, } from './scope-matcher.js';
12
+ export { AUTHORIZATION_POLICY_FACTORY_BASE_TYPE, AuthorizationPolicyFactory, } from './authorization-policy-factory.js';
13
+ export type * from './authorization-policy-factory.js';
14
+ export { AUTHORIZATION_POLICY_SOURCE_FACTORY_BASE_TYPE, AuthorizationPolicySourceFactory, } from './authorization-policy-source-factory.js';
15
+ export type * from './authorization-policy-source-factory.js';
16
+ export { BasicAuthorizationPolicy } from './basic-authorization-policy.js';
17
+ export type { BasicAuthorizationPolicyOptions } from './basic-authorization-policy.js';
18
+ export { BasicAuthorizationPolicyFactory } from './basic-authorization-policy-factory.js';
19
+ export type { BasicAuthorizationPolicyConfig } from './basic-authorization-policy-factory.js';
@@ -0,0 +1,51 @@
1
+ import type { AuthorizationPolicySource } from './authorization-policy-source.js';
2
+ import { AuthorizationPolicySourceFactory, type AuthorizationPolicySourceConfig } from './authorization-policy-source-factory.js';
3
+ import type { AuthorizationPolicyConfig } from './authorization-policy-factory.js';
4
+ /**
5
+ * Configuration for LocalFileAuthorizationPolicySource.
6
+ */
7
+ export interface LocalFileAuthorizationPolicySourceConfig extends AuthorizationPolicySourceConfig {
8
+ type: 'LocalFileAuthorizationPolicySource';
9
+ /**
10
+ * Path to the policy file (YAML or JSON).
11
+ */
12
+ path: string;
13
+ /**
14
+ * Format of the policy file.
15
+ * If not specified, auto-detects from file extension.
16
+ * @default 'auto'
17
+ */
18
+ format?: 'yaml' | 'json' | 'auto';
19
+ /**
20
+ * Configuration for the policy factory to use when parsing the loaded file.
21
+ * Determines which AuthorizationPolicy implementation is created.
22
+ *
23
+ * If not specified, the policy definition from the file is used directly
24
+ * as the factory configuration (must include a 'type' field).
25
+ */
26
+ policyFactory?: AuthorizationPolicyConfig | Record<string, unknown>;
27
+ }
28
+ /**
29
+ * Factory metadata for registration.
30
+ */
31
+ export declare const FACTORY_META: {
32
+ readonly base: "AuthorizationPolicySourceFactory";
33
+ readonly key: "LocalFileAuthorizationPolicySource";
34
+ };
35
+ /**
36
+ * Factory for creating LocalFileAuthorizationPolicySource instances.
37
+ *
38
+ * This factory uses lazy loading to avoid pulling in Node.js-specific
39
+ * code (filesystem operations) in browser environments.
40
+ */
41
+ export declare class LocalFileAuthorizationPolicySourceFactory extends AuthorizationPolicySourceFactory<LocalFileAuthorizationPolicySourceConfig> {
42
+ readonly type = "LocalFileAuthorizationPolicySource";
43
+ /**
44
+ * Creates a LocalFileAuthorizationPolicySource from the given configuration.
45
+ *
46
+ * @param config - Configuration specifying the policy file path and options
47
+ * @returns The created policy source
48
+ */
49
+ create(config?: LocalFileAuthorizationPolicySourceConfig | Record<string, unknown> | null): Promise<AuthorizationPolicySource>;
50
+ }
51
+ export default LocalFileAuthorizationPolicySourceFactory;
@@ -0,0 +1,67 @@
1
+ import type { AuthorizationPolicy } from './authorization-policy.js';
2
+ import { type AuthorizationPolicyConfig } from './authorization-policy-factory.js';
3
+ import type { AuthorizationPolicySource } from './authorization-policy-source.js';
4
+ /**
5
+ * Format of the policy file.
6
+ */
7
+ export type PolicyFileFormat = 'yaml' | 'json' | 'auto';
8
+ /**
9
+ * Configuration options for LocalFileAuthorizationPolicySource.
10
+ */
11
+ export interface LocalFileAuthorizationPolicySourceOptions {
12
+ /**
13
+ * Path to the policy file.
14
+ */
15
+ path: string;
16
+ /**
17
+ * Format of the policy file.
18
+ * If 'auto', the format is detected from the file extension.
19
+ * @default 'auto'
20
+ */
21
+ format?: PolicyFileFormat;
22
+ /**
23
+ * Configuration for the policy factory to use when parsing the loaded file.
24
+ * Determines which AuthorizationPolicy implementation is created from the
25
+ * loaded policy definition.
26
+ *
27
+ * If not specified, the policy definition from the file is used directly
28
+ * as the factory configuration (must include a 'type' field).
29
+ */
30
+ policyFactory?: AuthorizationPolicyConfig | Record<string, unknown>;
31
+ }
32
+ /**
33
+ * An authorization policy source that loads policy definitions from a local file.
34
+ *
35
+ * Supports YAML and JSON formats. The file must contain a valid policy
36
+ * configuration object that can be used to create an AuthorizationPolicy
37
+ * via the factory system.
38
+ *
39
+ * This is a Node.js-only implementation that uses the filesystem.
40
+ */
41
+ export declare class LocalFileAuthorizationPolicySource implements AuthorizationPolicySource {
42
+ private readonly path;
43
+ private readonly format;
44
+ private readonly policyFactoryConfig;
45
+ private cachedPolicy;
46
+ constructor(options: LocalFileAuthorizationPolicySourceOptions);
47
+ /**
48
+ * Loads the authorization policy from the configured file.
49
+ *
50
+ * The file is read and parsed according to the configured format.
51
+ * The parsed content is then used to create an AuthorizationPolicy
52
+ * via the factory system.
53
+ *
54
+ * @returns The loaded authorization policy
55
+ */
56
+ loadPolicy(): Promise<AuthorizationPolicy>;
57
+ /**
58
+ * Clears the cached policy, forcing a reload on the next loadPolicy() call.
59
+ */
60
+ clearCache(): void;
61
+ /**
62
+ * Reloads the policy from the file, clearing any cached version.
63
+ *
64
+ * @returns The reloaded authorization policy
65
+ */
66
+ reloadPolicy(): Promise<AuthorizationPolicy>;
67
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Pattern matching utilities for authorization policies.
3
+ *
4
+ * Supports:
5
+ * - Glob patterns: `*` (single segment), `**` (any depth), `?` (single char)
6
+ * - Regex patterns: patterns starting with `^` (for advanced/BSL use only)
7
+ *
8
+ * The OSS/basic policy uses glob-only matching via `compileGlobPattern()`.
9
+ * The advanced/BSL policy may use `compilePattern()` which interprets `^` as regex.
10
+ */
11
+ /**
12
+ * Compiled pattern for efficient repeated matching.
13
+ */
14
+ export interface CompiledPattern {
15
+ readonly source: string;
16
+ readonly isRegex: boolean;
17
+ match(value: string): boolean;
18
+ }
19
+ /**
20
+ * Checks if a pattern string is a regex pattern.
21
+ * Regex patterns start with `^`.
22
+ */
23
+ export declare function isRegexPattern(pattern: string): boolean;
24
+ /**
25
+ * Asserts that a pattern is not a regex pattern.
26
+ * Throws an error if the pattern starts with `^`.
27
+ *
28
+ * Use this in OSS/basic policy to reject regex patterns.
29
+ *
30
+ * @param pattern - The pattern to check
31
+ * @param context - Optional context for the error message (e.g., "address", "scope")
32
+ * @throws Error if the pattern is a regex pattern
33
+ */
34
+ export declare function assertNotRegexPattern(pattern: string, context?: string): void;
35
+ /**
36
+ * Compiles a pattern string into an efficient matcher.
37
+ *
38
+ * @param pattern - Glob pattern or regex (starting with `^`)
39
+ * @returns A compiled pattern object
40
+ * @throws Error if the regex pattern is invalid
41
+ */
42
+ export declare function compilePattern(pattern: string): CompiledPattern;
43
+ /**
44
+ * Compiles a pattern string as a glob pattern only (no regex interpretation).
45
+ *
46
+ * This is the preferred method for OSS/basic policy evaluation.
47
+ * Patterns starting with `^` are rejected with an error.
48
+ *
49
+ * @param pattern - Glob pattern (regex patterns rejected)
50
+ * @param context - Optional context for error messages
51
+ * @returns A compiled pattern object
52
+ * @throws Error if pattern starts with `^` (regex attempt)
53
+ */
54
+ export declare function compileGlobPattern(pattern: string, context?: string): CompiledPattern;
55
+ /**
56
+ * Gets or compiles a pattern, with caching.
57
+ *
58
+ * @param pattern - Glob pattern or regex
59
+ * @returns A compiled pattern object
60
+ */
61
+ export declare function getCompiledPattern(pattern: string): CompiledPattern;
62
+ /**
63
+ * Gets or compiles a glob-only pattern, with caching.
64
+ *
65
+ * This is the preferred method for OSS/basic policy evaluation.
66
+ * Patterns are always treated as globs, never regex.
67
+ *
68
+ * @param pattern - Glob pattern (never interpreted as regex)
69
+ * @returns A compiled pattern object
70
+ */
71
+ export declare function getCompiledGlobPattern(pattern: string): CompiledPattern;
72
+ /**
73
+ * Matches a value against a pattern string.
74
+ *
75
+ * @param pattern - Glob pattern or regex (starting with `^`)
76
+ * @param value - The value to match
77
+ * @returns True if the value matches the pattern
78
+ */
79
+ export declare function matchPattern(pattern: string, value: string): boolean;
80
+ /**
81
+ * Clears the pattern cache.
82
+ * Useful for testing or when memory is a concern.
83
+ */
84
+ export declare function clearPatternCache(): void;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Scope matching utilities for authorization policies.
3
+ *
4
+ * Supports:
5
+ * - Simple string patterns (glob only in OSS/basic policy)
6
+ * - Logical operators: any_of, all_of, none_of
7
+ * - Recursive nesting with depth limits
8
+ */
9
+ import type { ScopeRequirement, NormalizedScopeRequirement } from './authorization-policy-definition.js';
10
+ /**
11
+ * Normalizes a scope requirement into a typed structure.
12
+ *
13
+ * @param requirement - The scope requirement to normalize
14
+ * @param depth - Current nesting depth (for recursion limit)
15
+ * @returns Normalized scope requirement
16
+ * @throws Error if nesting exceeds maximum depth
17
+ */
18
+ export declare function normalizeScopeRequirement(requirement: ScopeRequirement, depth?: number): NormalizedScopeRequirement;
19
+ /**
20
+ * Evaluates a normalized scope requirement against granted scopes.
21
+ *
22
+ * @param requirement - The normalized scope requirement
23
+ * @param grantedScopes - The scopes granted to the principal
24
+ * @returns True if the requirement is satisfied
25
+ */
26
+ export declare function evaluateNormalizedScopeRequirement(requirement: NormalizedScopeRequirement, grantedScopes: readonly string[]): boolean;
27
+ /**
28
+ * Evaluates a scope requirement against granted scopes.
29
+ *
30
+ * This is the main entry point for scope matching.
31
+ *
32
+ * @param requirement - The scope requirement (string or object)
33
+ * @param grantedScopes - The scopes granted to the principal
34
+ * @returns True if the requirement is satisfied
35
+ */
36
+ export declare function evaluateScopeRequirement(requirement: ScopeRequirement, grantedScopes: readonly string[]): boolean;
37
+ /**
38
+ * Pre-compiles a scope requirement for efficient repeated evaluation.
39
+ *
40
+ * @param requirement - The scope requirement to compile
41
+ * @returns A function that evaluates the requirement against granted scopes
42
+ */
43
+ export declare function compileScopeRequirement(requirement: ScopeRequirement): (grantedScopes: readonly string[]) => boolean;
44
+ /**
45
+ * Compiled scope requirement for efficient repeated evaluation with glob-only patterns.
46
+ */
47
+ interface CompiledScopeRequirement {
48
+ evaluate: (grantedScopes: readonly string[]) => boolean;
49
+ }
50
+ /**
51
+ * Pre-compiles a scope requirement for OSS/basic policy (glob-only, no regex).
52
+ *
53
+ * This version rejects patterns starting with `^` at compile time.
54
+ *
55
+ * @param requirement - The scope requirement to compile
56
+ * @param ruleId - Rule ID for error messages
57
+ * @returns A compiled scope requirement
58
+ * @throws Error if any pattern starts with `^` (regex attempt)
59
+ */
60
+ export declare function compileGlobOnlyScopeRequirement(requirement: ScopeRequirement, ruleId: string): CompiledScopeRequirement;
61
+ export {};
@@ -0,0 +1,12 @@
1
+ import type { Authorizer } from './authorizer.js';
2
+ import type { AuthorizationPolicy } from './policy/authorization-policy.js';
3
+ /**
4
+ * An authorizer that delegates authorization decisions to a pluggable policy.
5
+ *
6
+ * This interface extends the base `Authorizer` interface and adds access
7
+ * to the underlying `AuthorizationPolicy` for inspection or debugging.
8
+ */
9
+ export interface PolicyAuthorizer extends Authorizer {
10
+ /** The currently active authorization policy */
11
+ readonly policy: AuthorizationPolicy;
12
+ }
@@ -14,6 +14,7 @@ import type { AttachInfo } from '../node/admission/node-attach-client.js';
14
14
  import type { NodeLike } from '../node/node-like.js';
15
15
  import { EnvelopeSecurityHandler } from '../node/envelope-security-handler.js';
16
16
  import { SecureChannelFrameHandler } from '../node/secure-channel-frame-handler.js';
17
+ import { type RouterState, type RoutingAction } from '../sentinel/router.js';
17
18
  export declare class DefaultSecurityManager implements SecurityManager {
18
19
  readonly priority = 2000;
19
20
  private _policy;
@@ -58,6 +59,27 @@ export declare class DefaultSecurityManager implements SecurityManager {
58
59
  onDeliverLocal(node: NodeLike, address: FameAddress, envelope: FameEnvelope, context?: FameDeliveryContext): Promise<FameEnvelope | null>;
59
60
  onDeliver(_node: NodeLike, envelope: FameEnvelope, context?: FameDeliveryContext): Promise<FameEnvelope | null>;
60
61
  onForwardUpstream(_node: NodeLike, envelope: FameEnvelope, context?: FameDeliveryContext): Promise<FameEnvelope | null>;
62
+ /**
63
+ * Route authorization hook - invoked after routing policy selects an action.
64
+ *
65
+ * This method provides centralized route authorization by:
66
+ * 1. Mapping the RoutingAction to an authorization action token
67
+ * 2. Calling authorizer.authorizeRoute() if available
68
+ * 3. Returning a Deny action on authorization failure (opaque on wire)
69
+ *
70
+ * @param node - The node performing the routing
71
+ * @param envelope - The envelope being routed
72
+ * @param selected - The RoutingAction selected by routing policy
73
+ * @param state - The current router state
74
+ * @param context - Optional delivery context
75
+ * @returns The action to execute (selected if authorized, Deny if denied)
76
+ */
77
+ onRoutingActionSelected(node: NodeLike, envelope: FameEnvelope, selected: RoutingAction, _state: RouterState, context?: FameDeliveryContext | null): Promise<RoutingAction | null | undefined>;
78
+ /**
79
+ * Gets the NACK disclosure mode from configuration.
80
+ * Default is 'opaque' to avoid leaking route existence.
81
+ */
82
+ private getNackDisclosureMode;
61
83
  onForwardToRoute(node: NodeLike, nextSegment: string, envelope: FameEnvelope, context?: FameDeliveryContext): Promise<FameEnvelope | null>;
62
84
  onForwardToPeer(node: NodeLike, peerSegment: string, envelope: FameEnvelope, context?: FameDeliveryContext): Promise<FameEnvelope | null>;
63
85
  onForwardToPeers(node: NodeLike, envelope: FameEnvelope, peers?: unknown, excludePeers?: unknown, context?: FameDeliveryContext): Promise<FameEnvelope | null>;
@@ -1,8 +1,12 @@
1
1
  export * from './auth/authorizer.js';
2
2
  export * from './auth/auth-identity.js';
3
+ export * from './auth/policy-authorizer.js';
3
4
  export { AUTHORIZER_FACTORY_BASE_TYPE, AuthorizerFactory, } from './auth/authorizer-factory.js';
4
5
  export type * from './auth/authorizer-factory.js';
6
+ 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';
7
+ export type { AuthorizationProfileConfig } from './auth/authorization-profile-factory.js';
5
8
  export * from './auth/auth-injection-strategy.js';
9
+ export * from './auth/policy/index.js';
6
10
  export { AUTH_INJECTION_STRATEGY_FACTORY_BASE_TYPE, AuthInjectionStrategyFactory, } from './auth/auth-injection-strategy-factory.js';
7
11
  export type * from './auth/auth-injection-strategy-factory.js';
8
12
  export * from './auth/token-issuer.js';
@@ -76,4 +80,4 @@ export * from './credential/browser-auto-key-credential-provider.js';
76
80
  export * from './credential/browser-wrapped-key-credential-provider.js';
77
81
  export * from './credential/session-key-credential-provider.js';
78
82
  export * from './credential/dev-fixed-key-credential-provider.js';
79
- 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';
83
+ 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';
@@ -11,6 +11,8 @@ export declare const ENV_VAR_HMAC_SECRET = "FAME_HMAC_SECRET";
11
11
  export declare const ENV_VAR_JWT_REVERSE_AUTH_TRUSTED_ISSUER = "FAME_JWT_REVERSE_AUTH_TRUSTED_ISSUER";
12
12
  export declare const ENV_VAR_JWT_REVERSE_AUTH_AUDIENCE = "FAME_JWT_REVERSE_AUTH_AUDIENCE";
13
13
  export declare const ENV_VAR_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY = "FAME_ENFORCE_TOKEN_SUBJECT_NODE_IDENTITY";
14
+ export declare const ENV_VAR_TRUSTED_CLIENT_SCOPE = "FAME_TRUSTED_CLIENT_SCOPE";
15
+ export declare const ENV_VAR_AUTHORIZATION_PROFILE = "FAME_AUTHORIZATION_PROFILE";
14
16
  export declare const PROFILE_NAME_STRICT_OVERLAY = "strict-overlay";
15
17
  export declare const PROFILE_NAME_OVERLAY = "overlay";
16
18
  export declare const PROFILE_NAME_OVERLAY_CALLBACK = "overlay-callback";
@@ -55,6 +55,74 @@ export declare class ForwardPeer implements RoutingAction {
55
55
  constructor(segment: string);
56
56
  execute(envelope: FameEnvelope, router: RoutingNodeLike, state: RouterState, context?: FameDeliveryContext | null): Promise<void>;
57
57
  }
58
+ /**
59
+ * Nack disclosure mode for authorization denials.
60
+ * - 'opaque': Emit generic NO_ROUTE (default, does not leak route existence)
61
+ * - 'verbose': Emit UNAUTHORIZED_ROUTE (only if safe to disclose)
62
+ */
63
+ export type NackDisclosureMode = 'opaque' | 'verbose';
64
+ /**
65
+ * Options for creating a Deny action.
66
+ */
67
+ export interface DenyOptions {
68
+ /**
69
+ * Internal reason for denial (logged but not sent on wire).
70
+ */
71
+ internalReason: string;
72
+ /**
73
+ * The action token that was denied.
74
+ */
75
+ deniedAction?: string;
76
+ /**
77
+ * Matched rule ID (for logging/audit).
78
+ */
79
+ matchedRule?: string;
80
+ /**
81
+ * Additional context for internal logging.
82
+ */
83
+ context?: Record<string, unknown>;
84
+ /**
85
+ * Nack disclosure mode.
86
+ * @default 'opaque'
87
+ */
88
+ disclosure?: NackDisclosureMode;
89
+ }
90
+ /**
91
+ * RoutingAction that denies an envelope due to authorization failure.
92
+ *
93
+ * Emits an opaque NO_ROUTE NACK on wire (by default) to avoid leaking
94
+ * route existence, while logging the true denial reason internally.
95
+ */
96
+ export declare class Deny implements RoutingAction {
97
+ private readonly options;
98
+ constructor(options: DenyOptions);
99
+ execute(envelope: FameEnvelope, router: RoutingNodeLike, state: RouterState, context?: FameDeliveryContext | null): Promise<void>;
100
+ }
101
+ /**
102
+ * Route-oriented authorization action tokens.
103
+ *
104
+ * These tokens map RoutingAction instances to policy-friendly action names:
105
+ * - ForwardUp -> 'ForwardUpstream'
106
+ * - ForwardChild -> 'ForwardDownstream'
107
+ * - ForwardPeer -> 'ForwardPeer'
108
+ * - DeliverLocal -> 'DeliverLocal'
109
+ * - Drop/Deny -> null (no authorization needed, already terminal)
110
+ */
111
+ export type AuthorizationAction = 'Connect' | 'ForwardUpstream' | 'ForwardDownstream' | 'ForwardPeer' | 'DeliverLocal';
112
+ /**
113
+ * Maps a RoutingAction instance to an authorization action token.
114
+ *
115
+ * This function uses instanceof checks to determine the action type,
116
+ * avoiding the need to expose action objects to the authorizer.
117
+ *
118
+ * For unknown/custom RoutingAction types, returns null. Callers should
119
+ * treat null as "deny by default" for security (unknown actions are not
120
+ * authorized).
121
+ *
122
+ * @param action - The RoutingAction instance to map
123
+ * @returns The authorization action token, or null for terminal/unknown actions
124
+ */
125
+ export declare function mapRoutingActionToAuthorizationAction(action: RoutingAction): AuthorizationAction | null;
58
126
  export interface RouterCapabilitiesMap {
59
127
  [capability: string]: Record<string, string>;
60
128
  }
@@ -99,6 +99,22 @@ export declare class Sentinel extends FameNode implements RoutingNodeLike {
99
99
  private onEpochChange;
100
100
  private propagateAddressBindingsUpstream;
101
101
  private bindAddressUpstream;
102
+ /**
103
+ * Dispatches the onRoutingActionSelected event to all event listeners.
104
+ *
105
+ * This allows listeners (like DefaultSecurityManager) to authorize
106
+ * routing actions and optionally replace them with Deny actions.
107
+ *
108
+ * The hook must return the RoutingAction to execute. If a listener returns
109
+ * null, undefined, or throws, the router will execute a Drop action.
110
+ *
111
+ * @param envelope - The envelope being routed
112
+ * @param selected - The RoutingAction selected by the routing policy
113
+ * @param state - The current router state
114
+ * @param context - Optional delivery context
115
+ * @returns The RoutingAction to execute (never null/undefined)
116
+ */
117
+ private dispatchRoutingActionSelected;
102
118
  static aserve(options?: SentinelServeOptions): Promise<void>;
103
119
  }
104
120
  export {};
@@ -2,4 +2,4 @@
2
2
  * The package version, injected at build time.
3
3
  * @internal
4
4
  */
5
- export declare const VERSION = "0.3.21";
5
+ export declare const VERSION = "0.4.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naylence/runtime",
3
- "version": "0.3.21",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "description": "Naylence Runtime - Complete TypeScript runtime",
6
6
  "author": "Naylence Dev <naylencedev@gmail.com>",