@a5c-ai/comm-adapter 6.0.2 → 6.0.3-staging.032e07a1ffa0
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/dist/__tests__/e2e-gate3-credential.e2e.test.d.ts +1 -0
- package/dist/__tests__/e2e-gate3-credential.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e-gate3-credential.e2e.test.js +191 -0
- package/dist/__tests__/e2e-gate3-credential.e2e.test.js.map +1 -0
- package/dist/__tests__/policy-credential-gate.test.d.ts +1 -0
- package/dist/__tests__/policy-credential-gate.test.d.ts.map +1 -0
- package/dist/__tests__/policy-credential-gate.test.js +327 -0
- package/dist/__tests__/policy-credential-gate.test.js.map +1 -0
- package/dist/__tests__/policy-pretooluse-gate.test.d.ts +1 -0
- package/dist/__tests__/policy-pretooluse-gate.test.d.ts.map +1 -0
- package/dist/__tests__/policy-pretooluse-gate.test.js +154 -0
- package/dist/__tests__/policy-pretooluse-gate.test.js.map +1 -0
- package/dist/__tests__/policy-spawn-gate.test.d.ts +1 -0
- package/dist/__tests__/policy-spawn-gate.test.d.ts.map +1 -0
- package/dist/__tests__/policy-spawn-gate.test.js +240 -0
- package/dist/__tests__/policy-spawn-gate.test.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/policy-credential-gate.d.ts +86 -0
- package/dist/policy-credential-gate.d.ts.map +1 -0
- package/dist/policy-credential-gate.js +141 -0
- package/dist/policy-credential-gate.js.map +1 -0
- package/dist/policy-pretooluse-hook.d.ts +55 -0
- package/dist/policy-pretooluse-hook.d.ts.map +1 -0
- package/dist/policy-pretooluse-hook.js +80 -0
- package/dist/policy-pretooluse-hook.js.map +1 -0
- package/dist/policy-spawn-gate.d.ts +82 -0
- package/dist/policy-spawn-gate.d.ts.map +1 -0
- package/dist/policy-spawn-gate.js +115 -0
- package/dist/policy-spawn-gate.js.map +1 -0
- package/dist/run-options.d.ts +40 -0
- package/dist/run-options.d.ts.map +1 -1
- package/dist/run-options.js.map +1 -1
- package/dist/spawn-invocation.d.ts +73 -1
- package/dist/spawn-invocation.d.ts.map +1 -1
- package/dist/spawn-invocation.js +190 -11
- package/dist/spawn-invocation.js.map +1 -1
- package/dist/spawn-runner.d.ts.map +1 -1
- package/dist/spawn-runner.js +41 -1
- package/dist/spawn-runner.js.map +1 -1
- package/package.json +6 -4
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Milestone D — GATE 3: credential-injection backstop (§9.3 / AC-23a / AC-40 /
|
|
3
|
+
* AC-40a / AC-50 / AC-55).
|
|
4
|
+
*
|
|
5
|
+
* Before env / credential injection, GATE 3 verifies a credential attestation: a
|
|
6
|
+
* policy-bound (scoped) credential is delivered ONLY when a valid
|
|
7
|
+
* CommandAuthorization covers its scope. It mediates every credential-delivery
|
|
8
|
+
* channel `spawn-invocation.ts` constructs:
|
|
9
|
+
* - env injection: docker `-e`, ssh `K=V`, k8s `env` / `--env` (`*-env`);
|
|
10
|
+
* - docker `-v` file mounts (`docker-mount`);
|
|
11
|
+
* - k8s secret / serviceaccount references (`k8s-secret`,
|
|
12
|
+
* `k8s-serviceaccount`).
|
|
13
|
+
* With NO valid authorization the channel is OMITTED (env dropped, mount omitted,
|
|
14
|
+
* secret/serviceaccount ref stripped); if the policy marks the credential REQUIRED,
|
|
15
|
+
* the spawn is DENIED.
|
|
16
|
+
*
|
|
17
|
+
* The credential→scope tag comes from a TRUSTED, out-of-agent source (AC-40) keyed
|
|
18
|
+
* by a COLLISION-RESISTANT identity (AC-40a); aliases of one physical credential
|
|
19
|
+
* canonicalize to one identity (AC-55). An absent / ambiguous identity, or no
|
|
20
|
+
* mediated scope, → deny (fail closed) — never inject an untagged credential, never
|
|
21
|
+
* pick the narrower of two candidate scopes.
|
|
22
|
+
*
|
|
23
|
+
* GATE 3 is the LAST point before exec, so it RECOMPUTES argsHash / commandHash from
|
|
24
|
+
* the exact spawn (TOCTOU, AC-32) and re-checks them against the authorization.
|
|
25
|
+
*
|
|
26
|
+
* BOUNDED, WARNED NON-GOAL (AC-50): credentials the process obtains WITHOUT
|
|
27
|
+
* spawn-invocation constructing the delivery — IMDS / IRSA / workload-identity,
|
|
28
|
+
* pre-existing mounts, image creds — cannot be gated. For a scoped credential with
|
|
29
|
+
* no GATE-3-mediated scope, the gate fails closed (does not inject) and surfaces a
|
|
30
|
+
* warning; it does NOT claim a backstop for such an action.
|
|
31
|
+
*
|
|
32
|
+
* OVERRIDING RULE: fail closed. Any verification / parse / resolution error, or any
|
|
33
|
+
* thrown exception, is a deny / no-injection. No fallbacks.
|
|
34
|
+
*/
|
|
35
|
+
import { verifyCommandAuthorization, resolveCredentialScope, argsHash as computeArgsHash, commandHash as computeCommandHash, } from '@a5c-ai/policy-adapter';
|
|
36
|
+
/**
|
|
37
|
+
* Gate credential injection at the last point before exec (AC-23a). Returns the
|
|
38
|
+
* credentials that may be delivered, those dropped, whether the spawn is denied, and
|
|
39
|
+
* any bounded-non-goal warnings.
|
|
40
|
+
*/
|
|
41
|
+
export function gateCredentialInjection(input) {
|
|
42
|
+
const injected = [];
|
|
43
|
+
const dropped = [];
|
|
44
|
+
const warnings = [];
|
|
45
|
+
try {
|
|
46
|
+
if (!input || typeof input !== 'object') {
|
|
47
|
+
return { denied: true, injected, dropped, warnings, reason: 'missing gate input' };
|
|
48
|
+
}
|
|
49
|
+
if (!Array.isArray(input.credentials)) {
|
|
50
|
+
return { denied: true, injected, dropped, warnings, reason: 'missing credentials' };
|
|
51
|
+
}
|
|
52
|
+
if (!input.credentialSource || typeof input.credentialSource !== 'object') {
|
|
53
|
+
// No trusted source → cannot tag ANY scoped credential → drop all, fail closed.
|
|
54
|
+
for (const cred of input.credentials)
|
|
55
|
+
dropped.push(cred);
|
|
56
|
+
return {
|
|
57
|
+
denied: input.credentials.some((c) => c?.required === true),
|
|
58
|
+
injected,
|
|
59
|
+
dropped,
|
|
60
|
+
warnings,
|
|
61
|
+
reason: 'missing trusted credential scope source',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// Recompute the authorization binding hashes from the EXACT spawn (TOCTOU, AC-32).
|
|
65
|
+
const argsHash = computeArgsHash(input.args);
|
|
66
|
+
const commandHash = computeCommandHash(input.command ?? '');
|
|
67
|
+
// Resolve + verify the authorization ONCE per spawn against the recomputed binding.
|
|
68
|
+
const authorization = input.resolveAuthorization?.();
|
|
69
|
+
let denied = false;
|
|
70
|
+
const denyReasons = [];
|
|
71
|
+
for (const cred of input.credentials) {
|
|
72
|
+
// (AC-40 / AC-40a / AC-55) Resolve the credential's scope from the trusted source
|
|
73
|
+
// keyed by the collision-resistant canonical identity of its alias. An absent /
|
|
74
|
+
// ambiguous alias, or an identity with no mediated scope → no scope.
|
|
75
|
+
const scopeResolution = resolveCredentialScope(cred.alias, input.credentialSource);
|
|
76
|
+
if (!scopeResolution.resolved || typeof scopeResolution.scope !== 'string') {
|
|
77
|
+
// No GATE-3-mediated scope for a scoped credential: fail closed (do NOT inject
|
|
78
|
+
// an untagged credential, AC-40) and surface the bounded-non-goal warning (AC-50)
|
|
79
|
+
// — the credential may be substrate-delivered (IMDS/IRSA/pre-mount), which GATE 3
|
|
80
|
+
// cannot mediate.
|
|
81
|
+
dropped.push(cred);
|
|
82
|
+
warnings.push(`credential '${cred.name}' (alias '${cred.alias}') has no GATE-3-mediated scope: ` +
|
|
83
|
+
`${scopeResolution.reason ?? 'unresolved'} — not injected (bounded non-goal, AC-50)`);
|
|
84
|
+
if (cred.required === true) {
|
|
85
|
+
denied = true;
|
|
86
|
+
denyReasons.push(`required credential '${cred.name}' has no mediated scope`);
|
|
87
|
+
}
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const scope = scopeResolution.scope;
|
|
91
|
+
// A valid CommandAuthorization whose credentialScope matches is REQUIRED before
|
|
92
|
+
// the credential may be delivered by its channel (AC-23a).
|
|
93
|
+
let authorized = false;
|
|
94
|
+
if (authorization) {
|
|
95
|
+
const verification = verifyCommandAuthorization(authorization, {
|
|
96
|
+
now: input.now,
|
|
97
|
+
toolName: input.toolName,
|
|
98
|
+
toolCallId: input.toolCallId,
|
|
99
|
+
commandHash,
|
|
100
|
+
argsHash,
|
|
101
|
+
credentialScope: scope,
|
|
102
|
+
policyDocHash: input.policyDocHash,
|
|
103
|
+
currentConfigEpoch: input.currentConfigEpoch,
|
|
104
|
+
minEpochFloor: input.minEpochFloor,
|
|
105
|
+
issuerRoots: input.issuerRoots,
|
|
106
|
+
});
|
|
107
|
+
authorized = verification.valid;
|
|
108
|
+
}
|
|
109
|
+
if (authorized) {
|
|
110
|
+
injected.push(cred);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
// No valid authorization → the channel is OMITTED (env dropped, -v mount
|
|
114
|
+
// omitted, secret/serviceaccount ref stripped). If required, deny the spawn.
|
|
115
|
+
dropped.push(cred);
|
|
116
|
+
if (cred.required === true) {
|
|
117
|
+
denied = true;
|
|
118
|
+
denyReasons.push(`required credential '${cred.name}' lacks a valid authorization for scope '${scope}'`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
denied,
|
|
124
|
+
injected,
|
|
125
|
+
dropped,
|
|
126
|
+
warnings,
|
|
127
|
+
reason: denyReasons.length > 0 ? denyReasons.join('; ') : undefined,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
// Fail closed — any exception is a deny / no-injection, never a pass.
|
|
132
|
+
return {
|
|
133
|
+
denied: true,
|
|
134
|
+
injected: [],
|
|
135
|
+
dropped: [...injected, ...dropped],
|
|
136
|
+
warnings,
|
|
137
|
+
reason: `exception during GATE 3 evaluation: ${err?.message ?? String(err)}`,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=policy-credential-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-credential-gate.js","sourceRoot":"","sources":["../src/policy-credential-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,EACtB,QAAQ,IAAI,eAAe,EAC3B,WAAW,IAAI,kBAAkB,GAIlC,MAAM,wBAAwB,CAAC;AAyDhC;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAmC;IAEnC,MAAM,QAAQ,GAAuB,EAAE,CAAC;IACxC,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACxC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;QACrF,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;QACtF,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,gBAAgB,IAAI,OAAO,KAAK,CAAC,gBAAgB,KAAK,QAAQ,EAAE,CAAC;YAC1E,gFAAgF;YAChF,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,WAAW;gBAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzD,OAAO;gBACL,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC;gBAC3D,QAAQ;gBACR,OAAO;gBACP,QAAQ;gBACR,MAAM,EAAE,yCAAyC;aAClD,CAAC;QACJ,CAAC;QAED,mFAAmF;QACnF,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,WAAW,GAAG,kBAAkB,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAE5D,oFAAoF;QACpF,MAAM,aAAa,GAAG,KAAK,CAAC,oBAAoB,EAAE,EAAE,CAAC;QAErD,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,MAAM,WAAW,GAAa,EAAE,CAAC;QAEjC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACrC,kFAAkF;YAClF,gFAAgF;YAChF,qEAAqE;YACrE,MAAM,eAAe,GAAG,sBAAsB,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;YACnF,IAAI,CAAC,eAAe,CAAC,QAAQ,IAAI,OAAO,eAAe,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC3E,+EAA+E;gBAC/E,kFAAkF;gBAClF,kFAAkF;gBAClF,kBAAkB;gBAClB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnB,QAAQ,CAAC,IAAI,CACX,eAAe,IAAI,CAAC,IAAI,aAAa,IAAI,CAAC,KAAK,mCAAmC;oBAChF,GAAG,eAAe,CAAC,MAAM,IAAI,YAAY,2CAA2C,CACvF,CAAC;gBACF,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;oBAC3B,MAAM,GAAG,IAAI,CAAC;oBACd,WAAW,CAAC,IAAI,CAAC,wBAAwB,IAAI,CAAC,IAAI,yBAAyB,CAAC,CAAC;gBAC/E,CAAC;gBACD,SAAS;YACX,CAAC;YAED,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC;YAEpC,gFAAgF;YAChF,2DAA2D;YAC3D,IAAI,UAAU,GAAG,KAAK,CAAC;YACvB,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,YAAY,GAAG,0BAA0B,CAAC,aAAa,EAAE;oBAC7D,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,WAAW;oBACX,QAAQ;oBACR,eAAe,EAAE,KAAK;oBACtB,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;oBAC5C,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,WAAW,EAAE,KAAK,CAAC,WAAW;iBAC/B,CAAC,CAAC;gBACH,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC;YAClC,CAAC;YAED,IAAI,UAAU,EAAE,CAAC;gBACf,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,yEAAyE;gBACzE,6EAA6E;gBAC7E,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;oBAC3B,MAAM,GAAG,IAAI,CAAC;oBACd,WAAW,CAAC,IAAI,CACd,wBAAwB,IAAI,CAAC,IAAI,4CAA4C,KAAK,GAAG,CACtF,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO;YACL,MAAM;YACN,QAAQ;YACR,OAAO;YACP,QAAQ;YACR,MAAM,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SACpE,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,sEAAsE;QACtE,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC;YAClC,QAAQ;YACR,MAAM,EAAE,uCAAwC,GAAa,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE;SACxF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Milestone D — GATE 2: runtime preToolUse policy handler (§9.2 / AC-23b / AC-49 /
|
|
3
|
+
* AC-44).
|
|
4
|
+
*
|
|
5
|
+
* The runtime preToolUse BLOCKING dispatch (spawn-runtime-hooks.ts) gates spawned
|
|
6
|
+
* harnesses. This factory produces a `PreToolUseHook` that returns
|
|
7
|
+
* `{ decision: 'deny', reason }` for a covered call that lacks a valid
|
|
8
|
+
* CommandAuthorization. The proof context (the exact toolCallId / argsHash /
|
|
9
|
+
* commandHash / credentialScope about to execute) is recomputed HERE from the
|
|
10
|
+
* preToolUse payload and bound to the authorization (AC-23b).
|
|
11
|
+
*
|
|
12
|
+
* Enforcement note (AC-49 / AC-44): only `mode === 'blocking'` adapters convert a
|
|
13
|
+
* deny into a swallowed tool event (spawn-runtime-hooks.ts). For non-blocking
|
|
14
|
+
* (advisory) adapters GATE 1 / GATE 3 are the enforcing gates — GATE 2 is
|
|
15
|
+
* defense-in-depth, never the sole line. This handler always RETURNS the correct
|
|
16
|
+
* decision; whether it hard-enforces is the runtime's mode decision.
|
|
17
|
+
*
|
|
18
|
+
* OVERRIDING RULE: fail closed. Any verification / parse / binding error, or any
|
|
19
|
+
* thrown exception, is a `{ decision: 'deny' }`. No fallbacks.
|
|
20
|
+
*/
|
|
21
|
+
import { type CommandAuthorizationPayload, type TrustRoot } from '@a5c-ai/policy-adapter';
|
|
22
|
+
import type { SignedEnvelope } from '@a5c-ai/trust-core';
|
|
23
|
+
import type { PreToolUseHook } from './runtime-hooks.js';
|
|
24
|
+
/**
|
|
25
|
+
* The preToolUse payload shape the runtime dispatches (spawn-runtime-hooks.ts),
|
|
26
|
+
* EXTENDED by Milestone D to carry the proof context (AC-23b).
|
|
27
|
+
*/
|
|
28
|
+
export interface PolicyPreToolUsePayload {
|
|
29
|
+
sessionId?: string;
|
|
30
|
+
toolCallId: string;
|
|
31
|
+
toolName: string;
|
|
32
|
+
input: unknown;
|
|
33
|
+
}
|
|
34
|
+
export interface CreatePolicyPreToolUseHookOptions {
|
|
35
|
+
/** Issuer trust roots (kind `engine`) that may sign a CommandAuthorization. */
|
|
36
|
+
issuerRoots: TrustRoot[];
|
|
37
|
+
/** sha256 of the integrity-verified policy document governing this action. */
|
|
38
|
+
policyDocHash: string;
|
|
39
|
+
/** The config epoch of the currently-honored signed manifest (AC-46). */
|
|
40
|
+
currentConfigEpoch: number;
|
|
41
|
+
/** The off-workspace pinned minimum-epoch floor (AC-47). */
|
|
42
|
+
minEpochFloor: number;
|
|
43
|
+
/** Coverage predicate: is this action policy-covered? */
|
|
44
|
+
isCovered: (payload: PolicyPreToolUsePayload) => boolean;
|
|
45
|
+
/** The credential scope for the executing action (from the trusted source, AC-40). */
|
|
46
|
+
credentialScopeFor: (payload: PolicyPreToolUsePayload) => string;
|
|
47
|
+
/** Resolve the CommandAuthorization bound to this exact tool call (or none). */
|
|
48
|
+
resolveAuthorization: (payload: PolicyPreToolUsePayload) => SignedEnvelope<CommandAuthorizationPayload> | undefined;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Build a GATE-2 preToolUse policy handler (AC-23b). For a covered call the handler
|
|
52
|
+
* REQUIRES a valid CommandAuthorization bound to the exact toolCallId / argsHash /
|
|
53
|
+
* commandHash / credentialScope in the payload; otherwise it denies (fail closed).
|
|
54
|
+
*/
|
|
55
|
+
export declare function createPolicyPreToolUseHook(options: CreatePolicyPreToolUseHookOptions): PreToolUseHook<PolicyPreToolUsePayload>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-pretooluse-hook.d.ts","sourceRoot":"","sources":["../src/policy-pretooluse-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAIL,KAAK,2BAA2B,EAChC,KAAK,SAAS,EACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,KAAK,EAA6B,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpF;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,iCAAiC;IAChD,+EAA+E;IAC/E,WAAW,EAAE,SAAS,EAAE,CAAC;IACzB,8EAA8E;IAC9E,aAAa,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,aAAa,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,SAAS,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC;IACzD,sFAAsF;IACtF,kBAAkB,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,MAAM,CAAC;IACjE,gFAAgF;IAChF,oBAAoB,EAAE,CACpB,OAAO,EAAE,uBAAuB,KAC7B,cAAc,CAAC,2BAA2B,CAAC,GAAG,SAAS,CAAC;CAC9D;AAcD;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,iCAAiC,GACzC,cAAc,CAAC,uBAAuB,CAAC,CAgDzC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Milestone D — GATE 2: runtime preToolUse policy handler (§9.2 / AC-23b / AC-49 /
|
|
3
|
+
* AC-44).
|
|
4
|
+
*
|
|
5
|
+
* The runtime preToolUse BLOCKING dispatch (spawn-runtime-hooks.ts) gates spawned
|
|
6
|
+
* harnesses. This factory produces a `PreToolUseHook` that returns
|
|
7
|
+
* `{ decision: 'deny', reason }` for a covered call that lacks a valid
|
|
8
|
+
* CommandAuthorization. The proof context (the exact toolCallId / argsHash /
|
|
9
|
+
* commandHash / credentialScope about to execute) is recomputed HERE from the
|
|
10
|
+
* preToolUse payload and bound to the authorization (AC-23b).
|
|
11
|
+
*
|
|
12
|
+
* Enforcement note (AC-49 / AC-44): only `mode === 'blocking'` adapters convert a
|
|
13
|
+
* deny into a swallowed tool event (spawn-runtime-hooks.ts). For non-blocking
|
|
14
|
+
* (advisory) adapters GATE 1 / GATE 3 are the enforcing gates — GATE 2 is
|
|
15
|
+
* defense-in-depth, never the sole line. This handler always RETURNS the correct
|
|
16
|
+
* decision; whether it hard-enforces is the runtime's mode decision.
|
|
17
|
+
*
|
|
18
|
+
* OVERRIDING RULE: fail closed. Any verification / parse / binding error, or any
|
|
19
|
+
* thrown exception, is a `{ decision: 'deny' }`. No fallbacks.
|
|
20
|
+
*/
|
|
21
|
+
import { verifyCommandAuthorization, argsHash as computeArgsHash, commandHash as computeCommandHash, } from '@a5c-ai/policy-adapter';
|
|
22
|
+
const deny = (reason) => ({ decision: 'deny', reason });
|
|
23
|
+
const allow = () => ({ decision: 'allow' });
|
|
24
|
+
/** Extract the command STRING for command-bearing tools (`{ command: "..." }`). */
|
|
25
|
+
function commandStringOf(input) {
|
|
26
|
+
if (input && typeof input === 'object') {
|
|
27
|
+
const cmd = input.command;
|
|
28
|
+
if (typeof cmd === 'string')
|
|
29
|
+
return cmd;
|
|
30
|
+
}
|
|
31
|
+
return '';
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build a GATE-2 preToolUse policy handler (AC-23b). For a covered call the handler
|
|
35
|
+
* REQUIRES a valid CommandAuthorization bound to the exact toolCallId / argsHash /
|
|
36
|
+
* commandHash / credentialScope in the payload; otherwise it denies (fail closed).
|
|
37
|
+
*/
|
|
38
|
+
export function createPolicyPreToolUseHook(options) {
|
|
39
|
+
return function policyPreToolUse(payload, _context) {
|
|
40
|
+
try {
|
|
41
|
+
if (!payload || typeof payload !== 'object') {
|
|
42
|
+
return deny('missing preToolUse payload');
|
|
43
|
+
}
|
|
44
|
+
const covered = options.isCovered(payload) === true;
|
|
45
|
+
if (!covered) {
|
|
46
|
+
// Uncovered actions are handled by GATE 1's coverage/default logic; GATE 2
|
|
47
|
+
// does not re-derive default-allow — it only enforces covered actions.
|
|
48
|
+
return allow();
|
|
49
|
+
}
|
|
50
|
+
const authorization = options.resolveAuthorization(payload);
|
|
51
|
+
if (!authorization) {
|
|
52
|
+
return deny('covered action has no CommandAuthorization — deny');
|
|
53
|
+
}
|
|
54
|
+
const credentialScope = options.credentialScopeFor(payload) ?? '';
|
|
55
|
+
const commandString = commandStringOf(payload.input);
|
|
56
|
+
const commandHash = computeCommandHash(commandString);
|
|
57
|
+
const argsHash = computeArgsHash(payload.input);
|
|
58
|
+
const verification = verifyCommandAuthorization(authorization, {
|
|
59
|
+
now: Date.now(),
|
|
60
|
+
toolName: payload.toolName,
|
|
61
|
+
toolCallId: payload.toolCallId,
|
|
62
|
+
commandHash,
|
|
63
|
+
argsHash,
|
|
64
|
+
credentialScope,
|
|
65
|
+
policyDocHash: options.policyDocHash,
|
|
66
|
+
currentConfigEpoch: options.currentConfigEpoch,
|
|
67
|
+
minEpochFloor: options.minEpochFloor,
|
|
68
|
+
issuerRoots: options.issuerRoots,
|
|
69
|
+
});
|
|
70
|
+
if (!verification.valid) {
|
|
71
|
+
return deny(`authorization verification failed: ${verification.reason}`);
|
|
72
|
+
}
|
|
73
|
+
return allow();
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
return deny(`exception during GATE 2 verification: ${err?.message ?? String(err)}`);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=policy-pretooluse-hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-pretooluse-hook.js","sourceRoot":"","sources":["../src/policy-pretooluse-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EACL,0BAA0B,EAC1B,QAAQ,IAAI,eAAe,EAC3B,WAAW,IAAI,kBAAkB,GAGlC,MAAM,wBAAwB,CAAC;AAmChC,MAAM,IAAI,GAAG,CAAC,MAAc,EAAgB,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAC9E,MAAM,KAAK,GAAG,GAAiB,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;AAE1D,mFAAmF;AACnF,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,GAAG,GAAI,KAAiC,CAAC,OAAO,CAAC;QACvD,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,GAAG,CAAC;IAC1C,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAA0C;IAE1C,OAAO,SAAS,gBAAgB,CAC9B,OAAgC,EAChC,QAAqB;QAErB,IAAI,CAAC;YACH,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC5C,OAAO,IAAI,CAAC,4BAA4B,CAAC,CAAC;YAC5C,CAAC;YAED,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;YACpD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,2EAA2E;gBAC3E,uEAAuE;gBACvE,OAAO,KAAK,EAAE,CAAC;YACjB,CAAC;YAED,MAAM,aAAa,GAAG,OAAO,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;YAC5D,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,OAAO,IAAI,CAAC,mDAAmD,CAAC,CAAC;YACnE,CAAC;YAED,MAAM,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClE,MAAM,aAAa,GAAG,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACrD,MAAM,WAAW,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;YACtD,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAEhD,MAAM,YAAY,GAAG,0BAA0B,CAAC,aAAa,EAAE;gBAC7D,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;gBACf,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,WAAW;gBACX,QAAQ;gBACR,eAAe;gBACf,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;gBAC9C,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,WAAW,EAAE,OAAO,CAAC,WAAW;aACjC,CAAC,CAAC;YAEH,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;gBACxB,OAAO,IAAI,CAAC,sCAAsC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3E,CAAC;YACD,OAAO,KAAK,EAAE,CAAC;QACjB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,yCAA0C,GAAa,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Milestone D — PRODUCTION wiring of GATE 3 (§9.3 / AC-23a / AC-40 / AC-50) into the
|
|
3
|
+
* adapters spawn path (`spawn-runner.ts` → `buildInvocationCommand`).
|
|
4
|
+
*
|
|
5
|
+
* GATE 3's PRIMITIVE (`gateCredentialInjection` + `applyGate3ToEnv/Mounts/ServiceAccount`)
|
|
6
|
+
* was shipped and fail-closed, but `spawn-runner.ts` called `buildInvocationCommand` with
|
|
7
|
+
* only 3 args, so `gate3` was `undefined` and every credential channel emitted
|
|
8
|
+
* unconditionally. This module resolves a `Gate3Options` from the SAME manifest-verified
|
|
9
|
+
* config that drives GATE 1 / the session gate (via `loadPolicyEnforcementGate`), so the
|
|
10
|
+
* production spawn path actually gates scoped-credential delivery.
|
|
11
|
+
*
|
|
12
|
+
* POSTURE (mirrors resolveRunPolicyGates):
|
|
13
|
+
* - Anchor pinned (`POLICY_CONFIG_ROOT_FP` set) → a Gate3Context is resolved from the
|
|
14
|
+
* verified config; a scoped credential with no valid CommandAuthorization is DROPPED
|
|
15
|
+
* (channel omitted) and, if required, the spawn is denied.
|
|
16
|
+
* - Anchor NOT pinned, OR no scoped credentials declared for this spawn → `undefined`;
|
|
17
|
+
* `buildInvocationCommand` runs with no gate (back-compat, channels emit as before).
|
|
18
|
+
*
|
|
19
|
+
* FAIL CLOSED: with the anchor pinned but the adapter unloadable / config untrusted, the
|
|
20
|
+
* resolved context has NO issuer roots, so every scoped credential fails authorization and
|
|
21
|
+
* is dropped (required → denied). No fallbacks — any thrown error yields no injection.
|
|
22
|
+
*/
|
|
23
|
+
import type { Gate3Options } from './spawn-invocation.js';
|
|
24
|
+
/** Per-spawn declaration of which delivery-channel credentials are SCOPED (from AC-40 source). */
|
|
25
|
+
export interface SpawnScopedCredentials {
|
|
26
|
+
/** env-var key → trusted alias (ARN/key-id/secret-name) + required flag. */
|
|
27
|
+
scopedEnvKeys?: Record<string, {
|
|
28
|
+
alias: string;
|
|
29
|
+
required?: boolean;
|
|
30
|
+
}>;
|
|
31
|
+
/** docker `-v` mount spec → trusted alias + required flag (AC-50). */
|
|
32
|
+
scopedMounts?: Record<string, {
|
|
33
|
+
alias: string;
|
|
34
|
+
required?: boolean;
|
|
35
|
+
}>;
|
|
36
|
+
/** k8s `--serviceaccount` name → trusted alias + required flag (AC-50). */
|
|
37
|
+
scopedServiceAccount?: {
|
|
38
|
+
name: string;
|
|
39
|
+
alias: string;
|
|
40
|
+
required?: boolean;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** The per-spawn binding context GATE 3 recomputes the authorization hash against (AC-32). */
|
|
44
|
+
export interface SpawnGateBinding {
|
|
45
|
+
toolName: string;
|
|
46
|
+
toolCallId: string;
|
|
47
|
+
/** The exact command about to be spawned. */
|
|
48
|
+
command: string;
|
|
49
|
+
/** The exact args about to be spawned. */
|
|
50
|
+
args: unknown;
|
|
51
|
+
/** Resolve the CommandAuthorization for this spawn (or none → drop scoped creds). */
|
|
52
|
+
resolveAuthorization: () => unknown;
|
|
53
|
+
}
|
|
54
|
+
/** Test-only: clear the memo so a test can re-resolve with a fresh env. */
|
|
55
|
+
export declare function __resetSpawnGateCache(): void;
|
|
56
|
+
/**
|
|
57
|
+
* Build a `Gate3Options` for a spawn, or `undefined` when GATE 3 should not gate this
|
|
58
|
+
* spawn (anchor unpinned, or no scoped credentials declared). When the anchor is pinned and
|
|
59
|
+
* this spawn declares scoped credentials, the returned options make `buildInvocationCommand`
|
|
60
|
+
* gate every credential channel it constructs against a valid CommandAuthorization.
|
|
61
|
+
*/
|
|
62
|
+
export declare function resolveSpawnGate3(projectRoot: string, scoped: SpawnScopedCredentials, binding: SpawnGateBinding): Promise<Gate3Options | undefined>;
|
|
63
|
+
/**
|
|
64
|
+
* Milestone E — AUTO-ACTIVATE GATE 3 from the SIGNED config (§9.3 / AC-23a / AC-40 / AC-50).
|
|
65
|
+
*
|
|
66
|
+
* The scoped-credential DECLARATION (which env keys / mounts / serviceaccount are scoped, and
|
|
67
|
+
* to which trusted alias) is DEPLOYMENT CONFIGURATION, not agent-writable input. It lives in
|
|
68
|
+
* the manifest-verified `credential-scope-source.json` (`scopedCredentials`), so a real spawn
|
|
69
|
+
* is gated end-to-end WITHOUT a caller passing `RunOptions.policyGate3` and WITHOUT the agent
|
|
70
|
+
* being able to declare its own scoping.
|
|
71
|
+
*
|
|
72
|
+
* When the anchor is pinned AND the signed source declares scoped credentials, this returns a
|
|
73
|
+
* `Gate3Options` built from the SAME manifest-verified config that drives GATE 1 / the session
|
|
74
|
+
* gate. When the anchor is unpinned, or the signed source declares no scoped credentials, this
|
|
75
|
+
* returns `undefined` (GATE 3 gates only what a caller explicitly declared, back-compat).
|
|
76
|
+
*
|
|
77
|
+
* `resolveAuthorization` is the run's authorization-store resolver (the ALLOW path); with none,
|
|
78
|
+
* a scoped credential fails authorization and its channel is dropped (fail closed).
|
|
79
|
+
*/
|
|
80
|
+
export declare function resolveSpawnGate3FromConfig(projectRoot: string, binding: Omit<SpawnGateBinding, 'resolveAuthorization'> & {
|
|
81
|
+
resolveAuthorization?: () => unknown;
|
|
82
|
+
}): Promise<Gate3Options | undefined>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-spawn-gate.d.ts","sourceRoot":"","sources":["../src/policy-spawn-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,kGAAkG;AAClG,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACtE,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACrE,2EAA2E;IAC3E,oBAAoB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC5E;AAED,8FAA8F;AAC9F,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,IAAI,EAAE,OAAO,CAAC;IACd,qFAAqF;IACrF,oBAAoB,EAAE,MAAM,OAAO,CAAC;CACrC;AAqDD,2EAA2E;AAC3E,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CA4BnC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,sBAAsB,CAAC,GAAG;IACxD,oBAAoB,CAAC,EAAE,MAAM,OAAO,CAAC;CACtC,GACA,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAmBnC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// Memoize the resolved Gate3Context per project root so repeated spawns in one run do not
|
|
2
|
+
// re-verify the manifest.
|
|
3
|
+
const cache = new Map();
|
|
4
|
+
function anchorPinned() {
|
|
5
|
+
const v = process.env.POLICY_CONFIG_ROOT_FP;
|
|
6
|
+
return typeof v === 'string' && v.length > 0;
|
|
7
|
+
}
|
|
8
|
+
async function resolveGate3Context(projectRoot) {
|
|
9
|
+
const key = projectRoot;
|
|
10
|
+
const existing = cache.get(key);
|
|
11
|
+
if (existing)
|
|
12
|
+
return existing;
|
|
13
|
+
const built = (async () => {
|
|
14
|
+
try {
|
|
15
|
+
const mod = await import('@a5c-ai/policy-adapter');
|
|
16
|
+
const result = await mod.loadPolicyEnforcementGate(projectRoot);
|
|
17
|
+
if (result.enforcementActive !== true)
|
|
18
|
+
return undefined;
|
|
19
|
+
return result.gate3Context;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Anchor pinned but adapter unloadable → return a trust-empty context so scoped creds
|
|
23
|
+
// fail authorization (fail closed). Unpinned → undefined (no gating).
|
|
24
|
+
if (anchorPinned()) {
|
|
25
|
+
return {
|
|
26
|
+
issuerRoots: [],
|
|
27
|
+
currentConfigEpoch: 0,
|
|
28
|
+
minEpochFloor: Number(process.env.POLICY_CONFIG_MIN_EPOCH ?? '1') || 1,
|
|
29
|
+
policyDocHashFor: () => '',
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
})();
|
|
35
|
+
cache.set(key, built);
|
|
36
|
+
return built;
|
|
37
|
+
}
|
|
38
|
+
/** Test-only: clear the memo so a test can re-resolve with a fresh env. */
|
|
39
|
+
export function __resetSpawnGateCache() {
|
|
40
|
+
cache.clear();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build a `Gate3Options` for a spawn, or `undefined` when GATE 3 should not gate this
|
|
44
|
+
* spawn (anchor unpinned, or no scoped credentials declared). When the anchor is pinned and
|
|
45
|
+
* this spawn declares scoped credentials, the returned options make `buildInvocationCommand`
|
|
46
|
+
* gate every credential channel it constructs against a valid CommandAuthorization.
|
|
47
|
+
*/
|
|
48
|
+
export async function resolveSpawnGate3(projectRoot, scoped, binding) {
|
|
49
|
+
const hasScoped = (scoped.scopedEnvKeys && Object.keys(scoped.scopedEnvKeys).length > 0) ||
|
|
50
|
+
(scoped.scopedMounts && Object.keys(scoped.scopedMounts).length > 0) ||
|
|
51
|
+
scoped.scopedServiceAccount !== undefined;
|
|
52
|
+
// Nothing scoped for this spawn → no gate needed (env/mounts/SA pass through unchanged).
|
|
53
|
+
if (!hasScoped)
|
|
54
|
+
return undefined;
|
|
55
|
+
const ctx = await resolveGate3Context(projectRoot);
|
|
56
|
+
if (!ctx)
|
|
57
|
+
return undefined;
|
|
58
|
+
const credentialSource = ctx.credentialSource;
|
|
59
|
+
return {
|
|
60
|
+
issuerRoots: ctx.issuerRoots,
|
|
61
|
+
policyDocHash: ctx.policyDocHashFor(binding.toolName, binding.command),
|
|
62
|
+
currentConfigEpoch: ctx.currentConfigEpoch,
|
|
63
|
+
minEpochFloor: ctx.minEpochFloor,
|
|
64
|
+
now: Date.now(),
|
|
65
|
+
toolName: binding.toolName,
|
|
66
|
+
toolCallId: binding.toolCallId,
|
|
67
|
+
command: binding.command,
|
|
68
|
+
args: binding.args,
|
|
69
|
+
credentialSource,
|
|
70
|
+
resolveAuthorization: binding.resolveAuthorization,
|
|
71
|
+
scopedEnvKeys: scoped.scopedEnvKeys ?? {},
|
|
72
|
+
...(scoped.scopedMounts ? { scopedMounts: scoped.scopedMounts } : {}),
|
|
73
|
+
...(scoped.scopedServiceAccount ? { scopedServiceAccount: scoped.scopedServiceAccount } : {}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Milestone E — AUTO-ACTIVATE GATE 3 from the SIGNED config (§9.3 / AC-23a / AC-40 / AC-50).
|
|
78
|
+
*
|
|
79
|
+
* The scoped-credential DECLARATION (which env keys / mounts / serviceaccount are scoped, and
|
|
80
|
+
* to which trusted alias) is DEPLOYMENT CONFIGURATION, not agent-writable input. It lives in
|
|
81
|
+
* the manifest-verified `credential-scope-source.json` (`scopedCredentials`), so a real spawn
|
|
82
|
+
* is gated end-to-end WITHOUT a caller passing `RunOptions.policyGate3` and WITHOUT the agent
|
|
83
|
+
* being able to declare its own scoping.
|
|
84
|
+
*
|
|
85
|
+
* When the anchor is pinned AND the signed source declares scoped credentials, this returns a
|
|
86
|
+
* `Gate3Options` built from the SAME manifest-verified config that drives GATE 1 / the session
|
|
87
|
+
* gate. When the anchor is unpinned, or the signed source declares no scoped credentials, this
|
|
88
|
+
* returns `undefined` (GATE 3 gates only what a caller explicitly declared, back-compat).
|
|
89
|
+
*
|
|
90
|
+
* `resolveAuthorization` is the run's authorization-store resolver (the ALLOW path); with none,
|
|
91
|
+
* a scoped credential fails authorization and its channel is dropped (fail closed).
|
|
92
|
+
*/
|
|
93
|
+
export async function resolveSpawnGate3FromConfig(projectRoot, binding) {
|
|
94
|
+
if (!anchorPinned())
|
|
95
|
+
return undefined;
|
|
96
|
+
const ctx = await resolveGate3Context(projectRoot);
|
|
97
|
+
if (!ctx)
|
|
98
|
+
return undefined;
|
|
99
|
+
const declared = ctx.credentialSource?.scopedCredentials;
|
|
100
|
+
if (!declared)
|
|
101
|
+
return undefined;
|
|
102
|
+
const scoped = {
|
|
103
|
+
...(declared.scopedEnvKeys ? { scopedEnvKeys: declared.scopedEnvKeys } : {}),
|
|
104
|
+
...(declared.scopedMounts ? { scopedMounts: declared.scopedMounts } : {}),
|
|
105
|
+
...(declared.scopedServiceAccount ? { scopedServiceAccount: declared.scopedServiceAccount } : {}),
|
|
106
|
+
};
|
|
107
|
+
return resolveSpawnGate3(projectRoot, scoped, {
|
|
108
|
+
toolName: binding.toolName,
|
|
109
|
+
toolCallId: binding.toolCallId,
|
|
110
|
+
command: binding.command,
|
|
111
|
+
args: binding.args,
|
|
112
|
+
resolveAuthorization: binding.resolveAuthorization ?? (() => undefined),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=policy-spawn-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-spawn-gate.js","sourceRoot":"","sources":["../src/policy-spawn-gate.ts"],"names":[],"mappings":"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"}
|
package/dist/run-options.d.ts
CHANGED
|
@@ -101,6 +101,46 @@ export interface RunOptions {
|
|
|
101
101
|
gracePeriodMs?: number;
|
|
102
102
|
/** Invocation mode — how to spawn the underlying process (local, docker, ssh, k8s). */
|
|
103
103
|
invocation?: InvocationMode;
|
|
104
|
+
/**
|
|
105
|
+
* Milestone D (§9.3 / AC-23a / AC-50) — GATE 3 credential-injection enforcement for the
|
|
106
|
+
* spawn path. When set AND the off-workspace config anchor (`POLICY_CONFIG_ROOT_FP`) is
|
|
107
|
+
* pinned, each declared scoped credential (env / docker `-v` / k8s serviceaccount) is
|
|
108
|
+
* delivered ONLY with a valid CommandAuthorization; otherwise the channel is omitted (and
|
|
109
|
+
* if required, the spawn is denied). When unset the spawn path is unchanged (back-compat).
|
|
110
|
+
*/
|
|
111
|
+
policyGate3?: {
|
|
112
|
+
/** The project root anchoring the `.policy` config dir (defaults to `cwd`). */
|
|
113
|
+
projectRoot?: string;
|
|
114
|
+
/** env-var key → trusted alias (ARN/key-id/secret-name) + required flag (AC-40). */
|
|
115
|
+
scopedEnvKeys?: Record<string, {
|
|
116
|
+
alias: string;
|
|
117
|
+
required?: boolean;
|
|
118
|
+
}>;
|
|
119
|
+
/** docker `-v` mount spec → trusted alias + required flag (AC-50). */
|
|
120
|
+
scopedMounts?: Record<string, {
|
|
121
|
+
alias: string;
|
|
122
|
+
required?: boolean;
|
|
123
|
+
}>;
|
|
124
|
+
/** k8s `--serviceaccount` name → trusted alias + required flag (AC-50). */
|
|
125
|
+
scopedServiceAccount?: {
|
|
126
|
+
name: string;
|
|
127
|
+
alias: string;
|
|
128
|
+
required?: boolean;
|
|
129
|
+
};
|
|
130
|
+
/** The bound tool identity for the authorization recheck (AC-32). */
|
|
131
|
+
toolName?: string;
|
|
132
|
+
toolCallId?: string;
|
|
133
|
+
/** Resolve the CommandAuthorization for this spawn (or none → drop scoped creds). */
|
|
134
|
+
resolveAuthorization?: () => unknown;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Milestone E (ALLOW path, §5 / AC-9 / AC-50) — the run's authorization-store resolver,
|
|
138
|
+
* threaded into GATE 3 when it AUTO-ACTIVATES from the signed credential-scope source (i.e.
|
|
139
|
+
* when the anchor is pinned and the signed source declares scoped credentials, without an
|
|
140
|
+
* explicit `policyGate3`). With none, an auto-gated scoped credential fails authorization and
|
|
141
|
+
* its channel is dropped (fail closed). Ignored when `policyGate3.resolveAuthorization` is set.
|
|
142
|
+
*/
|
|
143
|
+
policyResolveAuthorization?: () => unknown;
|
|
104
144
|
/** Provider configuration for model/provider selection. */
|
|
105
145
|
providerConfig?: import('./provider-config.js').ProviderConfig;
|
|
106
146
|
/** Named provider profile from ~/.adapters/providers.json. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-options.d.ts","sourceRoot":"","sources":["../src/run-options.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"run-options.d.ts","sourceRoot":"","sources":["../src/run-options.ts"],"names":[],"mappings":"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"}
|