Operator Action Packet — Deny-by-Default Sandbox Host for Phase-2 MVP
Operator Action Packet — Deny-by-Default Sandbox Host (Phase-2 MVP, B4′)
Produced under decision B (
BUILD_PROMPT_READY_BUT_OPERATOR_SANDBOX_ACTION_REQUIRED). Audience: operator (resource action). Pairs with the gated build prompt. No destructive commands. No assumed owner approval. This packet requests provisioning + attestation; it does not itself provision anything.
1. Why this is needed
The Phase-2 MVP is an offline inspector whose primary enforcement boundary (L1) is a deny-by-default execution sandbox (rev4 §12.1). The harness (sandbox profile + in-process guards + negative tests) is build-scope and will be authored in the build. What only the operator can do is run the harness in a real deny-by-default sandbox and attest the boundaries hold — that attestation is the B4′ acceptance gate. Without it, the MVP fails its own P1 self-check (BLOCKED / exit 3) and ~11 of 45 acceptance tests cannot pass.
Good news (governed evidence): a container runtime is already deployed and active on the host — mcp__claude_ai_Incomex_VPS__list_docker (read-only) shows 11 running containers (postgres:16, directus:11.5, qdrant, nginx:alpine) including an ephemeral test container pg-restore-test-20260520T031054Z. So the runtime exists; no new runtime install is required for the recommended option.
2. Exact sandbox requirement (the minimum bar)
A single run that satisfies all of:
| # | Requirement | Realization |
|---|---|---|
| 1 | No network | --network none (Docker/Podman) / bwrap --unshare-net |
| 2 | Read-only input mount only | -v <input>:/in:ro / --ro-bind <input> /in |
| 3 | Write-only output mount only | -v <output>:/out / --bind <output> /out (the only writable path) |
| 4 | No home / project / /etc / secret mounts | minimal image; no extra -v; mount namespace |
| 5 | Scrubbed environment | explicit minimal env / --clearenv; no tokens, conn-strings, creds |
| 6 | Syscall restriction | --security-opt seccomp=<profile>.json denying execve/execveat/socket/connect/bind/ptrace; --security-opt no-new-privileges; --cap-drop ALL |
3. Recommended implementation
- Primary — Option B (Docker/Podman deny-by-default container) on the existing host runtime. Podman-rootless preferred for least privilege if available. Realizes §12.1 1:1; no new runtime install.
- Fallback — Option C (bubblewrap) where a container daemon/privilege is unavailable;
bwrapneeds no daemon (may require installingbubblewrap— operator's call; install is out of scope for Claude). - Acceptance venue fallback — Option D (CI): a deny-by-default ephemeral CI runner if local attestation is impractical.
4. What the operator must provide
- A provisioned deny-by-default sandbox per §2 (Option B recommended), isolated from production (its own throwaway container; do not reuse a prod container).
- The
seccompprofile path and the two mount paths (RO input, WO output) used. - Read-only attestation evidence (so Agent can verify later without running anything itself):
- mount table inside the sandbox showing exactly two mounts (RO
/in, WO/out) and nothing else; - confirmation the network namespace is empty (no interfaces/routes);
- the in-sandbox env keyset (names only) showing no secret/token/conn-string;
- a negative-probe transcript showing
execve()→EPERM,socket()/connect()→EPERM/EAFNOSUPPORT, a write to/in→EROFS, and a write outside/out→EROFS/EACCES.
- mount table inside the sandbox showing exactly two mounts (RO
5. How Agent will verify it later
Agent will read the attestation evidence (governed/native, read-only) and bind it to matrix tests #24–#37 (L1) — confirming each boundary's proof-of-block (seccomp EPERM, mount table, env keyset) before declaring B4′ acceptance. Agent will not run the sandbox itself.
6. Risk if waived
If B4′ is waived (sandbox not attested), the MVP's L1 primary boundary is unproven; in-process L2/L3 guards are bypassable in principle (Codex's documented objection), so the inspector could in principle perform an unsafe access it claims to deny. The MVP's own P1 self-check is designed to fail closed (BLOCKED / exit 3) in that case — so a waiver does not yield a runnable accepted MVP, only a refusing one. Waiving B4′ is not recommended.
7. Fallback if unavailable
If no deny-by-default sandbox can be provisioned or attested on any venue (B, C, or D), the build stays BLOCKED (rev4 §21 hard fallback B); escalate to the owner as a genuine resource constraint. This is the only path on which the sandbox would become a true blocker — and current evidence (runtime already deployed) indicates it is not that path.
Action-ready. No destructive command is included; the operator chooses and executes provisioning. Claude performed no provisioning, install, sandbox creation, or production mutation in authoring this packet.