Claude Code Sandboxing
Turn on OS-enforced boundaries around Claude's bash tool. Covers Seatbelt on macOS, bubblewrap on Linux and WSL2, plus network proxy config.
Problem: An AI agent with open access to your disk and network is a risk you cannot hand-wave away. Every npm install pulls down code written by strangers. Every build script runs with your full user rights. Every prompt injection that lands gets the same reach you have. One bad dependency, with no walls in place, can read SSH keys, ship env vars elsewhere, or quietly edit your shell rc files.
Claude Code's sandbox shuts that door. It pushes filesystem and network limits down to the kernel, so the rules no longer depend on trust or on how a prompt is phrased.
Quick setup: One command turns on sandboxing right now:
> /sandbox
A menu appears for picking the sandbox mode. On macOS the feature is already live. For Linux or WSL2, two packages need to be installed first, bubblewrap and socat (instructions below).
Why Permission Prompts Are Not Enough On Their Own
Spend any real time with Claude Code and the pattern is familiar. Claude wants to run a command. Approve. Claude wants to write a file. Approve. Claude wants to run the tests. Approve. Thirty clicks in, you are rubber-stamping the flow without reading a single prompt.
That is approval fatigue. It is a security problem wearing a safety feature's uniform.
More prompts means less attention on each one. Security UX research keeps finding the same result: repeat dialogs train people to click through. You lose twice. Flow still breaks, and protection still degrades.
Sandboxing flips the model. Rather than asking "can this one action happen?" for each step, you set up the fences once. Here is where reads can happen. Here is where writes can happen. Here is what the network can reach. Inside those fences, nothing prompts. Outside, the OS stops the action, not a dialog.
The payoff is fewer interruptions, stronger defenses, and an agent free to work autonomously inside known-safe limits.
How Claude Code Sandboxing Works
Two isolation layers run side by side. Both matter. Take either one out and the remaining one has holes you can drive a truck through.
Filesystem Isolation
The sandboxed bash tool keeps file access to a short list of directories:
- Writes stay inside the working directory plus anything nested underneath
- Reads cover the whole system, apart from paths you have marked as denied
- Out-of-tree edits fail unless you specifically hand out permission
- Custom paths open or close extra directories through the sandbox settings
In practice Claude reads project files and edits code inside your repo, but ~/.bashrc, /usr/local/bin, and anything in ~/.ssh stay out of reach. A malicious npm package that tries to write past those walls is blocked by the OS itself.
Network Isolation
Outbound traffic is routed through a proxy server that lives outside the sandbox:
- Domain allowlist caps the hosts any process is allowed to hit
- Unknown domains pop a permission prompt, so every new host shows up in front of you
- Inherited limits travel with every child process, so a shell a build script spawns cannot slip the rules
- Custom proxies let enterprises send sandbox traffic into their own inspection pipeline
Filesystem walls on their own leave a hole. A hijacked agent might still push source code out to a host the attacker controls. Network walls alone leave the opposite hole. Both layers have to run side by side. The design rests on that.
Enforcement At The Kernel
The sandbox does not depend on app-layer checks. A clever exploit can always route around those. What does the work is a set of kernel security primitives:
- macOS: Seatbelt, the same framework Apple uses to isolate App Store apps
- Linux: bubblewrap (
bwrap), the small unprivileged sandbox tool Flatpak is built on - WSL2: bubblewrap again, no different from native Linux
WSL1 is out. bubblewrap needs features the kernel only exposes under WSL2, namely user and mount namespaces. A native Windows build is planned but not shipping yet.
Every child process a sandboxed command spawns inherits the same limits. Run npm install while sandboxed, and any postinstall hook ends up boxed in too.
Prerequisites and Installation
macOS
Nothing extra to install. Sandboxing runs straight away on the Seatbelt framework already in the OS. Type /sandbox and pick a mode.
Linux and WSL2
You need two packages. bubblewrap does the filesystem isolation and socat handles the network proxy plumbing:
Ubuntu/Debian:
sudo apt-get install bubblewrap socat
Fedora:
sudo dnf install bubblewrap socat
With those installed, type /sandbox in Claude Code. If a dependency is still missing, the menu shows you the install instructions for your platform.
Sandbox Modes: Auto-Allow vs Regular Permissions
Two modes exist. The filesystem and network walls are identical in both of them. What changes is whether a sandboxed command still needs your click to run.
Auto-Allow Mode
A bash command tries running under the sandbox, and if it fits, nothing asks you first. If that same command needs a host that is not on your allowed list, the usual permission flow kicks in. Any ask or deny rule already configured still fires.
Most builders want this mode. The agent has maximum room inside the fences, and prompts only come back when something would cross a fence.
One wrinkle is worth knowing. Auto-allow runs independently of permission mode. Even with "accept edits" turned off, a sandboxed bash command runs without a prompt whenever auto-allow is on. File edits through the Edit tool keep obeying your normal permission rules. Only bash inside the sandbox goes through.
Regular Permissions Mode
Every bash command, sandboxed or not, still routes through the normal permission dialog. The walls remain, and each command also asks you first.
Pick this when you want sandbox protection without dropping per-command review. A good fit for strict environments, or for the first days of tuning a new sandbox config.
Configuring Your Sandbox
Sandbox behavior is tuned through your settings.json. A working example looks like this:
{
"sandbox": {
"mode": "auto-allow",
"allowedDomains": ["registry.npmjs.org", "api.github.com", "pypi.org"],
"network": {
"httpProxyPort": 8080,
"socksProxyPort": 8081
}
}
}Key Settings
mode: Set it to "auto-allow" or "regular". That flag decides if sandboxed commands run on their own or wait for a click.
allowedDomains: Hosts that bash is free to reach without asking. New domains you hit pop up a prompt, and accepting writes the domain into this list for next time.
allowUnixSockets: Controls socket access. Careful here. Allowing /var/run/docker.sock is effectively a pass into the host through the Docker API, which sidesteps the sandbox walls.
allowUnsandboxedCommands: Defaults to true. When a sandbox rule kills a command, Claude may rerun that command unsandboxed after you confirm. Flip to false to kill the retry path.
excludedCommands: A list of commands that skip the sandbox every time. Good for tools that simply refuse to cooperate, like docker.
enableWeakerNestedSandbox: A Linux-only knob for unprivileged Docker setups. It weakens the walls, so reach for it only when the outer container is doing its own isolation.
How Sandboxing Fits Alongside Permissions
Permissions and the sandbox are two independent security layers that back each other up:
Permissions decide which tools are even in reach for Claude Code. They run ahead of any tool call, and they apply to every tool: Bash, Read, Edit, WebFetch, MCP tools, the whole set.
Sandboxing is OS-enforced, and it only shapes what a Bash command (or its subprocesses) can do with the filesystem and the network.
Think defense in depth. First gate: is this tool even allowed? Second gate: once it does run, how far can its reach go?
Security Benefits
Protection Against Prompt Injection
Prompt injection is the single biggest live risk for an AI agent. An attacker hides instructions inside a file, a README, or a web page. Claude reads them as if you wrote them, and starts running attacker commands.
With the sandbox on, even a successful injection runs into hard walls:
Filesystem protection:
- Shell rc files like
~/.bashrcand~/.zshrcare off limits - System binaries under
/bin/or/usr/local/bin/cannot be touched - Any path marked deny in your permission rules is unreadable
Network protection:
- Attacker-controlled servers cannot be used for data exfiltration
- Malicious scripts from unknown domains cannot be downloaded
- API calls to services you have not approved will not go through
- Any domain that is not on the allowed list is unreachable
A Smaller Attack Surface
Injection aside, the sandbox also trims damage from the everyday risks:
- Bad dependencies: any npm, pip, or other library that hides nasty logic in postinstall
- Broken build tools: build-time utilities carrying their own vulnerabilities
- Social engineering: dangerous commands that a user was tricked into running
- Supply chain hits: upstream packages tampered with, so install time turns into code injection
Limits You Should Know About
No sandbox is perfect. Being clear about where the walls have gaps is how you pick a realistic threat model.
Domain Fronting
The network filter picks domains, but it does not do deep packet inspection. Domain fronting, where traffic looks like it is headed for one host but actually lands at another, can slip past the domain filter in some cases.
Unix Socket Escalation
allowUnixSockets can quietly hand out powerful access. Allow /var/run/docker.sock and the sandboxed process now has the full Docker API in its pocket, which in practice means access to the host.
Filesystem Permission Escalation
Writes that are too loose hand out escalation paths. Let the sandbox write into any folder with binaries on $PATH, system config dirs, or user shell rc files and code can end up running under a different security context.
Practical Tips and Compatibility
Docker Does Not Play Nicely
Docker commands will not work under the sandbox. They need a direct line to the Docker daemon. Put docker into excludedCommands so it always runs outside.
Watchman Does Not Play Nicely Either
Facebook's watchman file watcher will not cooperate with a sandboxed process. Running Jest? Tack on the --no-watchman flag.
The Escape Hatch
Every so often a sandboxed command fails because of the walls themselves. Claude can look at the failure and offer to retry with dangerouslyDisableSandbox. That retry runs outside the sandbox, and it still waits for your approval through the usual permission flow.
Custom Proxy Configuration for Enterprises
Orgs with deeper network security needs can pipe sandbox traffic through a proxy of their own for inspection, logging, and hook-up with the rest of the security stack.
The payoff is the ability to:
- Terminate and inspect HTTPS traffic
- Apply rules that reach further than a plain domain block
- Write every outbound request into an audit log
- Tie the sandbox into an existing SIEM or security stack
- Push org-wide rules out through the managed settings scope
Open Source Sandbox Runtime
The runtime ships as its own npm package, open source. Drop it into any agent project you like. No Claude Code required:
npx @anthropic-ai/sandbox-runtime <command-to-sandbox>
Source code is hosted at github.com/anthropic-experimental/sandbox-runtime.
Setting Up Your First Sandbox
A practical path from zero to a working config:
- Deps first (Linux/WSL2 only):
sudo apt-get install bubblewrap socat - Type
/sandboxin Claude Code and pick a mode from the menu - Pick auto-allow if you want the sweet spot between safety and speed
- Use Claude as normal and approve any new domain the prompts ask about
- Revisit the config after a session or two, and sanity check the domain list
- Trim what you don't need by pulling stale domains back out
Start tight. Open things up only when the need is real. Loosening a rule is cheaper than cleaning up from one that was never there.
Stop configuring. Start building.