@guilz-dev/belay 0.6.0 → 0.8.0
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/README.md +39 -20
- package/dist/adapters/claude/runtime-entry.js +54 -25
- package/dist/adapters/shared/gate-runtime.d.ts +7 -0
- package/dist/adapters/shared/gate-runtime.js +443 -225
- package/dist/bundle/claude-runtime.mjs +13027 -7271
- package/dist/bundle/codex-runtime.mjs +12700 -6977
- package/dist/bundle/cursor-runtime.mjs +12695 -6977
- package/dist/cli.js +37 -1
- package/dist/commands/approve.js +34 -10
- package/dist/commands/doctor.js +58 -0
- package/dist/commands/dogfood.js +1 -1
- package/dist/commands/explain.js +2 -2
- package/dist/commands/harvest.d.ts +0 -1
- package/dist/commands/harvest.js +1 -4
- package/dist/commands/metrics.js +6 -0
- package/dist/commands/quality.js +1 -3
- package/dist/commands/recovery-checkpoints.d.ts +164 -0
- package/dist/commands/recovery-checkpoints.js +347 -0
- package/dist/commands/revoke.js +19 -7
- package/dist/commands/status.js +7 -0
- package/dist/config-io.js +49 -18
- package/dist/conformance/guarantee-table.js +137 -9
- package/dist/conformance/types.d.ts +2 -0
- package/dist/core/approval-replay.d.ts +1 -1
- package/dist/core/approval-replay.js +4 -1
- package/dist/core/approval-service.d.ts +6 -1
- package/dist/core/approval-service.js +86 -27
- package/dist/core/approval.d.ts +2 -0
- package/dist/core/approval.js +6 -3
- package/dist/core/audit-metrics.d.ts +1 -0
- package/dist/core/audit-metrics.js +12 -4
- package/dist/core/audit-types.d.ts +16 -0
- package/dist/core/capability/approval-state-mutation.d.ts +19 -0
- package/dist/core/capability/approval-state-mutation.js +76 -3
- package/dist/core/capability/approval-v3.d.ts +18 -1
- package/dist/core/capability/approval-v3.js +63 -23
- package/dist/core/capability/attestation.d.ts +3 -0
- package/dist/core/capability/attestation.js +7 -0
- package/dist/core/capability/boundary-driver-container.d.ts +12 -0
- package/dist/core/capability/boundary-driver-container.js +101 -34
- package/dist/core/capability/boundary-driver.js +1 -0
- package/dist/core/capability/boundary-grant-materialize.d.ts +1 -0
- package/dist/core/capability/boundary-grant-materialize.js +15 -0
- package/dist/core/capability/boundary-run.d.ts +25 -0
- package/dist/core/capability/boundary-run.js +37 -9
- package/dist/core/capability/boundary-session.d.ts +4 -0
- package/dist/core/capability/boundary-session.js +9 -0
- package/dist/core/capability/boundary-workspace-mount.d.ts +5 -0
- package/dist/core/capability/boundary-workspace-mount.js +68 -0
- package/dist/core/capability/gate-policy-shadow.js +23 -1
- package/dist/core/capability/grant-consumption.d.ts +4 -0
- package/dist/core/capability/grant-consumption.js +11 -0
- package/dist/core/capability/grant-lease.d.ts +36 -1
- package/dist/core/capability/grant-lease.js +213 -16
- package/dist/core/capability/grant-match.js +3 -0
- package/dist/core/capability/index.d.ts +2 -2
- package/dist/core/capability/index.js +1 -1
- package/dist/core/capability/policy-engine.d.ts +38 -1
- package/dist/core/capability/policy-engine.js +388 -15
- package/dist/core/capability/request.d.ts +12 -0
- package/dist/core/capability/resolver.d.ts +0 -1
- package/dist/core/capability/resolver.js +0 -1
- package/dist/core/config.d.ts +20 -0
- package/dist/core/config.js +62 -2
- package/dist/core/effect-ir/audit.d.ts +9 -0
- package/dist/core/effect-ir/audit.js +87 -0
- package/dist/core/effect-ir/build.d.ts +31 -0
- package/dist/core/effect-ir/build.js +281 -0
- package/dist/core/effect-ir/index.d.ts +13 -0
- package/dist/core/effect-ir/index.js +9 -0
- package/dist/core/effect-ir/normalize.d.ts +4 -0
- package/dist/core/effect-ir/normalize.js +110 -0
- package/dist/core/effect-ir/package-exec-eval.d.ts +8 -0
- package/dist/core/effect-ir/package-exec-eval.js +152 -0
- package/dist/core/effect-ir/package-exec.d.ts +29 -0
- package/dist/core/effect-ir/package-exec.js +292 -0
- package/dist/core/effect-ir/policy.d.ts +14 -0
- package/dist/core/effect-ir/policy.js +164 -0
- package/dist/core/effect-ir/shell-build.d.ts +43 -0
- package/dist/core/effect-ir/shell-build.js +77 -0
- package/dist/core/effect-ir/shell-lower.d.ts +14 -0
- package/dist/core/effect-ir/shell-lower.js +1509 -0
- package/dist/core/effect-ir/types.d.ts +62 -0
- package/dist/core/effect-ir/types.js +1 -0
- package/dist/core/egress/allowlist.d.ts +1 -0
- package/dist/core/egress/allowlist.js +8 -0
- package/dist/core/egress-approval.js +45 -51
- package/dist/core/gate-contract.d.ts +2 -0
- package/dist/core/gate-contract.js +2 -0
- package/dist/core/gate-engine.js +82 -25
- package/dist/core/git-resource-identity.d.ts +26 -0
- package/dist/core/git-resource-identity.js +284 -0
- package/dist/core/harvest.d.ts +3 -7
- package/dist/core/harvest.js +4 -27
- package/dist/core/index.d.ts +5 -1
- package/dist/core/index.js +3 -1
- package/dist/core/judge-cloud-consent.js +29 -15
- package/dist/core/network-endpoint.d.ts +10 -0
- package/dist/core/network-endpoint.js +51 -0
- package/dist/core/path-utils.js +42 -23
- package/dist/core/process-runner.d.ts +10 -0
- package/dist/core/process-runner.js +124 -0
- package/dist/core/recover-advice.js +2 -1
- package/dist/core/recovery/artifact-store.d.ts +29 -0
- package/dist/core/recovery/artifact-store.js +336 -0
- package/dist/core/recovery/checkpoint.d.ts +25 -0
- package/dist/core/recovery/checkpoint.js +260 -0
- package/dist/core/recovery/index.d.ts +3 -1
- package/dist/core/recovery/index.js +2 -0
- package/dist/core/recovery/operator-guidance.d.ts +7 -0
- package/dist/core/recovery/operator-guidance.js +39 -0
- package/dist/core/recovery/reconcile.d.ts +3 -0
- package/dist/core/recovery/reconcile.js +48 -0
- package/dist/core/recovery/resource-identity.d.ts +4 -0
- package/dist/core/recovery/resource-identity.js +34 -0
- package/dist/core/recovery/restore.d.ts +13 -0
- package/dist/core/recovery/restore.js +114 -0
- package/dist/core/recovery/snapshot-node.d.ts +27 -0
- package/dist/core/recovery/snapshot-node.js +261 -0
- package/dist/core/recovery/types.d.ts +85 -1
- package/dist/core/shell-substitution.d.ts +1 -0
- package/dist/core/shell-substitution.js +61 -0
- package/dist/core/standing-allow.d.ts +1 -2
- package/dist/core/standing-allow.js +3 -20
- package/dist/core/transactional/apply-observed-changes.d.ts +13 -0
- package/dist/core/transactional/apply-observed-changes.js +275 -0
- package/dist/core/transactional/backend-selector.d.ts +8 -0
- package/dist/core/transactional/backend-selector.js +118 -0
- package/dist/core/transactional/backend.d.ts +55 -0
- package/dist/core/transactional/backend.js +1 -0
- package/dist/core/transactional/file-checkpoint-backend.d.ts +3 -0
- package/dist/core/transactional/file-checkpoint-backend.js +278 -0
- package/dist/core/transactional/file-checkpoint-git.d.ts +11 -0
- package/dist/core/transactional/file-checkpoint-git.js +217 -0
- package/dist/core/transactional/file-checkpoint-staging.d.ts +13 -0
- package/dist/core/transactional/file-checkpoint-staging.js +54 -0
- package/dist/core/transactional/file-clone.d.ts +15 -0
- package/dist/core/transactional/file-clone.js +139 -0
- package/dist/core/transactional/file-tree-path.d.ts +7 -0
- package/dist/core/transactional/file-tree-path.js +50 -0
- package/dist/core/transactional/file-tree.d.ts +41 -0
- package/dist/core/transactional/file-tree.js +186 -0
- package/dist/core/transactional/git-worktree-backend.d.ts +2 -0
- package/dist/core/transactional/git-worktree-backend.js +50 -0
- package/dist/core/transactional/git-worktree.d.ts +9 -11
- package/dist/core/transactional/git-worktree.js +24 -119
- package/dist/core/transactional/index.d.ts +11 -0
- package/dist/core/transactional/index.js +10 -0
- package/dist/core/transactional/reasons.js +1 -0
- package/dist/core/transactional/runner.js +157 -25
- package/dist/core/transactional/snapshot-node.d.ts +26 -0
- package/dist/core/transactional/snapshot-node.js +87 -0
- package/dist/core/transactional/types.d.ts +17 -1
- package/dist/core/types.d.ts +13 -1
- package/dist/core/verdict/adapter.js +23 -15
- package/dist/core/verdict/containment.js +4 -0
- package/dist/core/verdict/egress-classify.d.ts +12 -0
- package/dist/core/verdict/egress-classify.js +746 -0
- package/dist/core/verdict/git-classifier.d.ts +12 -0
- package/dist/core/verdict/git-classifier.js +320 -0
- package/dist/core/verdict/launcher-resolve.js +79 -37
- package/dist/core/verdict/parser.d.ts +2 -0
- package/dist/core/verdict/parser.js +95 -1
- package/dist/core/verdict/types.d.ts +6 -2
- package/dist/core/verdict/verdict.js +103 -935
- package/dist/corpus/must-allow-commands.d.ts +2 -1
- package/dist/corpus/must-allow-commands.js +2 -1
- package/dist/corpus/runtime-match.d.ts +2 -1
- package/dist/corpus/runtime-match.js +2 -1
- package/dist/corpus/types.d.ts +2 -2
- package/dist/templates.js +7 -2
- package/dist/types.d.ts +11 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/skills/belay/SKILL.md +8 -3
- package/skills/belay/belay-approve.md +10 -7
- package/dist/core/verdict/overrides.d.ts +0 -7
- package/dist/core/verdict/overrides.js +0 -37
- package/dist/core/verdict/shell-policy.d.ts +0 -25
- package/dist/core/verdict/shell-policy.js +0 -40
- package/dist/corpus/standing-allow-catalog.generated.d.ts +0 -13
- package/dist/corpus/standing-allow-catalog.generated.js +0 -99
|
@@ -51,6 +51,9 @@ export function hostIntegrationBoundaryContext(repoRoot) {
|
|
|
51
51
|
egressProxyActive: false,
|
|
52
52
|
proxyEnv: {},
|
|
53
53
|
},
|
|
54
|
+
attestationPath: '',
|
|
55
|
+
attestation: null,
|
|
56
|
+
attestationFresh: false,
|
|
54
57
|
};
|
|
55
58
|
}
|
|
56
59
|
export async function resolveBoundaryDriverContext(params) {
|
|
@@ -74,6 +77,8 @@ export async function resolveBoundaryDriverContext(params) {
|
|
|
74
77
|
egressProxyEnv: proxyEnv,
|
|
75
78
|
repoRoot: params.repoRoot,
|
|
76
79
|
});
|
|
80
|
+
const attestationPath = boundaryAttestationPath(params.repoRoot, params.config);
|
|
81
|
+
const attestation = await loadBoundaryAttestation(attestationPath, params.repoRoot, configuredControlPlaneDir(params.config));
|
|
77
82
|
return {
|
|
78
83
|
driver,
|
|
79
84
|
driverId,
|
|
@@ -84,6 +89,9 @@ export async function resolveBoundaryDriverContext(params) {
|
|
|
84
89
|
egressProxyActive: proxyActive,
|
|
85
90
|
proxyEnv,
|
|
86
91
|
},
|
|
92
|
+
attestationPath,
|
|
93
|
+
attestation,
|
|
94
|
+
attestationFresh: attestation ? isAttestationFresh(attestation) : false,
|
|
87
95
|
};
|
|
88
96
|
}
|
|
89
97
|
export async function runWithBoundaryDriver(params) {
|
|
@@ -124,6 +132,7 @@ export async function runBoundaryAgentCommand(params) {
|
|
|
124
132
|
command: params.command,
|
|
125
133
|
cwd: params.cwd ?? params.repoRoot,
|
|
126
134
|
timeoutMs: params.timeoutMs ?? 30 * 60_000,
|
|
135
|
+
runOptions: params.runOptions,
|
|
127
136
|
});
|
|
128
137
|
}
|
|
129
138
|
export { dockerNetworkArgs };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { BoundaryWorkspaceMount } from './boundary-run.js';
|
|
2
|
+
export declare function validateWorkspaceMount(mount: BoundaryWorkspaceMount): void;
|
|
3
|
+
export declare function resolveGuestWorkdir(mount: BoundaryWorkspaceMount): string;
|
|
4
|
+
export declare function buildWorkspaceMountSpec(mount: BoundaryWorkspaceMount): string;
|
|
5
|
+
export declare function workspaceMountEnvArgs(mount: BoundaryWorkspaceMount): string[];
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { canonicalPath, pathWithinRoot } from '../path-utils.js';
|
|
3
|
+
const HOST_PATH_ENV_VARS = [
|
|
4
|
+
'BELAY_EGRESS_REPO_ROOT',
|
|
5
|
+
'BELAY_JUDGE_BROKER_REPO_ROOT',
|
|
6
|
+
'BELAY_JUDGE_BROKER_STATE_DIR',
|
|
7
|
+
'BELAY_REPO_ROOT',
|
|
8
|
+
];
|
|
9
|
+
export function validateWorkspaceMount(mount) {
|
|
10
|
+
const hostSourceRoot = canonicalPath(mount.hostSourceRoot);
|
|
11
|
+
const guestTargetRoot = canonicalPath(mount.guestTargetRoot);
|
|
12
|
+
if (!hostSourceRoot || !guestTargetRoot) {
|
|
13
|
+
throw new Error('boundary_workspace_mount_invalid_root');
|
|
14
|
+
}
|
|
15
|
+
if (hostSourceRoot.includes(',') || guestTargetRoot.includes(',')) {
|
|
16
|
+
throw new Error('boundary_workspace_mount_invalid_root');
|
|
17
|
+
}
|
|
18
|
+
if (hostSourceRoot === guestTargetRoot) {
|
|
19
|
+
throw new Error('boundary_workspace_mount_source_equals_target');
|
|
20
|
+
}
|
|
21
|
+
if (pathWithinRoot(hostSourceRoot, guestTargetRoot)) {
|
|
22
|
+
throw new Error('boundary_workspace_mount_source_contains_target');
|
|
23
|
+
}
|
|
24
|
+
if (mount.cwdRelative.includes('\0')) {
|
|
25
|
+
throw new Error('boundary_workspace_mount_invalid_cwd');
|
|
26
|
+
}
|
|
27
|
+
const normalizedRelative = path.posix.normalize(mount.cwdRelative.replace(/\\/g, '/'));
|
|
28
|
+
if (normalizedRelative === '..' || normalizedRelative.startsWith('../')) {
|
|
29
|
+
throw new Error('boundary_workspace_mount_invalid_cwd');
|
|
30
|
+
}
|
|
31
|
+
if (path.posix.isAbsolute(normalizedRelative)) {
|
|
32
|
+
throw new Error('boundary_workspace_mount_invalid_cwd');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export function resolveGuestWorkdir(mount) {
|
|
36
|
+
validateWorkspaceMount(mount);
|
|
37
|
+
const guestTargetRoot = canonicalPath(mount.guestTargetRoot);
|
|
38
|
+
const normalizedRelative = path.posix.normalize(mount.cwdRelative.replace(/\\/g, '/'));
|
|
39
|
+
if (normalizedRelative === '.' || normalizedRelative === '') {
|
|
40
|
+
return guestTargetRoot;
|
|
41
|
+
}
|
|
42
|
+
const segments = normalizedRelative.split('/').filter(Boolean);
|
|
43
|
+
return path.posix.join(guestTargetRoot, ...segments);
|
|
44
|
+
}
|
|
45
|
+
export function buildWorkspaceMountSpec(mount) {
|
|
46
|
+
validateWorkspaceMount(mount);
|
|
47
|
+
const hostSourceRoot = canonicalPath(mount.hostSourceRoot);
|
|
48
|
+
const guestTargetRoot = canonicalPath(mount.guestTargetRoot);
|
|
49
|
+
const readonly = mount.writable ? '' : ',readonly';
|
|
50
|
+
return `type=bind,src=${hostSourceRoot},dst=${guestTargetRoot}${readonly}`;
|
|
51
|
+
}
|
|
52
|
+
export function workspaceMountEnvArgs(mount) {
|
|
53
|
+
const workdir = resolveGuestWorkdir(mount);
|
|
54
|
+
if (!mount.hideHostSourcePath) {
|
|
55
|
+
return ['-e', `PWD=${workdir}`];
|
|
56
|
+
}
|
|
57
|
+
const guestTargetRoot = canonicalPath(mount.guestTargetRoot);
|
|
58
|
+
const hostSourceRoot = canonicalPath(mount.hostSourceRoot);
|
|
59
|
+
const args = [];
|
|
60
|
+
for (const key of HOST_PATH_ENV_VARS) {
|
|
61
|
+
args.push('-e', `${key}=`);
|
|
62
|
+
}
|
|
63
|
+
args.push('-e', `PWD=${workdir}`, '-e', `OLDPWD=${workdir}`, '-e', `BELAY_REPO_ROOT=${guestTargetRoot}`);
|
|
64
|
+
if (hostSourceRoot !== guestTargetRoot) {
|
|
65
|
+
args.push('-e', `BELAY_EGRESS_REPO_ROOT=${guestTargetRoot}`);
|
|
66
|
+
}
|
|
67
|
+
return args;
|
|
68
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { belayStateDir } from '../config.js';
|
|
3
|
+
import { effectPlanAuditFields } from '../effect-ir/audit.js';
|
|
3
4
|
import { buildTier1Prompt } from '../verdict/judge.js';
|
|
4
5
|
import { normalizeJudgeRuntimeConfig } from '../verdict/judge-runtime-config.js';
|
|
5
6
|
import { judgeShadowAuditFields, recordShadowComparison, shouldRunShadowComparison, triggerJudgeSessionKillSwitch, } from '../verdict/judge-shadow.js';
|
|
@@ -7,7 +8,16 @@ import { evaluateWithJudgeTransport } from '../verdict/judge-transport.js';
|
|
|
7
8
|
import { recordPolicyJudgeComparison } from './gate-shadow-ratchet.js';
|
|
8
9
|
export { recordGateApprovalAsk } from './gate-shadow-ratchet.js';
|
|
9
10
|
export function capabilityDecisionAuditFields(result) {
|
|
10
|
-
const fields = {
|
|
11
|
+
const fields = {
|
|
12
|
+
...effectPlanAuditFields(result.effectPlan, {
|
|
13
|
+
capabilityRequests: result.capabilityRequests,
|
|
14
|
+
decisions: result.effectPlanPolicyDecisions,
|
|
15
|
+
authorizationDecision: result.authorizationDecision,
|
|
16
|
+
}),
|
|
17
|
+
executionRoute: 'downstream_host',
|
|
18
|
+
enforcementStatus: 'prediction_only',
|
|
19
|
+
boundaryEnforcement: 'prediction_only',
|
|
20
|
+
};
|
|
11
21
|
if (result.capabilityRequests?.length) {
|
|
12
22
|
fields.capabilityRequestCount = result.capabilityRequests.length;
|
|
13
23
|
fields.capabilityActions = result.capabilityRequests.map((request) => request.action);
|
|
@@ -19,6 +29,18 @@ export function capabilityDecisionAuditFields(result) {
|
|
|
19
29
|
fields.policyMatchedRule = result.authorizationDecision.matchedRule;
|
|
20
30
|
}
|
|
21
31
|
}
|
|
32
|
+
const decisions = result.effectPlanPolicyDecisions ?? [];
|
|
33
|
+
if (decisions.length > 0 &&
|
|
34
|
+
decisions.every((decision) => decision.matchedRule === 'boundary.verified')) {
|
|
35
|
+
fields.authorizationMode = 'boundary_policy';
|
|
36
|
+
}
|
|
37
|
+
else if (decisions.length > 0 &&
|
|
38
|
+
decisions.every((decision) => decision.matchedRule === 'grant.exact')) {
|
|
39
|
+
fields.authorizationMode = 'exact_grant';
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
fields.authorizationMode = result.authorizationDecision ? 'policy_decision' : 'none';
|
|
43
|
+
}
|
|
22
44
|
if (result.boundaryProfile) {
|
|
23
45
|
fields.boundaryProfile = result.boundaryProfile;
|
|
24
46
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ClassifyResult } from '../types.js';
|
|
2
|
+
export declare function capabilityGrantLeaseRequired(result: Pick<ClassifyResult, 'reason' | 'authorizationDecision'>): boolean;
|
|
3
|
+
/** Fail closed when a grant lease is required but capability requests are missing. */
|
|
4
|
+
export declare function canConsumeCapabilityGrantLease(result: ClassifyResult): boolean;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function capabilityGrantLeaseRequired(result) {
|
|
2
|
+
return (result.reason === 'capability_grant' ||
|
|
3
|
+
result.authorizationDecision?.matchedRule === 'grant.exact');
|
|
4
|
+
}
|
|
5
|
+
/** Fail closed when a grant lease is required but capability requests are missing. */
|
|
6
|
+
export function canConsumeCapabilityGrantLease(result) {
|
|
7
|
+
if (!capabilityGrantLeaseRequired(result)) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
return (result.capabilityRequests?.length ?? 0) > 0;
|
|
11
|
+
}
|
|
@@ -1,9 +1,44 @@
|
|
|
1
|
-
import type { ApprovalStateFile } from '../types.js';
|
|
1
|
+
import type { ApprovalRecord, ApprovalStateFile } from '../types.js';
|
|
2
2
|
import type { CapabilityGrantV1 } from './grant.js';
|
|
3
3
|
import type { CapabilityRequestV1 } from './request.js';
|
|
4
|
+
export type GrantBundleValidationFailureReason = 'legacy_record' | 'empty_requests' | 'cardinality_mismatch' | 'grant_scope_too_broad' | 'grant_inactive' | 'grant_mismatch';
|
|
5
|
+
export type GrantBundleValidationResult = {
|
|
6
|
+
ok: true;
|
|
7
|
+
approval: ApprovalRecord;
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
reason: GrantBundleValidationFailureReason;
|
|
11
|
+
};
|
|
12
|
+
export declare function grantsFromApproval(approval: {
|
|
13
|
+
grant?: CapabilityGrantV1;
|
|
14
|
+
grants?: CapabilityGrantV1[];
|
|
15
|
+
}): CapabilityGrantV1[];
|
|
16
|
+
export declare function approvalGrantBundleExhausted(approval: {
|
|
17
|
+
grant?: CapabilityGrantV1;
|
|
18
|
+
grants?: CapabilityGrantV1[];
|
|
19
|
+
}): boolean;
|
|
20
|
+
export declare function consumeApprovalGrantBundle(approval: ApprovalRecord, requests: readonly CapabilityRequestV1[]): {
|
|
21
|
+
approval: ApprovalRecord;
|
|
22
|
+
consumed: boolean;
|
|
23
|
+
};
|
|
24
|
+
/** Validate and consume a marked exact bundle without mutating on any failure. */
|
|
25
|
+
export declare function validateAndConsumeGrantBundle(approval: ApprovalRecord, requests: readonly CapabilityRequestV1[], now?: number): GrantBundleValidationResult;
|
|
26
|
+
/** Revalidate a marked bundle during an active replay lease without consuming it twice. */
|
|
27
|
+
export declare function validateGrantBundleForLeaseReuse(approval: ApprovalRecord, requests: readonly CapabilityRequestV1[], now?: number): GrantBundleValidationResult;
|
|
28
|
+
/** Consume every grant in an approved record after fingerprint/hash replay validation. */
|
|
29
|
+
export declare function consumeApprovedRecordGrantBundle(approval: ApprovalRecord): {
|
|
30
|
+
approval: ApprovalRecord;
|
|
31
|
+
consumed: boolean;
|
|
32
|
+
};
|
|
33
|
+
export declare function decrementApprovalLegacyGrant(approval: ApprovalRecord): ApprovalRecord;
|
|
4
34
|
export declare function grantsFromApprovedState(state: ApprovalStateFile, repoRoot: string): CapabilityGrantV1[];
|
|
5
35
|
export declare function consumeGrantLease(state: ApprovalStateFile, grantId: string): {
|
|
6
36
|
state: ApprovalStateFile;
|
|
7
37
|
consumed: boolean;
|
|
8
38
|
};
|
|
39
|
+
/** Consume one lease for each request; all must succeed (atomic bundle consumption). */
|
|
40
|
+
export declare function consumeGrantLeasesForRequests(state: ApprovalStateFile, requests: CapabilityRequestV1[]): {
|
|
41
|
+
state: ApprovalStateFile;
|
|
42
|
+
consumed: boolean;
|
|
43
|
+
};
|
|
9
44
|
export declare function findMatchingGrant(grants: CapabilityGrantV1[] | undefined, request: CapabilityRequestV1): CapabilityGrantV1 | undefined;
|
|
@@ -1,36 +1,212 @@
|
|
|
1
|
+
import { canonicalStringify } from '../fingerprint.js';
|
|
1
2
|
import { isGrantScopeTooBroad } from './grant.js';
|
|
2
3
|
import { grantMatchesRequest } from './grant-match.js';
|
|
3
|
-
|
|
4
|
+
function isActiveGrant(grant, now) {
|
|
5
|
+
if (isGrantScopeTooBroad(grant)) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
const expires = Date.parse(grant.expiresAt);
|
|
9
|
+
return Number.isFinite(expires) && expires > now && grant.usesRemaining > 0;
|
|
10
|
+
}
|
|
11
|
+
export function grantsFromApproval(approval) {
|
|
12
|
+
if (approval.grants?.length) {
|
|
13
|
+
return approval.grants;
|
|
14
|
+
}
|
|
15
|
+
if (approval.grant) {
|
|
16
|
+
return [approval.grant];
|
|
17
|
+
}
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
export function approvalGrantBundleExhausted(approval) {
|
|
21
|
+
const bundle = grantsFromApproval(approval);
|
|
22
|
+
if (!bundle.length) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return bundle.every((grant) => grant.usesRemaining <= 0);
|
|
26
|
+
}
|
|
27
|
+
export function consumeApprovalGrantBundle(approval, requests) {
|
|
28
|
+
const bundle = grantsFromApproval(approval);
|
|
29
|
+
if (!bundle.length || !requests.length) {
|
|
30
|
+
return { approval, consumed: false };
|
|
31
|
+
}
|
|
32
|
+
const grants = [...bundle];
|
|
4
33
|
const now = Date.now();
|
|
5
|
-
|
|
6
|
-
.
|
|
7
|
-
|
|
8
|
-
|
|
34
|
+
for (const request of requests) {
|
|
35
|
+
const index = grants.findIndex((grant) => {
|
|
36
|
+
return isActiveGrant(grant, now) && grantMatchesRequest(grant, request);
|
|
37
|
+
});
|
|
38
|
+
if (index === -1) {
|
|
39
|
+
return { approval, consumed: false };
|
|
40
|
+
}
|
|
41
|
+
const grant = grants[index];
|
|
9
42
|
if (!grant) {
|
|
10
|
-
return false;
|
|
43
|
+
return { approval, consumed: false };
|
|
11
44
|
}
|
|
12
|
-
|
|
45
|
+
grants[index] = decrementGrant(grant);
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
approval: {
|
|
49
|
+
...approval,
|
|
50
|
+
grants,
|
|
51
|
+
grant: grants[0],
|
|
52
|
+
},
|
|
53
|
+
consumed: true,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function exactGrantMatchesRequest(grant, request) {
|
|
57
|
+
return (persistedCanonicalStringify(grant.principal) ===
|
|
58
|
+
persistedCanonicalStringify(request.principal) &&
|
|
59
|
+
grant.action === request.action &&
|
|
60
|
+
persistedCanonicalStringify(grant.resource) === persistedCanonicalStringify(request.resource) &&
|
|
61
|
+
grant.inputFingerprint === request.context.inputFingerprint);
|
|
62
|
+
}
|
|
63
|
+
function validateExactGrantBundle(approval, requests, now, usage) {
|
|
64
|
+
if (approval.grantBundleVersion !== 1) {
|
|
65
|
+
return { ok: false, reason: 'legacy_record' };
|
|
66
|
+
}
|
|
67
|
+
if (!requests.length) {
|
|
68
|
+
return { ok: false, reason: 'empty_requests' };
|
|
69
|
+
}
|
|
70
|
+
const bundle = grantsFromApproval(approval);
|
|
71
|
+
if (bundle.length !== requests.length) {
|
|
72
|
+
return { ok: false, reason: 'cardinality_mismatch' };
|
|
73
|
+
}
|
|
74
|
+
if (bundle.some((grant) => isGrantScopeTooBroad(grant))) {
|
|
75
|
+
return { ok: false, reason: 'grant_scope_too_broad' };
|
|
76
|
+
}
|
|
77
|
+
const usageIsValid = bundle.every((grant) => {
|
|
78
|
+
const expires = Date.parse(grant.expiresAt);
|
|
79
|
+
if (!Number.isFinite(expires) || expires <= now) {
|
|
13
80
|
return false;
|
|
14
81
|
}
|
|
15
|
-
|
|
16
|
-
|
|
82
|
+
return usage === 'available'
|
|
83
|
+
? grant.usesRemaining > 0
|
|
84
|
+
: grant.usesRemaining >= 0 && grant.usesRemaining < grant.maxUses;
|
|
17
85
|
});
|
|
86
|
+
if (!usageIsValid) {
|
|
87
|
+
return { ok: false, reason: 'grant_inactive' };
|
|
88
|
+
}
|
|
89
|
+
const unmatched = [...bundle];
|
|
90
|
+
for (const request of requests) {
|
|
91
|
+
const index = unmatched.findIndex((grant) => exactGrantMatchesRequest(grant, request));
|
|
92
|
+
if (index === -1) {
|
|
93
|
+
return { ok: false, reason: 'grant_mismatch' };
|
|
94
|
+
}
|
|
95
|
+
unmatched.splice(index, 1);
|
|
96
|
+
}
|
|
97
|
+
if (unmatched.length > 0) {
|
|
98
|
+
return { ok: false, reason: 'grant_mismatch' };
|
|
99
|
+
}
|
|
100
|
+
return { ok: true, approval };
|
|
101
|
+
}
|
|
102
|
+
function persistedCanonicalStringify(value) {
|
|
103
|
+
return canonicalStringify(omitUndefined(value));
|
|
104
|
+
}
|
|
105
|
+
function omitUndefined(value) {
|
|
106
|
+
if (Array.isArray(value)) {
|
|
107
|
+
return value.map((entry) => omitUndefined(entry));
|
|
108
|
+
}
|
|
109
|
+
if (!value || typeof value !== 'object') {
|
|
110
|
+
return value;
|
|
111
|
+
}
|
|
112
|
+
return Object.fromEntries(Object.entries(value)
|
|
113
|
+
.filter(([, entry]) => entry !== undefined)
|
|
114
|
+
.map(([key, entry]) => [key, omitUndefined(entry)]));
|
|
115
|
+
}
|
|
116
|
+
/** Validate and consume a marked exact bundle without mutating on any failure. */
|
|
117
|
+
export function validateAndConsumeGrantBundle(approval, requests, now = Date.now()) {
|
|
118
|
+
const validated = validateExactGrantBundle(approval, requests, now, 'available');
|
|
119
|
+
if (!validated.ok) {
|
|
120
|
+
return validated;
|
|
121
|
+
}
|
|
122
|
+
const grants = grantsFromApproval(approval).map((grant) => decrementGrant(grant));
|
|
123
|
+
return {
|
|
124
|
+
ok: true,
|
|
125
|
+
approval: {
|
|
126
|
+
...approval,
|
|
127
|
+
grants,
|
|
128
|
+
grant: grants[0],
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/** Revalidate a marked bundle during an active replay lease without consuming it twice. */
|
|
133
|
+
export function validateGrantBundleForLeaseReuse(approval, requests, now = Date.now()) {
|
|
134
|
+
return validateExactGrantBundle(approval, requests, now, 'previously_consumed');
|
|
135
|
+
}
|
|
136
|
+
/** Consume every grant in an approved record after fingerprint/hash replay validation. */
|
|
137
|
+
export function consumeApprovedRecordGrantBundle(approval) {
|
|
138
|
+
const bundle = grantsFromApproval(approval);
|
|
139
|
+
const now = Date.now();
|
|
140
|
+
if (!bundle.length ||
|
|
141
|
+
bundle.some((grant) => {
|
|
142
|
+
const expires = Date.parse(grant.expiresAt);
|
|
143
|
+
return !Number.isFinite(expires) || expires <= now || grant.usesRemaining <= 0;
|
|
144
|
+
})) {
|
|
145
|
+
return { approval, consumed: false };
|
|
146
|
+
}
|
|
147
|
+
const grants = bundle.map((grant) => decrementGrant(grant));
|
|
148
|
+
return {
|
|
149
|
+
approval: {
|
|
150
|
+
...approval,
|
|
151
|
+
grants,
|
|
152
|
+
grant: grants[0],
|
|
153
|
+
},
|
|
154
|
+
consumed: true,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
export function decrementApprovalLegacyGrant(approval) {
|
|
158
|
+
const bundle = grantsFromApproval(approval);
|
|
159
|
+
if (!bundle.length) {
|
|
160
|
+
return approval;
|
|
161
|
+
}
|
|
162
|
+
const grants = bundle.map((grant, index) => (index === 0 ? decrementGrant(grant) : grant));
|
|
163
|
+
return {
|
|
164
|
+
...approval,
|
|
165
|
+
grants,
|
|
166
|
+
grant: grants[0],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
export function grantsFromApprovedState(state, repoRoot) {
|
|
170
|
+
const now = Date.now();
|
|
171
|
+
const collected = [];
|
|
172
|
+
for (const approval of state.approvals) {
|
|
173
|
+
if (approval.repoRoot !== repoRoot) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
for (const grant of grantsFromApproval(approval)) {
|
|
177
|
+
if (isActiveGrant(grant, now)) {
|
|
178
|
+
collected.push(grant);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return collected;
|
|
183
|
+
}
|
|
184
|
+
function decrementGrant(grant) {
|
|
185
|
+
return {
|
|
186
|
+
...grant,
|
|
187
|
+
usesRemaining: grant.usesRemaining - 1,
|
|
188
|
+
};
|
|
18
189
|
}
|
|
19
190
|
export function consumeGrantLease(state, grantId) {
|
|
20
191
|
let consumed = false;
|
|
21
192
|
const approvals = state.approvals.map((approval) => {
|
|
22
|
-
const
|
|
23
|
-
|
|
193
|
+
const bundle = grantsFromApproval(approval);
|
|
194
|
+
const index = bundle.findIndex((g) => g.grantId === grantId);
|
|
195
|
+
if (index === -1) {
|
|
196
|
+
return approval;
|
|
197
|
+
}
|
|
198
|
+
const grant = bundle[index];
|
|
199
|
+
if (!grant || grant.usesRemaining <= 0) {
|
|
24
200
|
return approval;
|
|
25
201
|
}
|
|
26
202
|
consumed = true;
|
|
27
|
-
const
|
|
203
|
+
const updated = decrementGrant(grant);
|
|
204
|
+
const grants = [...bundle];
|
|
205
|
+
grants[index] = updated;
|
|
28
206
|
return {
|
|
29
207
|
...approval,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
usesRemaining,
|
|
33
|
-
},
|
|
208
|
+
grants,
|
|
209
|
+
grant: grants[0],
|
|
34
210
|
};
|
|
35
211
|
});
|
|
36
212
|
return {
|
|
@@ -38,6 +214,27 @@ export function consumeGrantLease(state, grantId) {
|
|
|
38
214
|
consumed,
|
|
39
215
|
};
|
|
40
216
|
}
|
|
217
|
+
/** Consume one lease for each request; all must succeed (atomic bundle consumption). */
|
|
218
|
+
export function consumeGrantLeasesForRequests(state, requests) {
|
|
219
|
+
const repoRoot = requests[0]?.principal.repoRoot;
|
|
220
|
+
if (!repoRoot || requests.some((request) => request.principal.repoRoot !== repoRoot)) {
|
|
221
|
+
return { state, consumed: false };
|
|
222
|
+
}
|
|
223
|
+
for (let index = 0; index < state.approvals.length; index += 1) {
|
|
224
|
+
const approval = state.approvals[index];
|
|
225
|
+
if (!approval || approval.repoRoot !== repoRoot) {
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
const consumed = consumeApprovalGrantBundle(approval, requests);
|
|
229
|
+
if (!consumed.consumed) {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const approvals = [...state.approvals];
|
|
233
|
+
approvals[index] = consumed.approval;
|
|
234
|
+
return { state: { ...state, approvals }, consumed: true };
|
|
235
|
+
}
|
|
236
|
+
return { state, consumed: false };
|
|
237
|
+
}
|
|
41
238
|
export function findMatchingGrant(grants, request) {
|
|
42
239
|
if (!grants?.length) {
|
|
43
240
|
return undefined;
|
|
@@ -53,6 +53,9 @@ function grantTargetsResource(grant, request) {
|
|
|
53
53
|
if (grant.resource.kind === 'executable' && request.resource.kind === 'executable') {
|
|
54
54
|
return grant.resource.command === request.resource.command;
|
|
55
55
|
}
|
|
56
|
+
if (grant.resource.kind === 'package-cache' && request.resource.kind === 'package-cache') {
|
|
57
|
+
return grant.resource.manager === request.resource.manager;
|
|
58
|
+
}
|
|
56
59
|
if (grant.resource.kind === 'git-ref' && request.resource.kind === 'git-ref') {
|
|
57
60
|
return grant.resource.ref === request.resource.ref;
|
|
58
61
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { addPathToAllowlist, allPathsAllowlisted, fsScopeAllowlistPath, isPathAllowlisted, loadFsScopeAllowlist, loadFsScopeAllowlistSync, saveFsScopeAllowlist, } from './allowlist.js';
|
|
2
|
-
export { BOUNDARY_ATTESTATION_VERSION, type BoundaryAttestation, type BoundaryDriverId, isAttestationFresh, } from './attestation.js';
|
|
2
|
+
export { attestsWorkspaceMountIsolation, BOUNDARY_ATTESTATION_VERSION, type BoundaryAttestation, type BoundaryDriverId, isAttestationFresh, } from './attestation.js';
|
|
3
3
|
export { BOUNDARY_PROFILE_L1_ATTESTED, BOUNDARY_PROFILE_L3_L4_ONLY, BOUNDARY_PROFILE_L3_POLICY, boundaryVerifiedAllowEnabled, isAttestedBoundary, resolveBoundaryProfile, } from './boundary-profile.js';
|
|
4
4
|
export { evaluateL1FullStatus, hasSandboxRuntime, isCapabilityBrokerDemotionActive, isSandboxBrokerEnabled, } from './broker.js';
|
|
5
5
|
export { CAPABILITY_GRANT_VERSION, type CapabilityGrantV1, isGrantScopeTooBroad, } from './grant.js';
|
|
@@ -9,6 +9,6 @@ export { type CapabilityAuthorizationMetadata, type PolicyLegacyReasonHints, pol
|
|
|
9
9
|
export { buildFileMutationCapabilityRequest, buildShellCapabilityRequest, createTypeScriptPolicyEngine, evaluateFileMutationPolicy, evaluateShellPolicy, evaluateSubagentPolicy, type FileMutationCapabilityAnalysis, getDefaultPolicyEngine, policyDecisionRequiresAsk, type ShellCapabilityAnalysis, type SubagentCapabilityAnalysis, } from './policy-engine.js';
|
|
10
10
|
export type { AuthorizationContext, PolicyDecision, PolicyEngine, PolicyOutcome, } from './policy-types.js';
|
|
11
11
|
export { FS_SCOPE_REASONS, shouldSkipBrokerApprovedOnce, shouldSkipBrokerApprovedRecord, } from './reasons.js';
|
|
12
|
-
export { CAPABILITY_REQUEST_VERSION, type CapabilityAction, type CapabilityEvidence, type CapabilityEvidenceLevel, type CapabilityHookKind, type CapabilityPrincipal, type CapabilityRequestContext, type CapabilityRequestV1, type CapabilityResource, } from './request.js';
|
|
12
|
+
export { CAPABILITY_REQUEST_VERSION, type CapabilityAction, type CapabilityEvidence, type CapabilityEvidenceLevel, type CapabilityHookKind, type CapabilityPrincipal, type CapabilityRequestContext, type CapabilityRequestV1, type CapabilityResource, type GitRefScope, type NetworkMode, type NetworkPayload, type ProcessOperation, } from './request.js';
|
|
13
13
|
export { addTrustedWorkspaceRoot, isBroadTrustedWorkspaceRoot, isHighStakesTrustedWorkspaceRoot, isPathWithinTrustedWorkspaceRoots, loadTrustedWorkspaceRoots, loadTrustedWorkspaceRootsSync, normalizeTrustedWorkspaceRootPath, saveTrustedWorkspaceRoots, trustedWorkspaceRootsPath, validateTrustedWorkspaceRootCandidate, } from './trusted-workspace-roots.js';
|
|
14
14
|
export type { CapabilityApprovalScope, FsScopeAllowlistEntry, FsScopeAllowlistFile, TrustedWorkspaceRootEntry, TrustedWorkspaceRootsFile, } from './types.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { addPathToAllowlist, allPathsAllowlisted, fsScopeAllowlistPath, isPathAllowlisted, loadFsScopeAllowlist, loadFsScopeAllowlistSync, saveFsScopeAllowlist, } from './allowlist.js';
|
|
2
|
-
export { BOUNDARY_ATTESTATION_VERSION, isAttestationFresh, } from './attestation.js';
|
|
2
|
+
export { attestsWorkspaceMountIsolation, BOUNDARY_ATTESTATION_VERSION, isAttestationFresh, } from './attestation.js';
|
|
3
3
|
export { BOUNDARY_PROFILE_L1_ATTESTED, BOUNDARY_PROFILE_L3_L4_ONLY, BOUNDARY_PROFILE_L3_POLICY, boundaryVerifiedAllowEnabled, isAttestedBoundary, resolveBoundaryProfile, } from './boundary-profile.js';
|
|
4
4
|
export { evaluateL1FullStatus, hasSandboxRuntime, isCapabilityBrokerDemotionActive, isSandboxBrokerEnabled, } from './broker.js';
|
|
5
5
|
export { CAPABILITY_GRANT_VERSION, isGrantScopeTooBroad, } from './grant.js';
|
|
@@ -1,11 +1,41 @@
|
|
|
1
1
|
import type { BelayConfigV4 } from '../config.js';
|
|
2
2
|
import type { VerdictEffect, VerdictLocation, VerdictOpacity } from '../verdict/types.js';
|
|
3
|
+
import type { CapabilityGrantV1 } from './grant.js';
|
|
3
4
|
import type { AuthorizationContext, PolicyDecision, PolicyEngine } from './policy-types.js';
|
|
4
|
-
import { type CapabilityHookKind, type CapabilityRequestV1 } from './request.js';
|
|
5
|
+
import { type CapabilityAction, type CapabilityEvidenceLevel, type CapabilityHookKind, type CapabilityRequestV1, type CapabilityResource } from './request.js';
|
|
5
6
|
export type PolicyAuthExtras = Pick<AuthorizationContext, 'grants' | 'attestation'> & {
|
|
6
7
|
egressProxyActive?: boolean;
|
|
7
8
|
sensitivePaths?: string[];
|
|
8
9
|
};
|
|
10
|
+
export type EffectPolicyDisposition = 'allow' | 'allow_flagged' | 'ask';
|
|
11
|
+
export interface EffectRequirementPolicyInput {
|
|
12
|
+
tag: string;
|
|
13
|
+
action: CapabilityAction;
|
|
14
|
+
resource: CapabilityResource;
|
|
15
|
+
evidence: {
|
|
16
|
+
level: CapabilityEvidenceLevel;
|
|
17
|
+
signals: readonly string[];
|
|
18
|
+
basis: readonly string[];
|
|
19
|
+
};
|
|
20
|
+
provenance?: unknown;
|
|
21
|
+
}
|
|
22
|
+
export interface EffectRequirementPolicyContext {
|
|
23
|
+
cwd: string;
|
|
24
|
+
repoRoot: string;
|
|
25
|
+
trustedWorkspaceRoots?: readonly string[];
|
|
26
|
+
sensitivePaths?: readonly string[];
|
|
27
|
+
protectedArtifactRoots?: readonly string[];
|
|
28
|
+
grants?: readonly CapabilityGrantV1[];
|
|
29
|
+
capabilityRequest?: CapabilityRequestV1;
|
|
30
|
+
}
|
|
31
|
+
export interface EffectRequirementPolicyDecision extends PolicyDecision {
|
|
32
|
+
effectDisposition: EffectPolicyDisposition;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Policy for a lowered shell effect. It intentionally ignores executable
|
|
36
|
+
* command names, segment heads, command text, and config allowlists.
|
|
37
|
+
*/
|
|
38
|
+
export declare function evaluateEffectRequirementPolicy(requirement: EffectRequirementPolicyInput, context: EffectRequirementPolicyContext): EffectRequirementPolicyDecision;
|
|
9
39
|
export interface ShellCapabilityAnalysis {
|
|
10
40
|
command: string;
|
|
11
41
|
hookKind: CapabilityHookKind;
|
|
@@ -56,12 +86,19 @@ export declare function evaluateSubagentPolicy(analysis: SubagentCapabilityAnaly
|
|
|
56
86
|
decision: PolicyDecision;
|
|
57
87
|
};
|
|
58
88
|
export declare function buildShellCapabilityRequest(analysis: ShellCapabilityAnalysis): CapabilityRequestV1;
|
|
89
|
+
export declare function buildShellCapabilityRequests(analysis: ShellCapabilityAnalysis): CapabilityRequestV1[];
|
|
59
90
|
export declare function buildFileMutationCapabilityRequest(analysis: FileMutationCapabilityAnalysis): CapabilityRequestV1;
|
|
60
91
|
export declare function createTypeScriptPolicyEngine(): PolicyEngine;
|
|
61
92
|
export declare function getDefaultPolicyEngine(): PolicyEngine;
|
|
62
93
|
export declare function policyDecisionRequiresAsk(decision: PolicyDecision): boolean;
|
|
94
|
+
export declare function combinePolicyDecisions(decisions: readonly PolicyDecision[]): PolicyDecision;
|
|
95
|
+
export declare function evaluateCapabilityRequestsPolicy(requests: readonly CapabilityRequestV1[], config: BelayConfigV4, auth?: PolicyAuthExtras, trustedWorkspaceRoots?: string[]): {
|
|
96
|
+
decisions: PolicyDecision[];
|
|
97
|
+
decision: PolicyDecision;
|
|
98
|
+
};
|
|
63
99
|
export declare function evaluateShellPolicy(analysis: ShellCapabilityAnalysis, config: BelayConfigV4, auth?: PolicyAuthExtras): {
|
|
64
100
|
request: CapabilityRequestV1;
|
|
101
|
+
requests: CapabilityRequestV1[];
|
|
65
102
|
decision: PolicyDecision;
|
|
66
103
|
};
|
|
67
104
|
export declare function evaluateFileMutationPolicy(analysis: FileMutationCapabilityAnalysis, config: BelayConfigV4, auth?: PolicyAuthExtras): {
|