Claude Code sandbox settings: what the sandbox covers, and what still runs outside it

Claude Code's sandbox is an OS-level boundary around shell commands. It's off by default, writes stay in the project when it's on, and reads don't. Here are the defaults, the settings and the gaps.

The short answer

Turn it on with /sandbox or "sandbox": { "enabled": true } in a settings file; it’s off by default.1 Once on, shell commands Claude runs can write only to the working directory, a per-user temp folder and directories you add, and can reach the network only through a local proxy that checks each host against an allowlist that starts empty.1 Reads are not limited: by default a sandboxed command can still read most of the machine, including ~/.ssh and ~/.aws/credentials, so add denyRead entries.1

The sandbox covers shell commands only. Claude’s file tools, MCP servers and hooks run outside it and follow permission rules instead.1

Every MCP tool call goes through your rules first. Here a delete that doesn’t say which rows is stopped before it reaches the database. These are the rules deedglass init starts with; the call is made up.

What the sandbox is

The docs describe it as a boundary the operating system enforces around the shell commands Claude runs, applying to Bash, PowerShell and Monitor commands and the processes they start.1 It uses Seatbelt on macOS and bubblewrap on Linux and WSL2; on native Windows, commands run unsandboxed.1

The difference from permission rules matters. A permission rule matches the text of a command. The sandbox doesn’t care what the command says; it refuses the write or the connection when it happens. A command you never thought to write a rule for, or one that hides its intent behind a script, still can’t write outside the project or call a host you didn’t allow.

The defaults

Default with the sandbox on
Writes Working directory, a per-user temp directory, directories you’ve added; protected paths stay write-denied1
Reads Most of the machine, including ~/.ssh and ~/.aws/credentials1
Network No direct route; a local proxy checks each host against allowed domains, which start empty1
Hosts not on the list Handled by your permission mode: a prompt in Manual mode, refused in dontAsk1
Prompts for sandboxed commands None by default (autoAllowBashIfSandboxed is true)1

Read the last row with care. With the sandbox on, sandboxed commands run without asking, because the boundary replaces the prompt. That’s the trade: fewer prompts in exchange for an OS-enforced limit. It’s a good trade only if the limit is set well.

A settings file that closes the obvious gaps

Using the documented keys (filesystem.denyRead, filesystem.allowWrite, network.allowedDomains, allowUnsandboxedCommands):11

Code Data in JSON, the format software uses to pass records and settings.

{
  "sandbox": {
    "enabled": true,
    "allowUnsandboxedCommands": false,
    "filesystem": {
      "denyRead": ["~/.ssh", "~/.aws", "~/.config/gcloud", "~/.kube", "./.env", "./.env.*"]
    },
    "network": {
      "allowedDomains": ["registry.npmjs.org", "github.com"]
    }
  },
  "permissions": {
    "deny": ["Read(./.env)", "Read(./.env.*)"]
  }
}

What each part does:

  • denyRead closes the default read access to credentials for shell commands.
  • permissions.deny on Read covers the built-in Read tool, which the sandbox doesn’t govern: a denyRead entry doesn’t stop the Read tool.1 You need both.
  • allowedDomains lets package installs and git work; everything else goes through your permission mode.
  • allowUnsandboxedCommands: false turns off the retry outside the sandbox; with it off, Claude Code ignores the dangerouslyDisableSandbox parameter.1

Check the exact key names against the docs for your version; settings evolve.

What runs outside the sandbox

From the docs:1

Runs outside Governed by instead
Read, Edit, Write, WebFetch, WebSearch Permission rules (allowedDomains doesn’t limit WebFetch)
Command hooks Nothing; full access
Local MCP servers Nothing; full access
Plugin monitors, LSP servers, status line and apiKeyHelper commands Nothing; full access
Commands you type at the ! prompt (in most sessions) Nothing
Commands in excludedCommands Nothing: no filesystem limits, no proxy
Unsandboxed retries Claude requests Your approval, unless retries are disabled

The MCP row is the one teams miss. A Postgres MCP server configured with an owner’s connection string runs with full access, sandbox or not. Its limits come from the database role it connects as. Our post on what rds_superuser and neon_superuser hand an agent covers that side, and agents reading .env files covers the file-tool side.

Settings that weaken it

The docs name several, worth searching your settings for:1

  • excludedCommands: matching commands run with no filesystem restrictions and no network proxy. docker compose * is the docs’ example; Docker can mount anything, so an excluded Docker command is effectively unsandboxed root on many machines.
  • filesystem.disabled: true: a sandboxed command can then write files that later commands run or read, and escalate its own access.
  • allowNestedUserNamespaces: true: turns off a boundary; code from a sandboxed command can end up running outside the sandbox.
  • The proxy doesn’t inspect TLS, so it enforces the allowlist by hostname only. An allowed host that serves user content (a paste site, a cloud storage domain) is an exit for data.

Also note what the proxy can’t carry: tools that ignore proxy variables, such as plain ssh and most database drivers, can’t reach allowed hosts.1 That’s usually what you want for an agent, and it explains why a psql to a remote database fails under the sandbox.

How to check it’s working

After enabling it, ask Claude to run three harmless commands and watch what happens:

  1. touch ~/sandbox-test should fail: a write outside the working directory.
  2. cat ~/.ssh/known_hosts should fail once denyRead covers ~/.ssh; without that entry, it succeeds, which is the default read access the docs describe.
  3. curl -sI https://example.com should prompt you or be refused, depending on your permission mode, because example.com isn’t on the allowlist.

If any of these behaves differently, run /status to confirm which settings files loaded, then check the key names against the docs for your version.

A checklist

  • sandbox.enabled: true in user or managed settings.
  • denyRead for ~/.ssh, cloud credential folders and .env files.
  • Matching Read deny rules for the built-in Read tool.
  • allowedDomains limited to package registries and your git host.
  • allowUnsandboxedCommands: false.
  • No broad excludedCommands (especially Docker).
  • MCP servers connect with narrow credentials, since they run outside the sandbox.
  • A PreToolUse hook for destructive commands as a second check.

Compare with Codex’s equivalent in Codex CLI sandbox and approval modes. To see which destructive commands could run without a prompt under your Claude Code settings, paste a config into the check page or run npx deedglass scan (how the grade works), which reads .claude/settings.json; to try tool-call rules in your browser, open the playground.

Written with AI assistance and checked against our claims register.

The takeaway

Claude Code's sandbox is off by default. On, it keeps shell writes in the project and network on an allowlist, but reads ~/.ssh unless you deny it.

Read nextYour AI coding agent can read your .env file. Here's what stops it, and what doesn't. Try it: install in 7 s

Related on this site

In the docs

More posts

Sources

  1. 1Claude Code docs: Sandboxing · code.claude.com · checked 26 October 2026

Published 26 October 2026, sources last checked 26 October 2026. If something here is out of date, write to hello@deedglass.com.

Try it on your own setup

npx deedglass scan

Grades only your own setup. Nothing is uploaded.

Pricing