@miller-tech/uap 2.21.3 → 2.36.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -10
- package/config/model-profiles/qwen38-coder390.json +46 -0
- package/config/model-profiles/qwen38.json +3 -2
- package/config/model-registry.json +110 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/benchmarks/paired/types.d.ts +2 -2
- package/dist/bin/cli.js +315 -20
- package/dist/bin/cli.js.map +1 -1
- package/dist/cli/attention.d.ts +6 -0
- package/dist/cli/attention.d.ts.map +1 -0
- package/dist/cli/attention.js +115 -0
- package/dist/cli/attention.js.map +1 -0
- package/dist/cli/bench-report.d.ts +82 -0
- package/dist/cli/bench-report.d.ts.map +1 -0
- package/dist/cli/bench-report.js +237 -0
- package/dist/cli/bench-report.js.map +1 -0
- package/dist/cli/clients.d.ts +6 -0
- package/dist/cli/clients.d.ts.map +1 -0
- package/dist/cli/clients.js +142 -0
- package/dist/cli/clients.js.map +1 -0
- package/dist/cli/dashboard-grants.d.ts +26 -0
- package/dist/cli/dashboard-grants.d.ts.map +1 -0
- package/dist/cli/dashboard-grants.js +69 -0
- package/dist/cli/dashboard-grants.js.map +1 -0
- package/dist/cli/dashboard-pace.d.ts +31 -0
- package/dist/cli/dashboard-pace.d.ts.map +1 -0
- package/dist/cli/dashboard-pace.js +42 -0
- package/dist/cli/dashboard-pace.js.map +1 -0
- package/dist/cli/dashboard-session.d.ts +25 -0
- package/dist/cli/dashboard-session.d.ts.map +1 -0
- package/dist/cli/dashboard-session.js +814 -0
- package/dist/cli/dashboard-session.js.map +1 -0
- package/dist/cli/dashboard-types.d.ts +18 -0
- package/dist/cli/dashboard-types.d.ts.map +1 -0
- package/dist/cli/dashboard-types.js +9 -0
- package/dist/cli/dashboard-types.js.map +1 -0
- package/dist/cli/dashboard.d.ts +2 -18
- package/dist/cli/dashboard.d.ts.map +1 -1
- package/dist/cli/dashboard.js +43 -793
- package/dist/cli/dashboard.js.map +1 -1
- package/dist/cli/deliver.d.ts +35 -0
- package/dist/cli/deliver.d.ts.map +1 -1
- package/dist/cli/deliver.js +93 -9
- package/dist/cli/deliver.js.map +1 -1
- package/dist/cli/diff.d.ts +85 -0
- package/dist/cli/diff.d.ts.map +1 -0
- package/dist/cli/diff.js +293 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/eta.d.ts +35 -0
- package/dist/cli/eta.d.ts.map +1 -0
- package/dist/cli/eta.js +101 -0
- package/dist/cli/eta.js.map +1 -0
- package/dist/cli/handsfree.d.ts +7 -0
- package/dist/cli/handsfree.d.ts.map +1 -1
- package/dist/cli/handsfree.js +27 -0
- package/dist/cli/handsfree.js.map +1 -1
- package/dist/cli/hooks.d.ts.map +1 -1
- package/dist/cli/hooks.js +126 -5
- package/dist/cli/hooks.js.map +1 -1
- package/dist/cli/loops.d.ts +24 -5
- package/dist/cli/loops.d.ts.map +1 -1
- package/dist/cli/loops.js +92 -12
- package/dist/cli/loops.js.map +1 -1
- package/dist/cli/models.d.ts +62 -0
- package/dist/cli/models.d.ts.map +1 -0
- package/dist/cli/models.js +567 -0
- package/dist/cli/models.js.map +1 -0
- package/dist/cli/plan.d.ts +9 -0
- package/dist/cli/plan.d.ts.map +1 -1
- package/dist/cli/plan.js +57 -4
- package/dist/cli/plan.js.map +1 -1
- package/dist/cli/proxy-relay.d.ts +55 -0
- package/dist/cli/proxy-relay.d.ts.map +1 -0
- package/dist/cli/proxy-relay.js +116 -0
- package/dist/cli/proxy-relay.js.map +1 -0
- package/dist/cli/proxy.d.ts +4 -0
- package/dist/cli/proxy.d.ts.map +1 -1
- package/dist/cli/proxy.js +26 -1
- package/dist/cli/proxy.js.map +1 -1
- package/dist/cli/sandbox.d.ts +101 -4
- package/dist/cli/sandbox.d.ts.map +1 -1
- package/dist/cli/sandbox.js +393 -44
- package/dist/cli/sandbox.js.map +1 -1
- package/dist/cli/self.d.ts +13 -0
- package/dist/cli/self.d.ts.map +1 -0
- package/dist/cli/self.js +94 -0
- package/dist/cli/self.js.map +1 -0
- package/dist/cli/systemd-services.d.ts +2 -8
- package/dist/cli/systemd-services.d.ts.map +1 -1
- package/dist/cli/systemd-services.js +5 -20
- package/dist/cli/systemd-services.js.map +1 -1
- package/dist/cli/task.js +1 -1
- package/dist/cli/task.js.map +1 -1
- package/dist/cli/wizard-config.d.ts.map +1 -1
- package/dist/cli/wizard-config.js +31 -2
- package/dist/cli/wizard-config.js.map +1 -1
- package/dist/config/settings-registry.d.ts +1 -1
- package/dist/config/settings-registry.d.ts.map +1 -1
- package/dist/config/settings-registry.js +108 -0
- package/dist/config/settings-registry.js.map +1 -1
- package/dist/coordination/capability-router.js +2 -2
- package/dist/coordination/capability-router.js.map +1 -1
- package/dist/coordination/database.d.ts +13 -0
- package/dist/coordination/database.d.ts.map +1 -1
- package/dist/coordination/database.js +63 -7
- package/dist/coordination/database.js.map +1 -1
- package/dist/coordination/eta-inject.d.ts +32 -0
- package/dist/coordination/eta-inject.d.ts.map +1 -0
- package/dist/coordination/eta-inject.js +64 -0
- package/dist/coordination/eta-inject.js.map +1 -0
- package/dist/coordination/reactor.d.ts.map +1 -1
- package/dist/coordination/reactor.js +14 -0
- package/dist/coordination/reactor.js.map +1 -1
- package/dist/coordination/service.d.ts +18 -8
- package/dist/coordination/service.d.ts.map +1 -1
- package/dist/coordination/service.js +38 -28
- package/dist/coordination/service.js.map +1 -1
- package/dist/dashboard/client-registry.d.ts +163 -0
- package/dist/dashboard/client-registry.d.ts.map +1 -0
- package/dist/dashboard/client-registry.js +549 -0
- package/dist/dashboard/client-registry.js.map +1 -0
- package/dist/dashboard/controls.d.ts.map +1 -1
- package/dist/dashboard/controls.js +33 -4
- package/dist/dashboard/controls.js.map +1 -1
- package/dist/dashboard/data-seeder.d.ts +10 -7
- package/dist/dashboard/data-seeder.d.ts.map +1 -1
- package/dist/dashboard/data-seeder.js +31 -75
- package/dist/dashboard/data-seeder.js.map +1 -1
- package/dist/dashboard/data-service.d.ts +9 -0
- package/dist/dashboard/data-service.d.ts.map +1 -1
- package/dist/dashboard/data-service.js +32 -3
- package/dist/dashboard/data-service.js.map +1 -1
- package/dist/dashboard/placement-routes.d.ts +119 -0
- package/dist/dashboard/placement-routes.d.ts.map +1 -0
- package/dist/dashboard/placement-routes.js +331 -0
- package/dist/dashboard/placement-routes.js.map +1 -0
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +408 -2
- package/dist/dashboard/server.js.map +1 -1
- package/dist/delivery/attention.d.ts +130 -0
- package/dist/delivery/attention.d.ts.map +1 -0
- package/dist/delivery/attention.js +341 -0
- package/dist/delivery/attention.js.map +1 -0
- package/dist/delivery/decompose.d.ts +18 -0
- package/dist/delivery/decompose.d.ts.map +1 -1
- package/dist/delivery/decompose.js +22 -1
- package/dist/delivery/decompose.js.map +1 -1
- package/dist/delivery/eta-estimate.d.ts +111 -0
- package/dist/delivery/eta-estimate.d.ts.map +1 -0
- package/dist/delivery/eta-estimate.js +171 -0
- package/dist/delivery/eta-estimate.js.map +1 -0
- package/dist/delivery/eta.d.ts +23 -0
- package/dist/delivery/eta.d.ts.map +1 -0
- package/dist/delivery/eta.js +59 -0
- package/dist/delivery/eta.js.map +1 -0
- package/dist/delivery/orchestrated-mission.d.ts +10 -0
- package/dist/delivery/orchestrated-mission.d.ts.map +1 -1
- package/dist/delivery/orchestrated-mission.js +15 -1
- package/dist/delivery/orchestrated-mission.js.map +1 -1
- package/dist/delivery/plan-check.d.ts +7 -1
- package/dist/delivery/plan-check.d.ts.map +1 -1
- package/dist/delivery/plan-check.js +23 -2
- package/dist/delivery/plan-check.js.map +1 -1
- package/dist/delivery/run-state.d.ts +1 -1
- package/dist/delivery/run-state.d.ts.map +1 -1
- package/dist/delivery/run-state.js +8 -1
- package/dist/delivery/run-state.js.map +1 -1
- package/dist/delivery/task-orchestrator.d.ts +8 -3
- package/dist/delivery/task-orchestrator.d.ts.map +1 -1
- package/dist/delivery/task-orchestrator.js +75 -43
- package/dist/delivery/task-orchestrator.js.map +1 -1
- package/dist/delivery/task-sync.d.ts +21 -0
- package/dist/delivery/task-sync.d.ts.map +1 -1
- package/dist/delivery/task-sync.js +44 -8
- package/dist/delivery/task-sync.js.map +1 -1
- package/dist/delivery/task-workspace.d.ts +3 -3
- package/dist/delivery/task-workspace.js +3 -3
- package/dist/generators/self-card.d.ts +65 -0
- package/dist/generators/self-card.d.ts.map +1 -0
- package/dist/generators/self-card.js +256 -0
- package/dist/generators/self-card.js.map +1 -0
- package/dist/inference/probe.js +1 -1
- package/dist/inference/probe.js.map +1 -1
- package/dist/memory/prepopulate.d.ts.map +1 -1
- package/dist/memory/prepopulate.js +2 -0
- package/dist/memory/prepopulate.js.map +1 -1
- package/dist/models/analytics.d.ts +32 -0
- package/dist/models/analytics.d.ts.map +1 -1
- package/dist/models/analytics.js +68 -5
- package/dist/models/analytics.js.map +1 -1
- package/dist/models/plan-readability.d.ts +55 -0
- package/dist/models/plan-readability.d.ts.map +1 -0
- package/dist/models/plan-readability.js +339 -0
- package/dist/models/plan-readability.js.map +1 -0
- package/dist/placement/admission.d.ts +59 -0
- package/dist/placement/admission.d.ts.map +1 -0
- package/dist/placement/admission.js +197 -0
- package/dist/placement/admission.js.map +1 -0
- package/dist/placement/auto.d.ts +44 -0
- package/dist/placement/auto.d.ts.map +1 -0
- package/dist/placement/auto.js +212 -0
- package/dist/placement/auto.js.map +1 -0
- package/dist/placement/enforce.d.ts +128 -0
- package/dist/placement/enforce.d.ts.map +1 -0
- package/dist/placement/enforce.js +655 -0
- package/dist/placement/enforce.js.map +1 -0
- package/dist/placement/idle.d.ts +50 -0
- package/dist/placement/idle.d.ts.map +1 -0
- package/dist/placement/idle.js +213 -0
- package/dist/placement/idle.js.map +1 -0
- package/dist/placement/ledger.d.ts +323 -0
- package/dist/placement/ledger.d.ts.map +1 -0
- package/dist/placement/ledger.js +263 -0
- package/dist/placement/ledger.js.map +1 -0
- package/dist/placement/preview.d.ts +51 -0
- package/dist/placement/preview.d.ts.map +1 -0
- package/dist/placement/preview.js +61 -0
- package/dist/placement/preview.js.map +1 -0
- package/dist/placement/probes.d.ts +47 -0
- package/dist/placement/probes.d.ts.map +1 -0
- package/dist/placement/probes.js +207 -0
- package/dist/placement/probes.js.map +1 -0
- package/dist/placement/proxy-env.d.ts +21 -0
- package/dist/placement/proxy-env.d.ts.map +1 -0
- package/dist/placement/proxy-env.js +42 -0
- package/dist/placement/proxy-env.js.map +1 -0
- package/dist/placement/registry.d.ts +1038 -0
- package/dist/placement/registry.d.ts.map +1 -0
- package/dist/placement/registry.js +274 -0
- package/dist/placement/registry.js.map +1 -0
- package/dist/policies/liveness.d.ts +6 -8
- package/dist/policies/liveness.d.ts.map +1 -1
- package/dist/policies/liveness.js +6 -25
- package/dist/policies/liveness.js.map +1 -1
- package/dist/policies/sandbox-anchor.d.ts +91 -0
- package/dist/policies/sandbox-anchor.d.ts.map +1 -0
- package/dist/policies/sandbox-anchor.js +187 -0
- package/dist/policies/sandbox-anchor.js.map +1 -0
- package/dist/policies/sandbox-grants.d.ts +131 -0
- package/dist/policies/sandbox-grants.d.ts.map +1 -0
- package/dist/policies/sandbox-grants.js +562 -0
- package/dist/policies/sandbox-grants.js.map +1 -0
- package/dist/state/manifest.d.ts +4 -2
- package/dist/state/manifest.d.ts.map +1 -1
- package/dist/state/manifest.js +32 -16
- package/dist/state/manifest.js.map +1 -1
- package/dist/utils/checkout-root.d.ts +2 -0
- package/dist/utils/checkout-root.d.ts.map +1 -0
- package/dist/utils/checkout-root.js +43 -0
- package/dist/utils/checkout-root.js.map +1 -0
- package/dist/utils/resolve-uap-bin.d.ts +5 -0
- package/dist/utils/resolve-uap-bin.d.ts.map +1 -0
- package/dist/utils/resolve-uap-bin.js +33 -0
- package/dist/utils/resolve-uap-bin.js.map +1 -0
- package/dist/utils/terminal-safe.d.ts +12 -0
- package/dist/utils/terminal-safe.d.ts.map +1 -0
- package/dist/utils/terminal-safe.js +53 -0
- package/dist/utils/terminal-safe.js.map +1 -0
- package/docs/ATTRIBUTION.md +1 -0
- package/docs/DASHBOARD_UPLIFT_SPEC.md +8 -8
- package/docs/INDEX.md +6 -5
- package/docs/architecture/OVERVIEW.md +15 -3
- package/docs/architecture/PROTOCOL.md +7 -1
- package/docs/architecture/adr/0006-operator-directed-model-placement.md +86 -0
- package/docs/architecture/adr/0007-auto-displacement-allowlist-as-standing-consent.md +79 -0
- package/docs/architecture/adr/0008-fleet-clients-link-out.md +92 -0
- package/docs/architecture/adr/0009-completion-triggered-dispatch-and-per-leaf-model-dials.md +71 -0
- package/docs/architecture/adr/0010-attention-queue-and-afk-auto-decider.md +159 -0
- package/docs/architecture/adr/0011-sandbox-grants-and-network-egress-boundary.md +219 -0
- package/docs/architecture/adr/0012-operator-legibility-surfaces.md +175 -0
- package/docs/getting-started/INSTALLATION.md +1 -1
- package/docs/guides/AUTOMATIC_FEATURES.md +8 -0
- package/docs/guides/LOCAL_MODELS.md +1 -1
- package/docs/guides/PROXY.md +2 -1
- package/docs/guides/SANDBOX.md +91 -4
- package/docs/integrations/MCP_ROUTER.md +1 -1
- package/docs/plans/model-performance-proof-options.md +176 -0
- package/docs/reference/API.md +1 -1
- package/docs/reference/CLI.md +169 -4
- package/docs/reference/COMPARISON.md +1 -1
- package/docs/reference/CONFIGURATION.md +12 -3
- package/docs/reference/CONFIGURATION_REFERENCE.md +269 -14
- package/docs/reference/DATABASE_SCHEMA.md +1 -1
- package/docs/reference/FEATURES.md +15 -3
- package/docs/reference/PATTERNS.md +1 -1
- package/docs/reference/PLATFORMS.md +14 -1
- package/docs/specs/operator-model-placement.md +1314 -0
- package/docs/specs/operator-model-placement.review.md +339 -0
- package/package.json +2 -2
- package/scripts/maintenance/publish-npm.sh +23 -11
- package/scripts/version-bump.sh +6 -51
- package/src/policies/enforcers/__pycache__/_common.cpython-311.pyc +0 -0
- package/src/policies/enforcers/__pycache__/expert_review_required.cpython-311.pyc +0 -0
- package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-311.pyc +0 -0
- package/src/policies/schemas/policies/mandatory-testing-deployment.md +2 -5
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-311.pyc +0 -0
- package/templates/hooks/session-start.sh +44 -0
- package/tools/agents/UAP/cli.py +14 -3
- package/tools/agents/UAP/paths.py +50 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-311.pyc +0 -0
- package/tools/agents/scripts/anthropic_proxy.py +1420 -100
- package/tools/agents/scripts/toolcall_path_normalizer.py +46 -1
- package/tools/agents/tests/test_anthropic_proxy_streaming.py +29 -6
- package/tools/agents/tests/test_doubling_break.py +64 -5
- package/tools/agents/tests/test_error_loop_break.py +10 -4
- package/tools/agents/tests/test_error_loop_ignores_correctives.py +13 -2
- package/tools/agents/tests/test_lockstep_escalation.py +280 -9
- package/tools/agents/tests/test_path_containment.py +94 -0
- package/tools/agents/tests/test_proxy_unix_socket.py +162 -0
- package/tools/agents/tests/test_signature_quality.py +400 -0
- package/tools/agents/tests/test_uap_compliance.py +11 -1
- package/web/dash/core.js +1 -0
- package/web/dash/tab-clients.js +196 -0
- package/web/dash/tab-models.js +387 -8
- package/web/dash/tab-policies.js +87 -4
- package/web/dash/tabs.js +77 -73
- package/web/dashboard.html +6 -0
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/expert_review_required.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-312.pyc +0 -0
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
- package/web/dash/tab-agents.js +0 -21
- package/web/dash/tab-deliver.js +0 -12
- package/web/dash/tab-memory.js +0 -12
- package/web/dash/tab-orchestration.js +0 -21
- package/web/dash/tab-overview.js +0 -21
- package/web/dash/tab-tasks.js +0 -21
package/dist/cli/sandbox.d.ts
CHANGED
|
@@ -6,14 +6,103 @@
|
|
|
6
6
|
* the KERNEL — for Write/Edit tools, Bash, and any subprocess alike.
|
|
7
7
|
*
|
|
8
8
|
* This is the workdir boundary that `--dangerously-skip-permissions` cannot
|
|
9
|
-
* bypass: the client can't escape the mount namespace.
|
|
10
|
-
*
|
|
9
|
+
* bypass: the client can't escape the mount namespace.
|
|
10
|
+
*
|
|
11
|
+
* Bridge Phase 4 adds two authorities on top of that floor:
|
|
12
|
+
*
|
|
13
|
+
* - Per-session GRANTS (`uap sandbox grant`, D2): extra writable holes
|
|
14
|
+
* recorded in a consent ledger (session-scoped, TTL-bounded, reason-
|
|
15
|
+
* stated, audit-logged). The pre-P4 answer, `UAP_SANDBOX_ALLOW=path:path`,
|
|
16
|
+
* still works but is UNRECORDED authority — it is honored for backwards
|
|
17
|
+
* compatibility and named as unrecorded in the audit and the banner.
|
|
18
|
+
*
|
|
19
|
+
* - The NETWORK EGRESS BOUNDARY (`--net off`, D1): the sandbox gets its own
|
|
20
|
+
* network namespace (--unshare-net) and NOTHING is brought up — no TCP,
|
|
21
|
+
* no DNS, no loopback, no egress of any kind, at the kernel. This is the
|
|
22
|
+
* complete boundary, for untrusted code, evals, and data-only work; model
|
|
23
|
+
* access is impossible by design (a harness that needs the model will fail
|
|
24
|
+
* loudly with connection refused).
|
|
25
|
+
*
|
|
26
|
+
* Why there is no "--net proxy" (netns cut with a single hole to the
|
|
27
|
+
* proxy): rootless Linux cannot express it. AF_UNIX pathname sockets are
|
|
28
|
+
* NETWORK-NAMESPACE-SCOPED — a socket bind-mounted across the netns wall
|
|
29
|
+
* is unreachable (empirically ECONNREFUSED, see ADR 0011), bwrap closes
|
|
30
|
+
* every inherited fd (so no SCM_RIGHTS broker), and the userspace network
|
|
31
|
+
* helpers (pasta/slirp4netns) provide no outbound port allowlist. A
|
|
32
|
+
* boundary that only works when the right helper is present would be a
|
|
33
|
+
* suggestion, not enforcement — so the shipped modes are the two REAL
|
|
34
|
+
* ones: shared (no claim) and off (kernel-complete). The proxy's own
|
|
35
|
+
* PROXY_SOCKET (0600 AF_UNIX) remains the model-path choke point for
|
|
36
|
+
* every non-sandboxed surface; `uap proxy connect` re-serves it on local
|
|
37
|
+
* TCP for clients that cannot speak AF_UNIX.
|
|
11
38
|
*
|
|
12
39
|
* Env:
|
|
13
40
|
* UAP_SANDBOX_WORKDIR workdir to make writable (default: cwd)
|
|
14
|
-
* UAP_SANDBOX_ALLOW extra writable paths, colon-separated
|
|
41
|
+
* UAP_SANDBOX_ALLOW extra writable paths, colon-separated (UNRECORDED)
|
|
42
|
+
* UAP_SANDBOX_NET 'off' to default the net mode (shared otherwise)
|
|
43
|
+
* UAP_SANDBOX_GRANTS pins the grant ledger file (tests, odd layouts)
|
|
44
|
+
* UAP_SANDBOX_AUDIT pins the audit JSONL file (tests, odd layouts)
|
|
45
|
+
* UAP_SANDBOX_GRANTS_OFF=1 resolve zero grants (escape hatch; the sandbox itself stays)
|
|
15
46
|
* UAP_SANDBOX_OFF=1 bypass the sandbox entirely (run the command as-is)
|
|
16
47
|
*/
|
|
48
|
+
import { type ResolvedGrants } from '../policies/sandbox-grants.js';
|
|
49
|
+
export type SandboxNetMode = 'shared' | 'off';
|
|
50
|
+
export interface SandboxPlanInput {
|
|
51
|
+
/** Command to run inside the sandbox. */
|
|
52
|
+
command: string[];
|
|
53
|
+
/** Session id (scopes the grant lookup; empty = no grants). */
|
|
54
|
+
session?: string;
|
|
55
|
+
/** Net mode: 'shared' (default) or 'off' (the kernel egress boundary).
|
|
56
|
+
* Undefined = fall back to `envNet`. */
|
|
57
|
+
net?: SandboxNetMode;
|
|
58
|
+
/** Writable workdir. */
|
|
59
|
+
workdir: string;
|
|
60
|
+
/** $HOME inside the sandbox. */
|
|
61
|
+
home: string;
|
|
62
|
+
/** Legacy unrecorded extra writable paths (UAP_SANDBOX_ALLOW, split). */
|
|
63
|
+
legacyAllow: string[];
|
|
64
|
+
/** Session-resolved grants (empty when the ledger is off/unreadable). */
|
|
65
|
+
grants: ResolvedGrants;
|
|
66
|
+
/** $UAP_SANDBOX_NET — the env default for the net mode (planner stays
|
|
67
|
+
* input-only: the CALLER resolves process.env, so the plan is a pure
|
|
68
|
+
* function of its inputs and unit tests need no env plumbing). */
|
|
69
|
+
envNet?: string;
|
|
70
|
+
/** $ANTHROPIC_CUSTOM_HEADERS — appended to, never clobbered. */
|
|
71
|
+
existingCustomHeaders?: string;
|
|
72
|
+
/** The grant-ledger file and audit JSONL, ro-bound into the namespace so
|
|
73
|
+
* a sandboxed agent can neither plant rows nor forge audit lines (a
|
|
74
|
+
* bind-mounted file cannot be unlinked or replaced inside the ns).
|
|
75
|
+
* Resolved by the CALLER (they honor the env overrides). P4 security
|
|
76
|
+
* review: without this, the consent store lives inside the writable
|
|
77
|
+
* hole and consent is forgeable by the very thing it guards against. */
|
|
78
|
+
grantsLedgerPath?: string;
|
|
79
|
+
auditLogPath?: string;
|
|
80
|
+
}
|
|
81
|
+
export interface SandboxPlan {
|
|
82
|
+
/** Full bwrap argv (bwrap args first, then the inner command). */
|
|
83
|
+
argv: string[];
|
|
84
|
+
/** The command bwrap execs (argv tail) — the session command, verbatim. */
|
|
85
|
+
inner: string[];
|
|
86
|
+
/** Extra env delivered via --setenv. */
|
|
87
|
+
setenv: Record<string, string>;
|
|
88
|
+
/** The net mode actually engaged ('off' = kernel egress boundary). */
|
|
89
|
+
netMode: SandboxNetMode;
|
|
90
|
+
/** Granted writable holes actually opened for this run. */
|
|
91
|
+
grantedPaths: string[];
|
|
92
|
+
/** Legacy-env holes actually opened (resolved targets — what was bound). */
|
|
93
|
+
legacyBound: string[];
|
|
94
|
+
/** Legacy-env entries refused at plan time (raw spellings — over-broad
|
|
95
|
+
* resolutions, or resolutions covering the trust-anchor dir). */
|
|
96
|
+
legacyRefused: string[];
|
|
97
|
+
/** Human-readable lines for the launch banner (colored at the print site). */
|
|
98
|
+
notes: string[];
|
|
99
|
+
}
|
|
100
|
+
/** Compute the bwrap invocation. Pure: a function of its inputs only — the
|
|
101
|
+
* CALLER resolves process.env into `envNet`/`existingCustomHeaders`. */
|
|
102
|
+
export declare function planSandbox(input: SandboxPlanInput): {
|
|
103
|
+
plan?: SandboxPlan;
|
|
104
|
+
error?: string;
|
|
105
|
+
};
|
|
17
106
|
/**
|
|
18
107
|
* Build the ANTHROPIC_CUSTOM_HEADERS value for a sandboxed session: append the
|
|
19
108
|
* `X-Uap-Sandbox: 1` marker (which the proxy uses to strip sandbox-unreachable
|
|
@@ -22,5 +111,13 @@
|
|
|
22
111
|
* (newline-separated "Name: Value" pairs).
|
|
23
112
|
*/
|
|
24
113
|
export declare function sandboxCustomHeaders(existing: string | undefined): string;
|
|
25
|
-
|
|
114
|
+
/**
|
|
115
|
+
* Should `command[0]` be dispatched as a ledger verb? Only when the
|
|
116
|
+
* invocation did NOT use the `--` separator: `uap sandbox -- revoke …` means
|
|
117
|
+
* the operator wants to run a BINARY named `revoke`, and a positional
|
|
118
|
+
* intercept that cannot be escaped would shadow legitimate commands (P4
|
|
119
|
+
* review finding). Exposed for the CLI-surface tests.
|
|
120
|
+
*/
|
|
121
|
+
export declare function shouldDispatchGrantVerb(command: string[], argv?: string[]): boolean;
|
|
122
|
+
export declare function sandboxCommand(command: string[], options?: Record<string, unknown>): Promise<void>;
|
|
26
123
|
//# sourceMappingURL=sandbox.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/cli/sandbox.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/cli/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAOH,OAAO,EAUL,KAAK,cAAc,EACpB,MAAM,+BAA+B,CAAC;AAkBvC,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE9C,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;6CACyC;IACzC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,yEAAyE;IACzE,MAAM,EAAE,cAAc,CAAC;IACvB;;uEAEmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;6EAKyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,2EAA2E;IAC3E,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,sEAAsE;IACtE,OAAO,EAAE,cAAc,CAAC;IACxB,2DAA2D;IAC3D,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,4EAA4E;IAC5E,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB;sEACkE;IAClE,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,8EAA8E;IAC9E,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAMD;yEACyE;AACzE,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG;IAAE,IAAI,CAAC,EAAE,WAAW,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAwK3F;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CASzE;AAQD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAGjG;AAoGD,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6G5G"}
|
package/dist/cli/sandbox.js
CHANGED
|
@@ -6,18 +6,236 @@
|
|
|
6
6
|
* the KERNEL — for Write/Edit tools, Bash, and any subprocess alike.
|
|
7
7
|
*
|
|
8
8
|
* This is the workdir boundary that `--dangerously-skip-permissions` cannot
|
|
9
|
-
* bypass: the client can't escape the mount namespace.
|
|
10
|
-
*
|
|
9
|
+
* bypass: the client can't escape the mount namespace.
|
|
10
|
+
*
|
|
11
|
+
* Bridge Phase 4 adds two authorities on top of that floor:
|
|
12
|
+
*
|
|
13
|
+
* - Per-session GRANTS (`uap sandbox grant`, D2): extra writable holes
|
|
14
|
+
* recorded in a consent ledger (session-scoped, TTL-bounded, reason-
|
|
15
|
+
* stated, audit-logged). The pre-P4 answer, `UAP_SANDBOX_ALLOW=path:path`,
|
|
16
|
+
* still works but is UNRECORDED authority — it is honored for backwards
|
|
17
|
+
* compatibility and named as unrecorded in the audit and the banner.
|
|
18
|
+
*
|
|
19
|
+
* - The NETWORK EGRESS BOUNDARY (`--net off`, D1): the sandbox gets its own
|
|
20
|
+
* network namespace (--unshare-net) and NOTHING is brought up — no TCP,
|
|
21
|
+
* no DNS, no loopback, no egress of any kind, at the kernel. This is the
|
|
22
|
+
* complete boundary, for untrusted code, evals, and data-only work; model
|
|
23
|
+
* access is impossible by design (a harness that needs the model will fail
|
|
24
|
+
* loudly with connection refused).
|
|
25
|
+
*
|
|
26
|
+
* Why there is no "--net proxy" (netns cut with a single hole to the
|
|
27
|
+
* proxy): rootless Linux cannot express it. AF_UNIX pathname sockets are
|
|
28
|
+
* NETWORK-NAMESPACE-SCOPED — a socket bind-mounted across the netns wall
|
|
29
|
+
* is unreachable (empirically ECONNREFUSED, see ADR 0011), bwrap closes
|
|
30
|
+
* every inherited fd (so no SCM_RIGHTS broker), and the userspace network
|
|
31
|
+
* helpers (pasta/slirp4netns) provide no outbound port allowlist. A
|
|
32
|
+
* boundary that only works when the right helper is present would be a
|
|
33
|
+
* suggestion, not enforcement — so the shipped modes are the two REAL
|
|
34
|
+
* ones: shared (no claim) and off (kernel-complete). The proxy's own
|
|
35
|
+
* PROXY_SOCKET (0600 AF_UNIX) remains the model-path choke point for
|
|
36
|
+
* every non-sandboxed surface; `uap proxy connect` re-serves it on local
|
|
37
|
+
* TCP for clients that cannot speak AF_UNIX.
|
|
11
38
|
*
|
|
12
39
|
* Env:
|
|
13
40
|
* UAP_SANDBOX_WORKDIR workdir to make writable (default: cwd)
|
|
14
|
-
* UAP_SANDBOX_ALLOW extra writable paths, colon-separated
|
|
41
|
+
* UAP_SANDBOX_ALLOW extra writable paths, colon-separated (UNRECORDED)
|
|
42
|
+
* UAP_SANDBOX_NET 'off' to default the net mode (shared otherwise)
|
|
43
|
+
* UAP_SANDBOX_GRANTS pins the grant ledger file (tests, odd layouts)
|
|
44
|
+
* UAP_SANDBOX_AUDIT pins the audit JSONL file (tests, odd layouts)
|
|
45
|
+
* UAP_SANDBOX_GRANTS_OFF=1 resolve zero grants (escape hatch; the sandbox itself stays)
|
|
15
46
|
* UAP_SANDBOX_OFF=1 bypass the sandbox entirely (run the command as-is)
|
|
16
47
|
*/
|
|
17
48
|
import { spawnSync } from 'child_process';
|
|
18
49
|
import { existsSync, realpathSync } from 'fs';
|
|
19
50
|
import { homedir } from 'os';
|
|
20
51
|
import { join } from 'path';
|
|
52
|
+
import chalk from 'chalk';
|
|
53
|
+
import { grantAuthority, listAuthority, resolveSessionGrants, revokeAuthority, auditSandboxUse, sandboxGrantsPath, sandboxAuditPath, verifyLedgerIntegrity, } from '../policies/sandbox-grants.js';
|
|
54
|
+
import { pathCoversAnchorDir } from '../policies/sandbox-anchor.js';
|
|
55
|
+
import { termSafe } from '../utils/terminal-safe.js';
|
|
56
|
+
function fail(msg, code = 2) {
|
|
57
|
+
console.error(`uap sandbox: ${msg}`);
|
|
58
|
+
process.exit(code);
|
|
59
|
+
}
|
|
60
|
+
function hasBwrap() {
|
|
61
|
+
const r = spawnSync('bwrap', ['--version'], { stdio: 'ignore' });
|
|
62
|
+
return !r.error && r.status === 0;
|
|
63
|
+
}
|
|
64
|
+
function planError(msg) {
|
|
65
|
+
return { error: msg };
|
|
66
|
+
}
|
|
67
|
+
/** Compute the bwrap invocation. Pure: a function of its inputs only — the
|
|
68
|
+
* CALLER resolves process.env into `envNet`/`existingCustomHeaders`. */
|
|
69
|
+
export function planSandbox(input) {
|
|
70
|
+
const workdir = input.workdir;
|
|
71
|
+
// Guard: never sandbox with an over-broad workdir — it would expose the tree.
|
|
72
|
+
if (workdir === input.home || workdir === '/' || workdir === '/home') {
|
|
73
|
+
return planError(`refusing to sandbox with workdir='${workdir}' (too broad)`);
|
|
74
|
+
}
|
|
75
|
+
const netMode = input.net === 'off' || input.net === 'shared'
|
|
76
|
+
? input.net
|
|
77
|
+
: input.envNet === 'off'
|
|
78
|
+
? 'off'
|
|
79
|
+
: 'shared';
|
|
80
|
+
// Read-only root with writable "holes".
|
|
81
|
+
const args = [
|
|
82
|
+
'--ro-bind', '/', '/',
|
|
83
|
+
'--dev', '/dev',
|
|
84
|
+
'--proc', '/proc',
|
|
85
|
+
'--tmpfs', '/run',
|
|
86
|
+
'--die-with-parent',
|
|
87
|
+
'--new-session',
|
|
88
|
+
'--unshare-pid',
|
|
89
|
+
];
|
|
90
|
+
if (netMode === 'off') {
|
|
91
|
+
// The egress boundary: a network namespace with NOTHING brought up —
|
|
92
|
+
// not even loopback. Any connect() fails at the kernel.
|
|
93
|
+
args.push('--unshare-net');
|
|
94
|
+
}
|
|
95
|
+
// writable holes:
|
|
96
|
+
args.push('--bind', workdir, workdir, '--bind', '/tmp', '/tmp', '--tmpfs', '/var/tmp');
|
|
97
|
+
for (const rel of ['.claude', '.cache', '.npm']) {
|
|
98
|
+
const p = join(input.home, rel);
|
|
99
|
+
if (existsSync(p))
|
|
100
|
+
args.push('--bind', p, p);
|
|
101
|
+
}
|
|
102
|
+
const grantedPaths = [];
|
|
103
|
+
// Seeded with the holes the floor already binds, so a legacy entry matching
|
|
104
|
+
// one skips its (harmless, bwrap-tolerated) duplicate bind. The grants loop
|
|
105
|
+
// above only WRITES the set (a grant of /tmp or the workdir legitimately
|
|
106
|
+
// re-binds them — bwrap tolerates the duplicate mount); only the legacy
|
|
107
|
+
// loop reads it.
|
|
108
|
+
const boundPaths = new Set([workdir, '/tmp']);
|
|
109
|
+
// The breadth trio is checked against the RESOLVED value, and $HOME can
|
|
110
|
+
// itself be a symlink (/home/u -> /disk/users/u): compare against BOTH the
|
|
111
|
+
// caller's spelling and its resolution, or an entry pointing at the real
|
|
112
|
+
// home through the symlink would bind the whole home (security review).
|
|
113
|
+
const homeResolved = (() => {
|
|
114
|
+
try {
|
|
115
|
+
return realpathSync(input.home);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return input.home;
|
|
119
|
+
}
|
|
120
|
+
})();
|
|
121
|
+
const tooBroad = (p) => p === '/' || p === '/home' || p === input.home || p === homeResolved;
|
|
122
|
+
for (const p of input.grants.paths) {
|
|
123
|
+
// TOCTOU (security review): the row's path was realpath-validated at
|
|
124
|
+
// LOAD; a concurrent writer could swap it for a symlink in the
|
|
125
|
+
// load→exec window. Resolve AGAIN at plan time, re-check breadth on the
|
|
126
|
+
// RESOLVED value, and bind what the resolution says — not the row's
|
|
127
|
+
// word for it. (A microsecond window remains between this resolution
|
|
128
|
+
// and bwrap's own; documented as residual in ADR 0011.)
|
|
129
|
+
let resolved;
|
|
130
|
+
try {
|
|
131
|
+
resolved = realpathSync(p);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
continue; // vanished between load and plan — open nothing
|
|
135
|
+
}
|
|
136
|
+
if (tooBroad(resolved))
|
|
137
|
+
continue;
|
|
138
|
+
// The anchor dir is "the one hole that must never open" (grant minting
|
|
139
|
+
// refuses it outright); plan time re-checks because a grant minted under
|
|
140
|
+
// a different anchor-dir pin could otherwise open it after a re-pin.
|
|
141
|
+
if (pathCoversAnchorDir(resolved))
|
|
142
|
+
continue;
|
|
143
|
+
grantedPaths.push(resolved);
|
|
144
|
+
boundPaths.add(resolved);
|
|
145
|
+
args.push('--bind', resolved, resolved);
|
|
146
|
+
}
|
|
147
|
+
const refusedLegacy = [];
|
|
148
|
+
const legacyBound = [];
|
|
149
|
+
for (const p of input.legacyAllow) {
|
|
150
|
+
// The legacy env is UNRECORDED authority — that is the whole complaint
|
|
151
|
+
// — so it gets the SAME plan-time re-check recorded grants get:
|
|
152
|
+
// resolve at plan time, refuse over-broad resolutions, bind what the
|
|
153
|
+
// resolution says. An env var in a shell history is not consent, and
|
|
154
|
+
// unrecorded must not mean unchecked.
|
|
155
|
+
if (!p)
|
|
156
|
+
continue;
|
|
157
|
+
let resolved;
|
|
158
|
+
try {
|
|
159
|
+
resolved = realpathSync(p);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
continue; // nonexistent entries stay inert, as before
|
|
163
|
+
}
|
|
164
|
+
if (tooBroad(resolved) || pathCoversAnchorDir(resolved)) {
|
|
165
|
+
// Raw env values are foreign strings reaching an operator terminal
|
|
166
|
+
// exactly when attention is on them — termSafe before interpolating.
|
|
167
|
+
refusedLegacy.push(`${termSafe(p)} → ${termSafe(resolved)}`);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (boundPaths.has(resolved))
|
|
171
|
+
continue; // already a writable hole; no dup binds
|
|
172
|
+
boundPaths.add(resolved);
|
|
173
|
+
legacyBound.push(resolved);
|
|
174
|
+
args.push('--bind', resolved, resolved);
|
|
175
|
+
}
|
|
176
|
+
// The consent store must be TAMPER-PROOF from the untrusted side: ro-bind
|
|
177
|
+
// the ledger and audit files over their host paths so a sandboxed agent
|
|
178
|
+
// can neither plant grant rows nor forge audit lines (security review
|
|
179
|
+
// — a planted well-formed `paths:["/etc"]` row opened the hole for real).
|
|
180
|
+
// A bind-mounted file cannot be unlinked or replaced inside the namespace;
|
|
181
|
+
// a MISSING file gets /dev/null bound at its path so planting one is
|
|
182
|
+
// equally impossible (it reads empty and refuses writes).
|
|
183
|
+
for (const target of [input.grantsLedgerPath, input.auditLogPath]) {
|
|
184
|
+
if (!target)
|
|
185
|
+
continue;
|
|
186
|
+
args.push('--ro-bind', existsSync(target) ? target : '/dev/null', target);
|
|
187
|
+
}
|
|
188
|
+
const setenv = {
|
|
189
|
+
HOME: input.home,
|
|
190
|
+
UAP_SANDBOX_ACTIVE: '1',
|
|
191
|
+
};
|
|
192
|
+
if (input.session)
|
|
193
|
+
setenv.UAP_SESSION_ID = input.session;
|
|
194
|
+
const notes = [];
|
|
195
|
+
if (netMode === 'off') {
|
|
196
|
+
notes.push('net: OFF (kernel egress boundary — no network at all, not even loopback; model access impossible by design)');
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
notes.push('net: shared (the sandbox has normal network)');
|
|
200
|
+
}
|
|
201
|
+
if (grantedPaths.length > 0)
|
|
202
|
+
notes.push(`granted holes: ${grantedPaths.join(', ')}`);
|
|
203
|
+
if (input.grants.paths.length > 0 && grantedPaths.length !== input.grants.paths.length) {
|
|
204
|
+
notes.push('(some granted paths were not opened: no longer present, or their plan-time resolution is over-broad)');
|
|
205
|
+
}
|
|
206
|
+
if (refusedLegacy.length > 0) {
|
|
207
|
+
notes.push(`refused UAP_SANDBOX_ALLOW entries: ${refusedLegacy.join(', ')} — /, /home, $HOME, and the trust-anchor dir are never writable holes`);
|
|
208
|
+
}
|
|
209
|
+
if (input.legacyAllow.filter(Boolean).length > 0) {
|
|
210
|
+
// The raw env spelling is the operator's own consent surface — show it
|
|
211
|
+
// verbatim (termSafe'd: env values are foreign strings too).
|
|
212
|
+
notes.push(`UNRECORDED allow (legacy env, consider 'uap sandbox grant'): ${input.legacyAllow.map((p) => termSafe(p)).join(':')}`);
|
|
213
|
+
}
|
|
214
|
+
const argv = [...args];
|
|
215
|
+
for (const [k, v] of Object.entries(setenv)) {
|
|
216
|
+
argv.push('--setenv', k, v);
|
|
217
|
+
}
|
|
218
|
+
// Tell the proxy this session is sandboxed so it can strip MCP tools the
|
|
219
|
+
// bubblewrap sandbox can't reach (the claude-in-chrome browser extension
|
|
220
|
+
// socket is unreachable here — offering browser_batch guarantees dead-end
|
|
221
|
+
// loops). Claude Code forwards ANTHROPIC_CUSTOM_HEADERS verbatim to its
|
|
222
|
+
// endpoint; append rather than clobber any pre-existing value.
|
|
223
|
+
const customHeaders = sandboxCustomHeaders(input.existingCustomHeaders);
|
|
224
|
+
argv.push('--setenv', 'ANTHROPIC_CUSTOM_HEADERS', customHeaders);
|
|
225
|
+
argv.push('--chdir', workdir, ...input.command);
|
|
226
|
+
return {
|
|
227
|
+
plan: {
|
|
228
|
+
argv,
|
|
229
|
+
inner: input.command,
|
|
230
|
+
setenv: { ...setenv, ANTHROPIC_CUSTOM_HEADERS: customHeaders },
|
|
231
|
+
netMode,
|
|
232
|
+
grantedPaths,
|
|
233
|
+
legacyBound,
|
|
234
|
+
legacyRefused: refusedLegacy,
|
|
235
|
+
notes,
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
}
|
|
21
239
|
/**
|
|
22
240
|
* Build the ANTHROPIC_CUSTOM_HEADERS value for a sandboxed session: append the
|
|
23
241
|
* `X-Uap-Sandbox: 1` marker (which the proxy uses to strip sandbox-unreachable
|
|
@@ -36,16 +254,119 @@ export function sandboxCustomHeaders(existing) {
|
|
|
36
254
|
.some((h) => h.trim().toLowerCase() === marker.toLowerCase());
|
|
37
255
|
return already ? prior : `${prior}\n${marker}`;
|
|
38
256
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
257
|
+
// ---------------------------------------------------------------------------
|
|
258
|
+
// Grant verbs (D2).
|
|
259
|
+
// ---------------------------------------------------------------------------
|
|
260
|
+
const GRANT_VERBS = new Set(['grant', 'grants', 'revoke']);
|
|
261
|
+
/**
|
|
262
|
+
* Should `command[0]` be dispatched as a ledger verb? Only when the
|
|
263
|
+
* invocation did NOT use the `--` separator: `uap sandbox -- revoke …` means
|
|
264
|
+
* the operator wants to run a BINARY named `revoke`, and a positional
|
|
265
|
+
* intercept that cannot be escaped would shadow legitimate commands (P4
|
|
266
|
+
* review finding). Exposed for the CLI-surface tests.
|
|
267
|
+
*/
|
|
268
|
+
export function shouldDispatchGrantVerb(command, argv = process.argv) {
|
|
269
|
+
if (!command.length || !GRANT_VERBS.has(command[0]))
|
|
270
|
+
return false;
|
|
271
|
+
return !argv.slice(2).includes('--');
|
|
42
272
|
}
|
|
43
|
-
function
|
|
44
|
-
const
|
|
45
|
-
return
|
|
273
|
+
function grantsDisabled() {
|
|
274
|
+
const v = process.env.UAP_SANDBOX_GRANTS_OFF;
|
|
275
|
+
return v === '1' || v === 'true' || v === 'yes';
|
|
46
276
|
}
|
|
47
|
-
|
|
48
|
-
|
|
277
|
+
function resolveSessionGrantsSafe(projectRoot, session) {
|
|
278
|
+
const none = { grants: [], paths: [] };
|
|
279
|
+
if (!session || grantsDisabled())
|
|
280
|
+
return none;
|
|
281
|
+
try {
|
|
282
|
+
return resolveSessionGrants(projectRoot, session);
|
|
283
|
+
}
|
|
284
|
+
catch (err) {
|
|
285
|
+
console.warn(`[sandbox] grant resolution failed (continuing with NO granted holes): ${err instanceof Error ? err.message : String(err)}`);
|
|
286
|
+
return none;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
async function grantVerb(args, options) {
|
|
290
|
+
const verb = args[0];
|
|
291
|
+
const projectRoot = process.cwd();
|
|
292
|
+
if ((verb === 'grant' || verb === 'revoke') && process.env.UAP_SANDBOX_ACTIVE === '1') {
|
|
293
|
+
// Consent cannot come from the thing being guarded (P4 security
|
|
294
|
+
// review): UAP_SANDBOX_ACTIVE is set by the sandbox itself, on the
|
|
295
|
+
// UNTRUSTED side, so a shell inside a sandbox must not be able to
|
|
296
|
+
// write new authority or remove the operator's. Listing stays
|
|
297
|
+
// available (read-only — the agent can see what it was granted).
|
|
298
|
+
fail('refusing to grant/revoke from inside a sandbox — consent must come from the operator (run it outside the sandbox)');
|
|
299
|
+
}
|
|
300
|
+
if (verb === 'grant') {
|
|
301
|
+
const paths = args.slice(1);
|
|
302
|
+
const input = {
|
|
303
|
+
sessionId: String(options.session || process.env.UAP_SESSION_ID || process.env.CLAUDE_SESSION_ID || ''),
|
|
304
|
+
paths,
|
|
305
|
+
reason: String(options.reason || ''),
|
|
306
|
+
ttlSecs: options.ttl === undefined ? undefined : Number(options.ttl),
|
|
307
|
+
};
|
|
308
|
+
const r = grantAuthority(projectRoot, input);
|
|
309
|
+
if (!r.ok)
|
|
310
|
+
fail(r.error);
|
|
311
|
+
console.log(chalk.green(`✓ grant ${r.grant.id}`) +
|
|
312
|
+
` — session '${r.grant.sessionId}' may write:\n ${r.grant.paths.join('\n ')}` +
|
|
313
|
+
chalk.dim(`\n reason: ${r.grant.reason}\n expires: ${r.grant.expiresAt} (granted by ${r.grant.grantedBy})`));
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
if (verb === 'grants') {
|
|
317
|
+
const sid = String(options.session || '');
|
|
318
|
+
// Tamper evidence (ADR 0011 anchor): the listing is the inspection
|
|
319
|
+
// surface, so the integrity verdict is stated here — on the human path
|
|
320
|
+
// as a red banner, on --json via stderr so the data stays pure.
|
|
321
|
+
const integrity = verifyLedgerIntegrity(projectRoot);
|
|
322
|
+
if (integrity.state === 'mismatch') {
|
|
323
|
+
const msg = `ledger INTEGRITY MISMATCH — ${integrity.detail}. Treat every listed row as unverified.`;
|
|
324
|
+
if (options.json)
|
|
325
|
+
console.error(`[sandbox] ${msg}`);
|
|
326
|
+
else
|
|
327
|
+
console.log(chalk.red(`⚠ ${msg}`));
|
|
328
|
+
}
|
|
329
|
+
else if (integrity.state === 'unanchored' && !options.json) {
|
|
330
|
+
console.log(chalk.dim(`ℹ ${integrity.detail}`));
|
|
331
|
+
}
|
|
332
|
+
const all = listAuthority(projectRoot, sid || undefined);
|
|
333
|
+
if (options.json) {
|
|
334
|
+
console.log(JSON.stringify(all, null, 2));
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
if (all.length === 0) {
|
|
338
|
+
console.log(sid ? `No active grants for session '${sid}'.` : 'No active grants.');
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
for (const g of all) {
|
|
342
|
+
console.log(`${chalk.green(g.id)} session '${g.sessionId}' expires ${g.expiresAt}` +
|
|
343
|
+
`\n ${g.paths.join('\n ')}` +
|
|
344
|
+
chalk.dim(`\n reason: ${g.reason} (granted by ${g.grantedBy})`));
|
|
345
|
+
}
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
if (verb === 'revoke') {
|
|
349
|
+
const id = args[1];
|
|
350
|
+
if (!id)
|
|
351
|
+
fail('usage: uap sandbox revoke <grantId>');
|
|
352
|
+
if (!revokeAuthority(projectRoot, id)) {
|
|
353
|
+
// Not found, or the ledger refused to persist the removal — either way
|
|
354
|
+
// the grant may still be ACTIVE, so the refusal must not sound like
|
|
355
|
+
// "nothing to do" (the persist failure already warned above).
|
|
356
|
+
fail(`could not revoke '${id}' — it is not in the ledger, or the ledger failed to persist the removal`);
|
|
357
|
+
}
|
|
358
|
+
console.log(chalk.green(`✓ revoked ${id}`));
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
fail(`unknown sandbox grant verb '${verb}' (grant | grants | revoke)`);
|
|
362
|
+
}
|
|
363
|
+
// ---------------------------------------------------------------------------
|
|
364
|
+
// Command entry.
|
|
365
|
+
// ---------------------------------------------------------------------------
|
|
366
|
+
export async function sandboxCommand(command, options = {}) {
|
|
367
|
+
// Belt-and-braces: commander v12 strips the `--` separator itself (the
|
|
368
|
+
// marker never reaches command[]), but older parsers and hand-built
|
|
369
|
+
// invocations (tests) may pass it through — strip if it survived.
|
|
49
370
|
if (command[0] === '--')
|
|
50
371
|
command = command.slice(1);
|
|
51
372
|
if (process.env.UAP_SANDBOX_OFF === '1') {
|
|
@@ -54,8 +375,15 @@ export async function sandboxCommand(command) {
|
|
|
54
375
|
const r = spawnSync(command[0], command.slice(1), { stdio: 'inherit' });
|
|
55
376
|
process.exit(r.status ?? (r.error ? 127 : 0));
|
|
56
377
|
}
|
|
378
|
+
// Grant verbs are ledger operations, not sandbox runs — but only when the
|
|
379
|
+
// invocation did NOT use the `--` separator (see shouldDispatchGrantVerb).
|
|
380
|
+
if (shouldDispatchGrantVerb(command)) {
|
|
381
|
+
await grantVerb(command, options);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
57
384
|
if (command.length === 0) {
|
|
58
|
-
fail('no command given. Usage: uap sandbox -- <command> [args...]'
|
|
385
|
+
fail('no command given. Usage: uap sandbox [--session <id>] [--net shared|off] -- <command> [args...]; ' +
|
|
386
|
+
`authority: uap sandbox grant <path...> --session <id> --reason "..." | grants | revoke <id>`);
|
|
59
387
|
}
|
|
60
388
|
if (!hasBwrap()) {
|
|
61
389
|
fail('bwrap (bubblewrap) not found — refusing to run unsandboxed. ' +
|
|
@@ -69,41 +397,62 @@ export async function sandboxCommand(command) {
|
|
|
69
397
|
catch {
|
|
70
398
|
workdir = process.env.UAP_SANDBOX_WORKDIR || process.cwd();
|
|
71
399
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
400
|
+
const session = String(options.session || process.env.UAP_SESSION_ID || process.env.CLAUDE_SESSION_ID || '');
|
|
401
|
+
const rawNet = options.net;
|
|
402
|
+
if (rawNet !== undefined && rawNet !== 'off' && rawNet !== 'shared') {
|
|
403
|
+
// Loud, not silent: an unknown --net value (e.g. the documented-then-cut
|
|
404
|
+
// 'proxy') silently downgrading to full network would be the exact hole
|
|
405
|
+
// the boundary exists to close.
|
|
406
|
+
fail(`unknown --net mode '${String(rawNet)}' (shared | off)`);
|
|
75
407
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
'
|
|
84
|
-
'--new-session',
|
|
85
|
-
// writable holes:
|
|
86
|
-
'--bind', workdir, workdir,
|
|
87
|
-
'--bind', '/tmp', '/tmp',
|
|
88
|
-
'--tmpfs', '/var/tmp',
|
|
89
|
-
];
|
|
90
|
-
for (const rel of ['.claude', '.cache', '.npm']) {
|
|
91
|
-
const p = join(home, rel);
|
|
92
|
-
if (existsSync(p))
|
|
93
|
-
args.push('--bind', p, p);
|
|
408
|
+
const netOpt = rawNet === 'off' ? 'off' : rawNet === 'shared' ? 'shared' : undefined;
|
|
409
|
+
// The env default is validated exactly like the flag (security review):
|
|
410
|
+
// 'OFF', 'off ', '0ff' silently meaning FULL network is the exact hole
|
|
411
|
+
// the boundary exists to close. Whitespace is trimmed (shell quirks),
|
|
412
|
+
// anything else fails loud.
|
|
413
|
+
const envNet = process.env.UAP_SANDBOX_NET?.trim();
|
|
414
|
+
if (envNet && envNet !== 'shared' && envNet !== 'off') {
|
|
415
|
+
fail(`unknown UAP_SANDBOX_NET value '${envNet}' (shared | off)`);
|
|
94
416
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
417
|
+
const legacyAllow = (process.env.UAP_SANDBOX_ALLOW || '').split(':');
|
|
418
|
+
const grants = resolveSessionGrantsSafe(process.cwd(), session);
|
|
419
|
+
const planned = planSandbox({
|
|
420
|
+
command,
|
|
421
|
+
session: session || undefined,
|
|
422
|
+
net: netOpt,
|
|
423
|
+
workdir,
|
|
424
|
+
home,
|
|
425
|
+
legacyAllow,
|
|
426
|
+
grants,
|
|
427
|
+
envNet,
|
|
428
|
+
existingCustomHeaders: process.env.ANTHROPIC_CUSTOM_HEADERS,
|
|
429
|
+
// Ro-bound into the namespace by the planner: the consent store must be
|
|
430
|
+
// untouchable from the sandboxed side (security review finding 1).
|
|
431
|
+
grantsLedgerPath: sandboxGrantsPath(process.cwd()),
|
|
432
|
+
auditLogPath: sandboxAuditPath(process.cwd()),
|
|
433
|
+
});
|
|
434
|
+
if (planned.error)
|
|
435
|
+
fail(planned.error);
|
|
436
|
+
const plan = planned.plan;
|
|
437
|
+
// The consent record: who granted, what was actually OPENED (not merely
|
|
438
|
+
// resolved — a granted path that no longer exists opens nothing and must
|
|
439
|
+
// not be recorded as authority exercised), what ran unrecorded, and the
|
|
440
|
+
// net boundary actually engaged.
|
|
441
|
+
const openedGrants = grants.grants.filter((g) => g.paths.some((p) => plan.grantedPaths.includes(p)));
|
|
442
|
+
// The legacy-env record must state what ACTUALLY opened vs what was
|
|
443
|
+
// refused at plan time — recording a refused entry under the run's allow
|
|
444
|
+
// would attribute authority the run never had (the banner and the
|
|
445
|
+
// durable record must agree).
|
|
446
|
+
auditSandboxUse(process.cwd(), session, { grants: openedGrants, paths: plan.grantedPaths }, plan.legacyBound, plan.legacyRefused, plan.netMode);
|
|
447
|
+
console.error(chalk.dim(`uap sandbox: workdir ${workdir} (writable); everything else is EROFS`));
|
|
448
|
+
for (const n of plan.notes)
|
|
449
|
+
console.error(chalk.dim(` ${n}`));
|
|
450
|
+
if (grantsDisabled())
|
|
451
|
+
console.error(chalk.dim(' grants: ledger off (UAP_SANDBOX_GRANTS_OFF=1)'));
|
|
452
|
+
if (!session) {
|
|
453
|
+
console.error(chalk.dim(' grants: none (no --session; grant one with: uap sandbox grant <path> --session <id> --reason "...")'));
|
|
98
454
|
}
|
|
99
|
-
|
|
100
|
-
// bubblewrap sandbox can't reach (the claude-in-chrome browser extension
|
|
101
|
-
// socket is unreachable here — offering browser_batch guarantees dead-end
|
|
102
|
-
// loops). Claude Code forwards ANTHROPIC_CUSTOM_HEADERS verbatim to its
|
|
103
|
-
// endpoint; append rather than clobber any pre-existing value.
|
|
104
|
-
const customHeaders = sandboxCustomHeaders(process.env.ANTHROPIC_CUSTOM_HEADERS);
|
|
105
|
-
args.push('--setenv', 'HOME', home, '--setenv', 'UAP_SANDBOX_ACTIVE', '1', '--setenv', 'ANTHROPIC_CUSTOM_HEADERS', customHeaders, '--chdir', workdir);
|
|
106
|
-
const r = spawnSync('bwrap', [...args, ...command], { stdio: 'inherit' });
|
|
455
|
+
const r = spawnSync('bwrap', plan.argv, { stdio: 'inherit' });
|
|
107
456
|
if (r.error)
|
|
108
457
|
fail(`failed to launch bwrap: ${r.error.message}`, 127);
|
|
109
458
|
process.exit(r.status ?? 1);
|
package/dist/cli/sandbox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/cli/sandbox.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/cli/sandbox.ts"],"names":[],"mappings":"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"}
|