bash tool executes a command it runs inside an OS-level sandbox
configured from the agent’s workspace. This is filesystem + network enforcement
at the kernel level — a separate concern from policy enforcement,
which decides whether a tool may be invoked at all.
Runtime requirement
Thebash tool depends on srt (Anthropic’s sandbox-runtime). It wraps
each command in sandbox-exec + a Seatbelt profile (macOS) or bubblewrap + a
network namespace + a seccomp filter (Linux).
srt is not
on PATH, run_command raises SrtUnavailableError rather than falling back to
unsandboxed execution — fail closed by design.
Configuration
Tune the boundary throughLocalWorkspace:
| Knob | What it controls | Default |
|---|---|---|
root_dir | Workspace root; reads + writes allowed inside | required |
allowed_domains | Hostnames the proxy forwards | () — no egress |
denied_domains | Hostnames the proxy refuses | () |
extra_read_paths | Read-only paths beyond the workspace | () |
extra_write_paths | Writable paths beyond workspace + /tmp | () |
deny_write_paths | Paths the agent can never write to | () |
allow_unix_sockets | Unix sockets the agent can connect() | () — no IPC |
allow_local_binding | Whether the agent can bind(127.0.0.1, …) | False |
extra_env | Env vars passed into the sandbox | {} |
$HOME, writes allowed
only inside the workspace + /tmp.
allow_unix_sockets and allow_local_binding exist because they’re the two ways
traffic can leave the proxy lane (Unix-domain IPC and inbound localhost).
Default-deny on both; opt in per-deployment when you actually need docker-socket
access, a local dev server, etc.
Env scrubbing
The sandboxed child does not inherit the parent process’s environment. Only an explicit allowlist passes through:PATH(curated baseline including/opt/homebrew/binfor Apple Silicon)HOME(set to the workspace root, so cache writes land insideallowWrite)TMPDIR,TERM- Locale keys:
LANG,LC_ALL,LC_CTYPE,LC_COLLATE,LC_MESSAGES - Anything operator-supplied via
extra_env
AWS_SECRET_ACCESS_KEY, OPENAI_API_KEY,
ANTHROPIC_API_KEY, GH_TOKEN, SSH_AUTH_SOCK, etc. — don’t leak into the
agent. Tools that legitimately need credentials should receive them through
extra_env, where you control exactly what’s passed.
Layering with policy + approval
| Layer | Question | Mechanism |
|---|---|---|
| Policy | Is this tool allowed at all for this caller’s role? | adapter / enforce_policy(...) |
| Approval | Should this specific call go ahead? | enforce_policy(..., approval_handler=...) |
| Sandbox | What can the spawned shell actually do? | OS-level via srt |
bash tool is callable. The approval handler inspects
each call gated by approval_required. The sandbox bounds reach if a call does
run. They’re complementary — deploy whichever combination matches your threat
model.
What the sandbox does NOT do
- Resource limits. No CPU/memory/fork caps. A fork-bomb runs to completion.
Use cgroups or
ulimitif that matters. - Command-string semantics.
srtseessh -c "<command>"as an opaque arg. The sandbox bounds reach, not intent —rm -rf <workspace>is permitted because the workspace is inallowWrite. - Inside-sandbox actions. The sandbox stops the agent from exfiltrating a workspace file over the network or writing outside the boundary, but doesn’t reason about what the agent does within the boundary.