@vorionsys/atsf-core 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -0
- package/LICENSE +190 -0
- package/README.md +305 -181
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +86 -4
- package/dist/api/server.js.map +1 -1
- package/dist/basis/parser.d.ts +210 -210
- package/dist/basis/parser.js.map +1 -1
- package/dist/chain/index.d.ts +147 -0
- package/dist/chain/index.d.ts.map +1 -0
- package/dist/chain/index.js +219 -0
- package/dist/chain/index.js.map +1 -0
- package/dist/common/adapters.d.ts +9 -9
- package/dist/common/adapters.d.ts.map +1 -1
- package/dist/common/adapters.js +6 -6
- package/dist/common/config.d.ts +152 -152
- package/dist/common/types.d.ts +35 -15
- package/dist/common/types.d.ts.map +1 -1
- package/dist/common/types.js.map +1 -1
- package/dist/enforce/index.d.ts +226 -16
- package/dist/enforce/index.d.ts.map +1 -1
- package/dist/enforce/index.js +196 -49
- package/dist/enforce/index.js.map +1 -1
- package/dist/governance/index.d.ts +2 -0
- package/dist/governance/index.d.ts.map +1 -1
- package/dist/governance/index.js +1 -0
- package/dist/governance/index.js.map +1 -1
- package/dist/governance/proof-bridge.d.ts +86 -0
- package/dist/governance/proof-bridge.d.ts.map +1 -0
- package/dist/governance/proof-bridge.js +139 -0
- package/dist/governance/proof-bridge.js.map +1 -0
- package/dist/index.d.ts +11 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -4
- package/dist/index.js.map +1 -1
- package/dist/intent/index.d.ts +127 -10
- package/dist/intent/index.d.ts.map +1 -1
- package/dist/intent/index.js +121 -16
- package/dist/intent/index.js.map +1 -1
- package/dist/langchain/executor.d.ts +19 -5
- package/dist/langchain/executor.d.ts.map +1 -1
- package/dist/langchain/executor.js +287 -36
- package/dist/langchain/executor.js.map +1 -1
- package/dist/langchain/index.d.ts +2 -1
- package/dist/langchain/index.d.ts.map +1 -1
- package/dist/langchain/index.js +3 -1
- package/dist/langchain/index.js.map +1 -1
- package/dist/langchain/tools.d.ts.map +1 -1
- package/dist/langchain/tools.js +2 -1
- package/dist/langchain/tools.js.map +1 -1
- package/dist/langchain/types.d.ts +41 -0
- package/dist/langchain/types.d.ts.map +1 -1
- package/dist/layers/index.d.ts +1 -1
- package/dist/layers/index.d.ts.map +1 -1
- package/dist/persistence/file.d.ts +35 -3
- package/dist/persistence/file.d.ts.map +1 -1
- package/dist/persistence/file.js +138 -11
- package/dist/persistence/file.js.map +1 -1
- package/dist/persistence/index.d.ts +10 -1
- package/dist/persistence/index.d.ts.map +1 -1
- package/dist/persistence/index.js +15 -1
- package/dist/persistence/index.js.map +1 -1
- package/dist/persistence/sqlite.d.ts +135 -0
- package/dist/persistence/sqlite.d.ts.map +1 -0
- package/dist/persistence/sqlite.js +372 -0
- package/dist/persistence/sqlite.js.map +1 -0
- package/dist/phase6/ceiling.d.ts +177 -0
- package/dist/phase6/ceiling.d.ts.map +1 -0
- package/dist/phase6/ceiling.js +463 -0
- package/dist/phase6/ceiling.js.map +1 -0
- package/dist/phase6/context.d.ts +207 -0
- package/dist/phase6/context.d.ts.map +1 -0
- package/dist/phase6/context.js +603 -0
- package/dist/phase6/context.js.map +1 -0
- package/dist/phase6/index.d.ts +79 -0
- package/dist/phase6/index.d.ts.map +1 -0
- package/dist/phase6/index.js +152 -0
- package/dist/phase6/index.js.map +1 -0
- package/dist/phase6/presets.d.ts +148 -0
- package/dist/phase6/presets.d.ts.map +1 -0
- package/dist/phase6/presets.js +467 -0
- package/dist/phase6/presets.js.map +1 -0
- package/dist/phase6/provenance.d.ts +148 -0
- package/dist/phase6/provenance.d.ts.map +1 -0
- package/dist/phase6/provenance.js +545 -0
- package/dist/phase6/provenance.js.map +1 -0
- package/dist/phase6/role-gates/index.d.ts +7 -0
- package/dist/phase6/role-gates/index.d.ts.map +1 -0
- package/dist/phase6/role-gates/index.js +7 -0
- package/dist/phase6/role-gates/index.js.map +1 -0
- package/dist/phase6/role-gates/kernel.d.ts +84 -0
- package/dist/phase6/role-gates/kernel.d.ts.map +1 -0
- package/dist/phase6/role-gates/kernel.js +258 -0
- package/dist/phase6/role-gates/kernel.js.map +1 -0
- package/dist/phase6/role-gates/policy.d.ts +110 -0
- package/dist/phase6/role-gates/policy.d.ts.map +1 -0
- package/dist/phase6/role-gates/policy.js +157 -0
- package/dist/phase6/role-gates/policy.js.map +1 -0
- package/dist/phase6/role-gates.d.ts +164 -0
- package/dist/phase6/role-gates.d.ts.map +1 -0
- package/dist/phase6/role-gates.js +536 -0
- package/dist/phase6/role-gates.js.map +1 -0
- package/dist/phase6/types.d.ts +1829 -0
- package/dist/phase6/types.d.ts.map +1 -0
- package/dist/phase6/types.js +452 -0
- package/dist/phase6/types.js.map +1 -0
- package/dist/phase6/weight-presets/canonical.d.ts +93 -0
- package/dist/phase6/weight-presets/canonical.d.ts.map +1 -0
- package/dist/phase6/weight-presets/canonical.js +122 -0
- package/dist/phase6/weight-presets/canonical.js.map +1 -0
- package/dist/phase6/weight-presets/deltas.d.ts +144 -0
- package/dist/phase6/weight-presets/deltas.d.ts.map +1 -0
- package/dist/phase6/weight-presets/deltas.js +184 -0
- package/dist/phase6/weight-presets/deltas.js.map +1 -0
- package/dist/phase6/weight-presets/index.d.ts +8 -0
- package/dist/phase6/weight-presets/index.d.ts.map +1 -0
- package/dist/phase6/weight-presets/index.js +8 -0
- package/dist/phase6/weight-presets/index.js.map +1 -0
- package/dist/phase6/weight-presets/merger.d.ts +79 -0
- package/dist/phase6/weight-presets/merger.d.ts.map +1 -0
- package/dist/phase6/weight-presets/merger.js +161 -0
- package/dist/phase6/weight-presets/merger.js.map +1 -0
- package/dist/proof/index.d.ts +6 -0
- package/dist/proof/index.d.ts.map +1 -1
- package/dist/proof/index.js +56 -6
- package/dist/proof/index.js.map +1 -1
- package/dist/proof/merkle.d.ts +195 -0
- package/dist/proof/merkle.d.ts.map +1 -0
- package/dist/proof/merkle.js +412 -0
- package/dist/proof/merkle.js.map +1 -0
- package/dist/proof/zk-proofs.d.ts +218 -0
- package/dist/proof/zk-proofs.d.ts.map +1 -0
- package/dist/proof/zk-proofs.js +531 -0
- package/dist/proof/zk-proofs.js.map +1 -0
- package/dist/sandbox-training/challenges.d.ts +16 -0
- package/dist/sandbox-training/challenges.d.ts.map +1 -0
- package/dist/sandbox-training/challenges.js +561 -0
- package/dist/sandbox-training/challenges.js.map +1 -0
- package/dist/sandbox-training/graduation.d.ts +25 -0
- package/dist/sandbox-training/graduation.d.ts.map +1 -0
- package/dist/sandbox-training/graduation.js +143 -0
- package/dist/sandbox-training/graduation.js.map +1 -0
- package/dist/sandbox-training/index.d.ts +19 -0
- package/dist/sandbox-training/index.d.ts.map +1 -0
- package/dist/sandbox-training/index.js +22 -0
- package/dist/sandbox-training/index.js.map +1 -0
- package/dist/sandbox-training/promotion-service.d.ts +76 -0
- package/dist/sandbox-training/promotion-service.d.ts.map +1 -0
- package/dist/sandbox-training/promotion-service.js +117 -0
- package/dist/sandbox-training/promotion-service.js.map +1 -0
- package/dist/sandbox-training/runner.d.ts +58 -0
- package/dist/sandbox-training/runner.d.ts.map +1 -0
- package/dist/sandbox-training/runner.js +388 -0
- package/dist/sandbox-training/runner.js.map +1 -0
- package/dist/sandbox-training/scorer.d.ts +40 -0
- package/dist/sandbox-training/scorer.d.ts.map +1 -0
- package/dist/sandbox-training/scorer.js +79 -0
- package/dist/sandbox-training/scorer.js.map +1 -0
- package/dist/sandbox-training/types.d.ts +162 -0
- package/dist/sandbox-training/types.d.ts.map +1 -0
- package/dist/sandbox-training/types.js +32 -0
- package/dist/sandbox-training/types.js.map +1 -0
- package/dist/trust-engine/ceiling-enforcement/audit.d.ts +98 -0
- package/dist/trust-engine/ceiling-enforcement/audit.d.ts.map +1 -0
- package/dist/trust-engine/ceiling-enforcement/audit.js +160 -0
- package/dist/trust-engine/ceiling-enforcement/audit.js.map +1 -0
- package/dist/trust-engine/ceiling-enforcement/index.d.ts +6 -0
- package/dist/trust-engine/ceiling-enforcement/index.d.ts.map +1 -0
- package/dist/trust-engine/ceiling-enforcement/index.js +6 -0
- package/dist/trust-engine/ceiling-enforcement/index.js.map +1 -0
- package/dist/trust-engine/ceiling-enforcement/kernel.d.ts +112 -0
- package/dist/trust-engine/ceiling-enforcement/kernel.d.ts.map +1 -0
- package/dist/trust-engine/ceiling-enforcement/kernel.js +158 -0
- package/dist/trust-engine/ceiling-enforcement/kernel.js.map +1 -0
- package/dist/trust-engine/context-policy/enforcement.d.ts +62 -0
- package/dist/trust-engine/context-policy/enforcement.d.ts.map +1 -0
- package/dist/trust-engine/context-policy/enforcement.js +104 -0
- package/dist/trust-engine/context-policy/enforcement.js.map +1 -0
- package/dist/trust-engine/context-policy/factory.d.ts +75 -0
- package/dist/trust-engine/context-policy/factory.d.ts.map +1 -0
- package/dist/trust-engine/context-policy/factory.js +130 -0
- package/dist/trust-engine/context-policy/factory.js.map +1 -0
- package/dist/trust-engine/context-policy/index.d.ts +6 -0
- package/dist/trust-engine/context-policy/index.d.ts.map +1 -0
- package/dist/trust-engine/context-policy/index.js +6 -0
- package/dist/trust-engine/context-policy/index.js.map +1 -0
- package/dist/trust-engine/creation-modifiers/index.d.ts +5 -0
- package/dist/trust-engine/creation-modifiers/index.d.ts.map +1 -0
- package/dist/trust-engine/creation-modifiers/index.js +5 -0
- package/dist/trust-engine/creation-modifiers/index.js.map +1 -0
- package/dist/trust-engine/creation-modifiers/types.d.ts +112 -0
- package/dist/trust-engine/creation-modifiers/types.d.ts.map +1 -0
- package/dist/trust-engine/creation-modifiers/types.js +166 -0
- package/dist/trust-engine/creation-modifiers/types.js.map +1 -0
- package/dist/trust-engine/index.d.ts +54 -1
- package/dist/trust-engine/index.d.ts.map +1 -1
- package/dist/trust-engine/index.js +118 -1
- package/dist/trust-engine/index.js.map +1 -1
- package/dist/trust-engine/phase6-types.d.ts +123 -0
- package/dist/trust-engine/phase6-types.d.ts.map +1 -0
- package/dist/trust-engine/phase6-types.js +88 -0
- package/dist/trust-engine/phase6-types.js.map +1 -0
- package/package.json +42 -12
- package/dist/audit/key-manager.d.ts +0 -118
- package/dist/audit/key-manager.d.ts.map +0 -1
- package/dist/audit/key-manager.js +0 -565
- package/dist/audit/key-manager.js.map +0 -1
- package/dist/carbon-aware/carbon-metrics.d.ts +0 -151
- package/dist/carbon-aware/carbon-metrics.d.ts.map +0 -1
- package/dist/carbon-aware/carbon-metrics.js +0 -370
- package/dist/carbon-aware/carbon-metrics.js.map +0 -1
- package/dist/carbon-aware/carbon-router.d.ts +0 -101
- package/dist/carbon-aware/carbon-router.d.ts.map +0 -1
- package/dist/carbon-aware/carbon-router.js +0 -400
- package/dist/carbon-aware/carbon-router.js.map +0 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Q3: Stratified Role Gates (3-Layer Enforcement)
|
|
3
|
+
*
|
|
4
|
+
* Implements three-layer role+trust enforcement:
|
|
5
|
+
* - Layer 1: Kernel (structure validation from pre-computed matrix)
|
|
6
|
+
* - Layer 2: Policy (authorization via policy-as-code rules)
|
|
7
|
+
* - Layer 3: BASIS/ENFORCE (runtime context with dual-control override)
|
|
8
|
+
*
|
|
9
|
+
* Key Features:
|
|
10
|
+
* - Pre-computed role gate matrix (compile-time verification)
|
|
11
|
+
* - Policy rules with priority, conditions, and actions
|
|
12
|
+
* - Dual-control override for exceptional cases
|
|
13
|
+
* - Full audit trail of all evaluations
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { type RoleGateEntry, type RoleGatePolicy, type RoleGateEvaluation, AgentRole, TrustTier, ContextType } from './types.js';
|
|
18
|
+
/**
|
|
19
|
+
* Get all role gate entries
|
|
20
|
+
*/
|
|
21
|
+
export declare function getRoleGateMatrix(): readonly RoleGateEntry[];
|
|
22
|
+
/**
|
|
23
|
+
* Get minimum required tier for a role
|
|
24
|
+
*/
|
|
25
|
+
export declare function getMinimumTierForRole(role: AgentRole): TrustTier;
|
|
26
|
+
/**
|
|
27
|
+
* Kernel layer validation result
|
|
28
|
+
*/
|
|
29
|
+
export interface KernelLayerResult {
|
|
30
|
+
valid: boolean;
|
|
31
|
+
matrixAllows: boolean;
|
|
32
|
+
reason?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Kernel layer: Validate role+tier combination against matrix
|
|
36
|
+
* This is the fastest check - uses pre-computed matrix.
|
|
37
|
+
*/
|
|
38
|
+
export declare function evaluateKernelLayer(role: AgentRole, tier: TrustTier): KernelLayerResult;
|
|
39
|
+
/**
|
|
40
|
+
* Policy evaluation context
|
|
41
|
+
*/
|
|
42
|
+
export interface PolicyEvaluationContext {
|
|
43
|
+
role: AgentRole;
|
|
44
|
+
tier: TrustTier;
|
|
45
|
+
contextType?: ContextType;
|
|
46
|
+
domains?: string[];
|
|
47
|
+
currentTime?: Date;
|
|
48
|
+
attestations?: string[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Policy layer result
|
|
52
|
+
*/
|
|
53
|
+
export interface PolicyLayerResult {
|
|
54
|
+
valid: boolean;
|
|
55
|
+
appliedRuleId?: string;
|
|
56
|
+
appliedPolicyVersion?: number;
|
|
57
|
+
action: 'ALLOW' | 'DENY' | 'ESCALATE';
|
|
58
|
+
reason: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Policy layer: Evaluate authorization rules
|
|
62
|
+
*/
|
|
63
|
+
export declare function evaluatePolicyLayer(context: PolicyEvaluationContext, policy: RoleGatePolicy): PolicyLayerResult;
|
|
64
|
+
/**
|
|
65
|
+
* Override request for dual-control scenarios
|
|
66
|
+
*/
|
|
67
|
+
export interface OverrideRequest {
|
|
68
|
+
requestedBy: string;
|
|
69
|
+
approvedBy: string;
|
|
70
|
+
reason: string;
|
|
71
|
+
expiresAt: Date;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* BASIS layer context
|
|
75
|
+
*/
|
|
76
|
+
export interface BasisLayerContext {
|
|
77
|
+
agentId: string;
|
|
78
|
+
contextConstraints: {
|
|
79
|
+
allowedRoles?: AgentRole[];
|
|
80
|
+
deniedRoles?: AgentRole[];
|
|
81
|
+
requiresOverride?: boolean;
|
|
82
|
+
overrideRequest?: OverrideRequest;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* BASIS layer result
|
|
87
|
+
*/
|
|
88
|
+
export interface BasisLayerResult {
|
|
89
|
+
valid: boolean;
|
|
90
|
+
requiresOverride: boolean;
|
|
91
|
+
overrideSignatures?: string[];
|
|
92
|
+
contextConstraintsMet: boolean;
|
|
93
|
+
reason?: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* BASIS/ENFORCE layer: Runtime context validation
|
|
97
|
+
*/
|
|
98
|
+
export declare function evaluateBasisLayer(role: AgentRole, context: BasisLayerContext): BasisLayerResult;
|
|
99
|
+
/**
|
|
100
|
+
* Evaluate all three layers and produce final decision
|
|
101
|
+
*/
|
|
102
|
+
export declare function evaluateRoleGate(agentId: string, role: AgentRole, tier: TrustTier, policy: RoleGatePolicy, basisContext: BasisLayerContext, policyContext?: Partial<PolicyEvaluationContext>): Promise<RoleGateEvaluation>;
|
|
103
|
+
/**
|
|
104
|
+
* Create default role gate policy
|
|
105
|
+
*/
|
|
106
|
+
export declare function createDefaultRoleGatePolicy(createdBy: string): Promise<RoleGatePolicy>;
|
|
107
|
+
/**
|
|
108
|
+
* Service for managing role gate evaluations
|
|
109
|
+
*/
|
|
110
|
+
export declare class RoleGateService {
|
|
111
|
+
private policies;
|
|
112
|
+
private evaluations;
|
|
113
|
+
private defaultPolicy?;
|
|
114
|
+
/**
|
|
115
|
+
* Initialize with default policy
|
|
116
|
+
*/
|
|
117
|
+
initialize(createdBy?: string): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Register a custom policy
|
|
120
|
+
*/
|
|
121
|
+
registerPolicy(policy: RoleGatePolicy): void;
|
|
122
|
+
/**
|
|
123
|
+
* Get current policy version
|
|
124
|
+
*/
|
|
125
|
+
getPolicy(policyId: string): RoleGatePolicy | undefined;
|
|
126
|
+
/**
|
|
127
|
+
* Get default policy
|
|
128
|
+
*/
|
|
129
|
+
getDefaultPolicy(): RoleGatePolicy | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* Evaluate role gate for an agent
|
|
132
|
+
*/
|
|
133
|
+
evaluate(agentId: string, role: AgentRole, tier: TrustTier, basisContext: BasisLayerContext, options?: {
|
|
134
|
+
policyId?: string;
|
|
135
|
+
policyContext?: Partial<PolicyEvaluationContext>;
|
|
136
|
+
}): Promise<RoleGateEvaluation>;
|
|
137
|
+
/**
|
|
138
|
+
* Quick check (kernel layer only)
|
|
139
|
+
*/
|
|
140
|
+
quickCheck(role: AgentRole, tier: TrustTier): boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Get evaluation history for an agent
|
|
143
|
+
*/
|
|
144
|
+
getEvaluationHistory(agentId: string): readonly RoleGateEvaluation[];
|
|
145
|
+
/**
|
|
146
|
+
* Get all evaluations that resulted in denial or escalation
|
|
147
|
+
*/
|
|
148
|
+
getDeniedEvaluations(): readonly RoleGateEvaluation[];
|
|
149
|
+
/**
|
|
150
|
+
* Get statistics
|
|
151
|
+
*/
|
|
152
|
+
getStats(): {
|
|
153
|
+
totalEvaluations: number;
|
|
154
|
+
byDecision: Record<'ALLOW' | 'DENY' | 'ESCALATE', number>;
|
|
155
|
+
byRole: Record<AgentRole, number>;
|
|
156
|
+
policyCount: number;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Create a new role gate service
|
|
161
|
+
*/
|
|
162
|
+
export declare function createRoleGateService(): RoleGateService;
|
|
163
|
+
export { type RoleGateEntry, type RoleGatePolicy, type RoleGatePolicyRule, type RoleGateCondition, type RoleGateEvaluation, AgentRole, TrustTier, ROLE_GATE_MATRIX, validateRoleGateKernel, } from './types.js';
|
|
164
|
+
//# sourceMappingURL=role-gates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"role-gates.d.ts","sourceRoot":"","sources":["../../src/phase6/role-gates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EAGnB,KAAK,kBAAkB,EACvB,SAAS,EACT,SAAS,EACT,WAAW,EAKZ,MAAM,YAAY,CAAC;AAuBpB;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,SAAS,aAAa,EAAE,CA0B5D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAOhE;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,iBAAiB,CAgBvF;AAMD;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AA2DD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,cAAc,GACrB,iBAAiB,CAsBnB;AAMD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE;QAClB,YAAY,CAAC,EAAE,SAAS,EAAE,CAAC;QAC3B,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC;QAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,eAAe,CAAC,EAAE,eAAe,CAAC;KACnC,CAAC;CACH;AAqBD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,iBAAiB,GACzB,gBAAgB,CA4DlB;AAMD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,cAAc,EACtB,YAAY,EAAE,iBAAiB,EAC/B,aAAa,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC/C,OAAO,CAAC,kBAAkB,CAAC,CAyF7B;AAMD;;GAEG;AACH,wBAAsB,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAyF5F;AAMD;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAA4C;IAC5D,OAAO,CAAC,WAAW,CAAgD;IACnE,OAAO,CAAC,aAAa,CAAC,CAAiB;IAEvC;;OAEG;IACG,UAAU,CAAC,SAAS,GAAE,MAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAO7D;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAO5C;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAKvD;;OAEG;IACH,gBAAgB,IAAI,cAAc,GAAG,SAAS;IAI9C;;OAEG;IACG,QAAQ,CACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,SAAS,EACf,YAAY,EAAE,iBAAiB,EAC/B,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;KAClD,GACA,OAAO,CAAC,kBAAkB,CAAC;IA4B9B;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO;IAIrD;;OAEG;IACH,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,kBAAkB,EAAE;IAIpE;;OAEG;IACH,oBAAoB,IAAI,SAAS,kBAAkB,EAAE;IAcrD;;OAEG;IACH,QAAQ,IAAI;QACV,gBAAgB,EAAE,MAAM,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,GAAG,UAAU,EAAE,MAAM,CAAC,CAAC;QAC1D,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAClC,WAAW,EAAE,MAAM,CAAC;KACrB;CAyBF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAEvD;AAMD,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Q3: Stratified Role Gates (3-Layer Enforcement)
|
|
3
|
+
*
|
|
4
|
+
* Implements three-layer role+trust enforcement:
|
|
5
|
+
* - Layer 1: Kernel (structure validation from pre-computed matrix)
|
|
6
|
+
* - Layer 2: Policy (authorization via policy-as-code rules)
|
|
7
|
+
* - Layer 3: BASIS/ENFORCE (runtime context with dual-control override)
|
|
8
|
+
*
|
|
9
|
+
* Key Features:
|
|
10
|
+
* - Pre-computed role gate matrix (compile-time verification)
|
|
11
|
+
* - Policy rules with priority, conditions, and actions
|
|
12
|
+
* - Dual-control override for exceptional cases
|
|
13
|
+
* - Full audit trail of all evaluations
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { createLogger } from '../common/logger.js';
|
|
18
|
+
import { AgentRole, TrustTier, ContextType, ROLE_GATE_MATRIX, validateRoleGateKernel, roleGateEvaluationSchema, } from './types.js';
|
|
19
|
+
const logger = createLogger({ component: 'phase6:role-gates' });
|
|
20
|
+
// =============================================================================
|
|
21
|
+
// HASH UTILITIES
|
|
22
|
+
// =============================================================================
|
|
23
|
+
/**
|
|
24
|
+
* Calculate SHA-256 hash
|
|
25
|
+
*/
|
|
26
|
+
async function calculateHash(data) {
|
|
27
|
+
const encoder = new TextEncoder();
|
|
28
|
+
const dataBuffer = encoder.encode(data);
|
|
29
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);
|
|
30
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
31
|
+
return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
32
|
+
}
|
|
33
|
+
// =============================================================================
|
|
34
|
+
// KERNEL LAYER (Pre-computed Matrix)
|
|
35
|
+
// =============================================================================
|
|
36
|
+
/**
|
|
37
|
+
* Get all role gate entries
|
|
38
|
+
*/
|
|
39
|
+
export function getRoleGateMatrix() {
|
|
40
|
+
const entries = [];
|
|
41
|
+
for (const role of Object.values(AgentRole)) {
|
|
42
|
+
const allowedTiers = [];
|
|
43
|
+
let minimumTier = TrustTier.T5;
|
|
44
|
+
for (const tier of Object.values(TrustTier)) {
|
|
45
|
+
if (ROLE_GATE_MATRIX[role][tier]) {
|
|
46
|
+
allowedTiers.push(tier);
|
|
47
|
+
// Track minimum tier
|
|
48
|
+
const tierOrder = [TrustTier.T0, TrustTier.T1, TrustTier.T2, TrustTier.T3, TrustTier.T4, TrustTier.T5];
|
|
49
|
+
if (tierOrder.indexOf(tier) < tierOrder.indexOf(minimumTier)) {
|
|
50
|
+
minimumTier = tier;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
entries.push({
|
|
55
|
+
role,
|
|
56
|
+
minimumTier,
|
|
57
|
+
allowedTiers,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return entries;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get minimum required tier for a role
|
|
64
|
+
*/
|
|
65
|
+
export function getMinimumTierForRole(role) {
|
|
66
|
+
for (const tier of [TrustTier.T0, TrustTier.T1, TrustTier.T2, TrustTier.T3, TrustTier.T4, TrustTier.T5]) {
|
|
67
|
+
if (ROLE_GATE_MATRIX[role][tier]) {
|
|
68
|
+
return tier;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return TrustTier.T5; // Fallback - requires highest tier
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Kernel layer: Validate role+tier combination against matrix
|
|
75
|
+
* This is the fastest check - uses pre-computed matrix.
|
|
76
|
+
*/
|
|
77
|
+
export function evaluateKernelLayer(role, tier) {
|
|
78
|
+
const matrixAllows = validateRoleGateKernel(role, tier);
|
|
79
|
+
if (!matrixAllows) {
|
|
80
|
+
const minimumTier = getMinimumTierForRole(role);
|
|
81
|
+
return {
|
|
82
|
+
valid: false,
|
|
83
|
+
matrixAllows: false,
|
|
84
|
+
reason: `Role ${role} requires minimum tier ${minimumTier}, current tier ${tier}`,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
valid: true,
|
|
89
|
+
matrixAllows: true,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Check if condition matches context
|
|
94
|
+
*/
|
|
95
|
+
function conditionMatches(condition, context) {
|
|
96
|
+
// Check roles
|
|
97
|
+
if (condition.roles && condition.roles.length > 0) {
|
|
98
|
+
if (!condition.roles.includes(context.role)) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Check tiers
|
|
103
|
+
if (condition.tiers && condition.tiers.length > 0) {
|
|
104
|
+
if (!condition.tiers.includes(context.tier)) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Check context types
|
|
109
|
+
if (condition.contextTypes && condition.contextTypes.length > 0) {
|
|
110
|
+
if (!context.contextType || !condition.contextTypes.includes(context.contextType)) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Check domains
|
|
115
|
+
if (condition.domains && condition.domains.length > 0) {
|
|
116
|
+
if (!context.domains || !condition.domains.some((d) => context.domains.includes(d))) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Check time window
|
|
121
|
+
if (condition.timeWindow) {
|
|
122
|
+
const now = context.currentTime ?? new Date();
|
|
123
|
+
const currentHHMM = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`;
|
|
124
|
+
if (currentHHMM < condition.timeWindow.start || currentHHMM > condition.timeWindow.end) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Check attestations
|
|
129
|
+
if (condition.requiresAttestation && condition.requiresAttestation.length > 0) {
|
|
130
|
+
if (!context.attestations) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
for (const required of condition.requiresAttestation) {
|
|
134
|
+
if (!context.attestations.includes(required)) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Policy layer: Evaluate authorization rules
|
|
143
|
+
*/
|
|
144
|
+
export function evaluatePolicyLayer(context, policy) {
|
|
145
|
+
// Sort rules by priority (lower number = higher priority)
|
|
146
|
+
const sortedRules = [...policy.rules].sort((a, b) => a.priority - b.priority);
|
|
147
|
+
for (const rule of sortedRules) {
|
|
148
|
+
if (conditionMatches(rule.condition, context)) {
|
|
149
|
+
return {
|
|
150
|
+
valid: rule.action === 'ALLOW',
|
|
151
|
+
appliedRuleId: rule.ruleId,
|
|
152
|
+
appliedPolicyVersion: policy.version,
|
|
153
|
+
action: rule.action,
|
|
154
|
+
reason: rule.reason,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// No rules matched - default allow (kernel already validated)
|
|
159
|
+
return {
|
|
160
|
+
valid: true,
|
|
161
|
+
action: 'ALLOW',
|
|
162
|
+
reason: 'No policy rules matched - default allow',
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Validate override request
|
|
167
|
+
*/
|
|
168
|
+
function validateOverride(override) {
|
|
169
|
+
const now = new Date();
|
|
170
|
+
// Check expiration
|
|
171
|
+
if (override.expiresAt < now) {
|
|
172
|
+
return { valid: false, reason: 'Override has expired' };
|
|
173
|
+
}
|
|
174
|
+
// Check dual-control (requester != approver)
|
|
175
|
+
if (override.requestedBy === override.approvedBy) {
|
|
176
|
+
return { valid: false, reason: 'Override requires dual-control (different requester and approver)' };
|
|
177
|
+
}
|
|
178
|
+
return { valid: true };
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* BASIS/ENFORCE layer: Runtime context validation
|
|
182
|
+
*/
|
|
183
|
+
export function evaluateBasisLayer(role, context) {
|
|
184
|
+
// Check denied roles
|
|
185
|
+
if (context.contextConstraints.deniedRoles?.includes(role)) {
|
|
186
|
+
return {
|
|
187
|
+
valid: false,
|
|
188
|
+
requiresOverride: false,
|
|
189
|
+
contextConstraintsMet: false,
|
|
190
|
+
reason: `Role ${role} is explicitly denied by context constraints`,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
// Check allowed roles (if specified, role must be in list)
|
|
194
|
+
if (context.contextConstraints.allowedRoles && context.contextConstraints.allowedRoles.length > 0) {
|
|
195
|
+
if (!context.contextConstraints.allowedRoles.includes(role)) {
|
|
196
|
+
return {
|
|
197
|
+
valid: false,
|
|
198
|
+
requiresOverride: true,
|
|
199
|
+
contextConstraintsMet: false,
|
|
200
|
+
reason: `Role ${role} not in allowed roles list`,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// Check if override is required
|
|
205
|
+
if (context.contextConstraints.requiresOverride) {
|
|
206
|
+
if (!context.contextConstraints.overrideRequest) {
|
|
207
|
+
return {
|
|
208
|
+
valid: false,
|
|
209
|
+
requiresOverride: true,
|
|
210
|
+
contextConstraintsMet: true,
|
|
211
|
+
reason: 'Override required but not provided',
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const overrideResult = validateOverride(context.contextConstraints.overrideRequest);
|
|
215
|
+
if (!overrideResult.valid) {
|
|
216
|
+
return {
|
|
217
|
+
valid: false,
|
|
218
|
+
requiresOverride: true,
|
|
219
|
+
contextConstraintsMet: true,
|
|
220
|
+
reason: overrideResult.reason,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
valid: true,
|
|
225
|
+
requiresOverride: true,
|
|
226
|
+
overrideSignatures: [
|
|
227
|
+
context.contextConstraints.overrideRequest.requestedBy,
|
|
228
|
+
context.contextConstraints.overrideRequest.approvedBy,
|
|
229
|
+
],
|
|
230
|
+
contextConstraintsMet: true,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
valid: true,
|
|
235
|
+
requiresOverride: false,
|
|
236
|
+
contextConstraintsMet: true,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
// =============================================================================
|
|
240
|
+
// FULL ROLE GATE EVALUATION
|
|
241
|
+
// =============================================================================
|
|
242
|
+
/**
|
|
243
|
+
* Evaluate all three layers and produce final decision
|
|
244
|
+
*/
|
|
245
|
+
export async function evaluateRoleGate(agentId, role, tier, policy, basisContext, policyContext) {
|
|
246
|
+
const now = new Date();
|
|
247
|
+
// Layer 1: Kernel
|
|
248
|
+
const kernelResult = evaluateKernelLayer(role, tier);
|
|
249
|
+
// Layer 2: Policy
|
|
250
|
+
const fullPolicyContext = {
|
|
251
|
+
role,
|
|
252
|
+
tier,
|
|
253
|
+
...policyContext,
|
|
254
|
+
};
|
|
255
|
+
const policyResult = evaluatePolicyLayer(fullPolicyContext, policy);
|
|
256
|
+
// Layer 3: BASIS/ENFORCE
|
|
257
|
+
const basisResult = evaluateBasisLayer(role, basisContext);
|
|
258
|
+
// Determine final decision
|
|
259
|
+
let decision;
|
|
260
|
+
if (!kernelResult.valid) {
|
|
261
|
+
// Kernel denial cannot be overridden
|
|
262
|
+
decision = 'DENY';
|
|
263
|
+
}
|
|
264
|
+
else if (!policyResult.valid) {
|
|
265
|
+
decision = policyResult.action;
|
|
266
|
+
}
|
|
267
|
+
else if (!basisResult.valid) {
|
|
268
|
+
decision = basisResult.requiresOverride ? 'ESCALATE' : 'DENY';
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
decision = 'ALLOW';
|
|
272
|
+
}
|
|
273
|
+
const evaluationData = {
|
|
274
|
+
evaluationId: crypto.randomUUID(),
|
|
275
|
+
agentId,
|
|
276
|
+
role,
|
|
277
|
+
tier,
|
|
278
|
+
timestamp: now,
|
|
279
|
+
kernelResult: {
|
|
280
|
+
valid: kernelResult.valid,
|
|
281
|
+
matrixAllows: kernelResult.matrixAllows,
|
|
282
|
+
reason: kernelResult.reason,
|
|
283
|
+
},
|
|
284
|
+
policyResult: {
|
|
285
|
+
valid: policyResult.valid,
|
|
286
|
+
appliedRuleId: policyResult.appliedRuleId,
|
|
287
|
+
appliedPolicyVersion: policyResult.appliedPolicyVersion,
|
|
288
|
+
action: policyResult.action,
|
|
289
|
+
reason: policyResult.reason,
|
|
290
|
+
},
|
|
291
|
+
basisResult: {
|
|
292
|
+
valid: basisResult.valid,
|
|
293
|
+
requiresOverride: basisResult.requiresOverride,
|
|
294
|
+
overrideSignatures: basisResult.overrideSignatures,
|
|
295
|
+
contextConstraintsMet: basisResult.contextConstraintsMet,
|
|
296
|
+
reason: basisResult.reason,
|
|
297
|
+
},
|
|
298
|
+
decision,
|
|
299
|
+
decidedAt: now,
|
|
300
|
+
};
|
|
301
|
+
const evaluationHash = await calculateHash(JSON.stringify(evaluationData));
|
|
302
|
+
const evaluation = {
|
|
303
|
+
...evaluationData,
|
|
304
|
+
evaluationHash,
|
|
305
|
+
};
|
|
306
|
+
// Validate with Zod
|
|
307
|
+
const parsed = roleGateEvaluationSchema.safeParse(evaluation);
|
|
308
|
+
if (!parsed.success) {
|
|
309
|
+
throw new Error(`Invalid role gate evaluation: ${parsed.error.message}`);
|
|
310
|
+
}
|
|
311
|
+
if (decision !== 'ALLOW') {
|
|
312
|
+
logger.warn({
|
|
313
|
+
agentId,
|
|
314
|
+
role,
|
|
315
|
+
tier,
|
|
316
|
+
decision,
|
|
317
|
+
kernelValid: kernelResult.valid,
|
|
318
|
+
policyValid: policyResult.valid,
|
|
319
|
+
basisValid: basisResult.valid,
|
|
320
|
+
}, 'Role gate denied or escalated');
|
|
321
|
+
}
|
|
322
|
+
return evaluation;
|
|
323
|
+
}
|
|
324
|
+
// =============================================================================
|
|
325
|
+
// DEFAULT POLICIES
|
|
326
|
+
// =============================================================================
|
|
327
|
+
/**
|
|
328
|
+
* Create default role gate policy
|
|
329
|
+
*/
|
|
330
|
+
export async function createDefaultRoleGatePolicy(createdBy) {
|
|
331
|
+
const now = new Date();
|
|
332
|
+
const policy = {
|
|
333
|
+
policyId: 'default:role-gate-policy',
|
|
334
|
+
version: 1,
|
|
335
|
+
rules: [
|
|
336
|
+
// Rule 1: Block sovereign roles (R-L6+) in non-sovereign contexts
|
|
337
|
+
{
|
|
338
|
+
ruleId: 'rule:sovereign-context-required',
|
|
339
|
+
name: 'Sovereign Context Required for High Roles',
|
|
340
|
+
condition: {
|
|
341
|
+
roles: [AgentRole.R_L6, AgentRole.R_L7, AgentRole.R_L8],
|
|
342
|
+
contextTypes: [ContextType.LOCAL, ContextType.ENTERPRISE],
|
|
343
|
+
},
|
|
344
|
+
action: 'DENY',
|
|
345
|
+
priority: 10,
|
|
346
|
+
reason: 'Sovereign roles (R-L6+) require sovereign context',
|
|
347
|
+
},
|
|
348
|
+
// Rule 2: Require attestation for orchestrators
|
|
349
|
+
{
|
|
350
|
+
ruleId: 'rule:orchestrator-attestation',
|
|
351
|
+
name: 'Orchestrator Attestation Required',
|
|
352
|
+
condition: {
|
|
353
|
+
roles: [AgentRole.R_L3],
|
|
354
|
+
requiresAttestation: ['capability:orchestration'],
|
|
355
|
+
},
|
|
356
|
+
action: 'ALLOW',
|
|
357
|
+
priority: 20,
|
|
358
|
+
reason: 'Orchestrators require capability attestation',
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
ruleId: 'rule:orchestrator-no-attestation',
|
|
362
|
+
name: 'Orchestrator Without Attestation',
|
|
363
|
+
condition: {
|
|
364
|
+
roles: [AgentRole.R_L3],
|
|
365
|
+
},
|
|
366
|
+
action: 'ESCALATE',
|
|
367
|
+
priority: 21,
|
|
368
|
+
reason: 'Orchestrator without attestation requires approval',
|
|
369
|
+
},
|
|
370
|
+
// Rule 3: Allow basic roles everywhere
|
|
371
|
+
{
|
|
372
|
+
ruleId: 'rule:basic-roles-allowed',
|
|
373
|
+
name: 'Basic Roles Allowed',
|
|
374
|
+
condition: {
|
|
375
|
+
roles: [AgentRole.R_L0, AgentRole.R_L1],
|
|
376
|
+
},
|
|
377
|
+
action: 'ALLOW',
|
|
378
|
+
priority: 100,
|
|
379
|
+
reason: 'Listener and executor roles are generally allowed',
|
|
380
|
+
},
|
|
381
|
+
// Rule 4: Business hours restriction for architects
|
|
382
|
+
{
|
|
383
|
+
ruleId: 'rule:architect-business-hours',
|
|
384
|
+
name: 'Architect Business Hours Only',
|
|
385
|
+
condition: {
|
|
386
|
+
roles: [AgentRole.R_L4],
|
|
387
|
+
timeWindow: { start: '09:00', end: '17:00' },
|
|
388
|
+
},
|
|
389
|
+
action: 'ALLOW',
|
|
390
|
+
priority: 30,
|
|
391
|
+
reason: 'Architects allowed during business hours',
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
ruleId: 'rule:architect-outside-hours',
|
|
395
|
+
name: 'Architect Outside Hours Escalation',
|
|
396
|
+
condition: {
|
|
397
|
+
roles: [AgentRole.R_L4],
|
|
398
|
+
},
|
|
399
|
+
action: 'ESCALATE',
|
|
400
|
+
priority: 31,
|
|
401
|
+
reason: 'Architect operations outside business hours require approval',
|
|
402
|
+
},
|
|
403
|
+
],
|
|
404
|
+
effectiveFrom: now,
|
|
405
|
+
createdAt: now,
|
|
406
|
+
createdBy,
|
|
407
|
+
policyHash: await calculateHash(JSON.stringify({
|
|
408
|
+
policyId: 'default:role-gate-policy',
|
|
409
|
+
version: 1,
|
|
410
|
+
createdAt: now.toISOString(),
|
|
411
|
+
})),
|
|
412
|
+
};
|
|
413
|
+
return policy;
|
|
414
|
+
}
|
|
415
|
+
// =============================================================================
|
|
416
|
+
// ROLE GATE SERVICE
|
|
417
|
+
// =============================================================================
|
|
418
|
+
/**
|
|
419
|
+
* Service for managing role gate evaluations
|
|
420
|
+
*/
|
|
421
|
+
export class RoleGateService {
|
|
422
|
+
policies = new Map(); // policyId -> versions
|
|
423
|
+
evaluations = new Map(); // agentId -> evaluations
|
|
424
|
+
defaultPolicy;
|
|
425
|
+
/**
|
|
426
|
+
* Initialize with default policy
|
|
427
|
+
*/
|
|
428
|
+
async initialize(createdBy = 'system') {
|
|
429
|
+
this.defaultPolicy = await createDefaultRoleGatePolicy(createdBy);
|
|
430
|
+
const versions = [this.defaultPolicy];
|
|
431
|
+
this.policies.set(this.defaultPolicy.policyId, versions);
|
|
432
|
+
logger.info('Role gate service initialized with default policy');
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Register a custom policy
|
|
436
|
+
*/
|
|
437
|
+
registerPolicy(policy) {
|
|
438
|
+
const versions = this.policies.get(policy.policyId) ?? [];
|
|
439
|
+
versions.push(policy);
|
|
440
|
+
this.policies.set(policy.policyId, versions);
|
|
441
|
+
logger.info({ policyId: policy.policyId, version: policy.version }, 'Policy registered');
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Get current policy version
|
|
445
|
+
*/
|
|
446
|
+
getPolicy(policyId) {
|
|
447
|
+
const versions = this.policies.get(policyId);
|
|
448
|
+
return versions?.[versions.length - 1];
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Get default policy
|
|
452
|
+
*/
|
|
453
|
+
getDefaultPolicy() {
|
|
454
|
+
return this.defaultPolicy;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Evaluate role gate for an agent
|
|
458
|
+
*/
|
|
459
|
+
async evaluate(agentId, role, tier, basisContext, options) {
|
|
460
|
+
// Get policy
|
|
461
|
+
const policy = options?.policyId
|
|
462
|
+
? this.getPolicy(options.policyId)
|
|
463
|
+
: this.defaultPolicy;
|
|
464
|
+
if (!policy) {
|
|
465
|
+
throw new Error('No policy available for evaluation');
|
|
466
|
+
}
|
|
467
|
+
// Evaluate
|
|
468
|
+
const evaluation = await evaluateRoleGate(agentId, role, tier, policy, basisContext, options?.policyContext);
|
|
469
|
+
// Store evaluation
|
|
470
|
+
const agentEvaluations = this.evaluations.get(agentId) ?? [];
|
|
471
|
+
agentEvaluations.push(evaluation);
|
|
472
|
+
this.evaluations.set(agentId, agentEvaluations);
|
|
473
|
+
return evaluation;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Quick check (kernel layer only)
|
|
477
|
+
*/
|
|
478
|
+
quickCheck(role, tier) {
|
|
479
|
+
return validateRoleGateKernel(role, tier);
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Get evaluation history for an agent
|
|
483
|
+
*/
|
|
484
|
+
getEvaluationHistory(agentId) {
|
|
485
|
+
return this.evaluations.get(agentId) ?? [];
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Get all evaluations that resulted in denial or escalation
|
|
489
|
+
*/
|
|
490
|
+
getDeniedEvaluations() {
|
|
491
|
+
const denied = [];
|
|
492
|
+
for (const evaluations of this.evaluations.values()) {
|
|
493
|
+
for (const evaluation of evaluations) {
|
|
494
|
+
if (evaluation.decision !== 'ALLOW') {
|
|
495
|
+
denied.push(evaluation);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return denied.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Get statistics
|
|
503
|
+
*/
|
|
504
|
+
getStats() {
|
|
505
|
+
const byDecision = { ALLOW: 0, DENY: 0, ESCALATE: 0 };
|
|
506
|
+
const byRole = {};
|
|
507
|
+
for (const role of Object.values(AgentRole)) {
|
|
508
|
+
byRole[role] = 0;
|
|
509
|
+
}
|
|
510
|
+
let totalEvaluations = 0;
|
|
511
|
+
for (const evaluations of this.evaluations.values()) {
|
|
512
|
+
for (const evaluation of evaluations) {
|
|
513
|
+
totalEvaluations++;
|
|
514
|
+
byDecision[evaluation.decision]++;
|
|
515
|
+
byRole[evaluation.role]++;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return {
|
|
519
|
+
totalEvaluations,
|
|
520
|
+
byDecision,
|
|
521
|
+
byRole,
|
|
522
|
+
policyCount: this.policies.size,
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Create a new role gate service
|
|
528
|
+
*/
|
|
529
|
+
export function createRoleGateService() {
|
|
530
|
+
return new RoleGateService();
|
|
531
|
+
}
|
|
532
|
+
// =============================================================================
|
|
533
|
+
// EXPORTS
|
|
534
|
+
// =============================================================================
|
|
535
|
+
export { AgentRole, TrustTier, ROLE_GATE_MATRIX, validateRoleGateKernel, } from './types.js';
|
|
536
|
+
//# sourceMappingURL=role-gates.js.map
|