agent: OS-level isolation for the agent tool boundary (SPEC §10)

harnessd gains --socket mode (Unix socket, trusted uid, mutating ops
serialized); the harness client speaks socket when
HOTPATH_HARNESS_SOCKET is set. scripts/agent-isolated.sh launches an
attempt with the agent tree confined — mountns mode (repo bind-mounted
read-only, CAP_SYS_ADMIN/CAP_SYS_PTRACE dropped; no credential copying)
or user mode (unprivileged hpagent, bench-metal shape).
scripts/isolation-check.sh + just isolation-check verify the boundary
from the agent's side: 19 checks, both modes, all passing — repo
writes, forged ledger INSERTs, trust-binary replacement, rw remounts,
and userns re-entry all refused; the harnessd socket door works.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EcKPWQ3MQD4NdEHwar96u2
This commit is contained in:
Claude
2026-07-10 04:43:08 +00:00
parent 4eef6a7bd4
commit e0c5018008
7 changed files with 395 additions and 32 deletions
+8 -9
View File
@@ -36,15 +36,14 @@ HARNESS_TOOLS = [
]
# Built-in tools we deny at the SDK layer. This is DEFENSE IN DEPTH, not the
# trust boundary. SPEC §10's real boundary is OS-level process/user isolation:
# harnessd runs as a separate process the agent can't bypass, target code runs
# in a no-net container. In THIS dev container the nested agent runs as root
# under a parent Claude Code session, so neither --dangerously-skip-permissions
# nor a can_use_tool callback reliably gates built-ins (settings inherited from
# the parent session shadow them). We enumerate what we can; production runs the
# agent process without host-shell capability at all. What holds regardless:
# propose_patch is the only harness-mediated write path (path-allowlist + git
# apply), and the ledger is append-only (mutation-refusing triggers).
# trust boundary. SPEC §10's real boundary is OS-level isolation, shipped in
# scripts/agent-isolated.sh: this whole process tree runs either inside a
# mount namespace with the repo read-only and CAP_SYS_ADMIN dropped, or as
# the unprivileged hpagent user — verified by `just isolation-check`. Even
# if the nested CLI reaches a shell despite this list (settings inherited
# from a parent session can shadow SDK gating), repo writes fail at the OS.
# What holds regardless: propose_patch is the only harness-mediated write
# path (path-allowlist + git apply), and the ledger is append-only.
BUILTIN_TOOLS_DENIED = [
"Bash", "Read", "Write", "Edit", "Glob", "Grep",
"WebSearch", "WebFetch", "Task", "TodoWrite",