Locked-down defences#
The canonical map of every defence the sandbox enforces, the bwrap
primitive that delivers it, and the /verify-sandbox
check number that proves it. Each row corresponds to one observed
exfiltration path closed by the matching primitive.
Defence → primitive → check#
Defence |
bwrap primitive |
Verify |
|---|---|---|
Sandbox is actually entered |
|
check 01 |
Setuid escalation blocked |
|
check 02 |
Strict-under- |
|
check 03 |
Host env vars scrubbed |
|
checks 04, 05 |
Zero capabilities |
|
check 06 |
PID namespace (kill/ptrace scoping) |
|
check 07 |
SysV IPC namespace |
|
check 08 |
UTS namespace |
|
check 09 |
TIOCSTI terminal injection blocked |
|
check 10 |
VS Code IPC bridges masked |
|
check 11 |
User runtime dir masked |
|
check 12 |
Docker/Compose secrets masked |
|
check 13 |
|
|
check 14 |
|
|
check 15 |
Curated gitconfig in effect |
|
check 16 |
Chrome browser-extension RPC channel disabled |
shadow injects |
check 03 (regression manifests as browser dirs under |
Lateral-movement (RFC1918) egress isolation |
netns + |
no jail-aware check needed — check 06 ( |
Notes#
Network egress is jailed by default#
As of 2026-06-18 the egress jail (15. Jail Claude’s egress in a per-process netns with a routing allowlist) is the
default posture: Claude runs in its own per-process network namespace,
bridged to the internet by pasta, with a routing allowlist that
blackholes RFC1918 (10/8, 172.16/12, 192.168/16, the connected
subnet) and link-local (169.254/16) so a compromised session cannot
pivot to internal hosts or lab devices. api.anthropic.com,
GitHub/GitLab, DNS resolvers, and any configured allow-ip devices stay
reachable so Claude still works.
It is fail-closed — if /dev/net/tun, pasta, or unshare is
missing, claude refuses to launch rather than silently dropping back to
open egress. The escape hatch is CLAUDE_SANDBOX_EGRESS_JAIL=0 (env, per
session, or egress-jail = 0 in /etc/claude-sandbox.conf; env wins),
which restores the older shared-host-netns world (--share-net, NOT
unshared; 5. Leave network egress open; egress filtering is out of scope). Only that =0 path shares the
host netns, which is what makes the host’s network identity disclosable
from inside.
The jail sits around bwrap, so /verify-sandbox
passes unchanged inside it — check 06 asserts CapEff=0 (the effective
set, empty even in the jail’s nested userns), not netns state. There is
therefore no PASS/FAIL check for the jail itself (a netns/blackhole check
is a future item); any egress regression makes Claude fail on first use
rather than silently. See the
threat model.
--die-with-parent#
Implicit: --die-with-parent — the sandbox disappears the moment
Claude does.
Refusal-on-failure#
If the host cannot run unprivileged user namespaces, the installer refuses with a specific actionable diagnostic. Silent degradation to “Claude installed but not sandboxed” is itself a UX failure mode, so it is not allowed to happen.