You turned on Claude Code's sandbox on Linux, and most things kept working. Then the agent tried to start Chrome for a screenshot, or podman build for an image, and the command failed inside the sandbox. Claude Code 2.1.305, released on October 20, added a setting for exactly this case. The release note is honest about the price: the setting "lets them get around the sandbox's file protections."
This post explains what changed underneath, what the new setting does, and how to decide whether to turn it on. Everything here comes from Anthropic's release notes and docs as of 22 October 2026. We make Sessionboxer, which takes a different approach, so that part is near the end.
What changed in the sandbox
Claude Code's Bash sandbox is built on Anthropic's open source @anthropic-ai/sandbox-runtime. On Linux it uses bubblewrap, which puts each command in its own user namespace and mount namespace, then mounts the paths you allowed and blocks the ones you denied.
On October 16, sandbox-runtime 0.0.80 closed a gap. Its release notes say that on Linux "a sandboxed command stays in the namespaces made for it. It can no longer create a user namespace, or a mount namespace of its own." The same notes list what stops working as a result: "the namespace sandbox of Chromium and Electron, rootless podman or buildah, a nested bubblewrap, unshare -r."
The reason is simple once you see it. A process that can create its own user namespace becomes root inside that namespace, and can then build a fresh mount table. The write denies are mounts. A command that can make new mounts can arrange its own view of the files, and the denies no longer describe what it can touch.
Four days later, Claude Code 2.1.305 added the switch:
Added
sandbox.allowNestedUserNamespacesso sandboxed commands on Linux can create user namespaces (Chromium, rootless podman); this lets them get around the sandbox's file protections
The Claude Code release notes do not say which sandbox-runtime version each release bundles, so we cannot tell you the exact version where your Chromium started failing. If it fails on a current Claude Code and worked a few weeks ago, this is the likely cause.
What the setting really allows
The runtime's README describes the option in more detail. Turn it on, it says, "only where the commands run have to sandbox themselves that way," and "treat denyWrite and the mandatory denies as not holding against any command run under it."
That second part matters. The mandatory denies are paths the runtime keeps write-protected even when you did not list them. With allowNestedUserNamespaces on, a sandboxed command that sets out to write to them, or to a path in your own denyWrite, can. The README speaks only of the write denies, so we do not claim more than that.
On macOS nothing changes. The sandbox there uses Seatbelt, and the setting is Linux only.
Do you need it at all?
Often you do not. Look at what is actually failing.
Playwright launches its bundled Chromium without the Chromium sandbox by default. The chromiumSandbox option "defaults to false." A Playwright test suite therefore should not need a user namespace for the browser, or the new setting. If your failing command is a Playwright run, the cause is probably something else, such as a blocked network host.
A script that starts Chrome or Chromium directly, or an Electron app, uses the browser's own sandbox unless it is told not to. That is the case 0.0.80 broke. You have three options:
- Start the browser with its sandbox off for that command. You trade the browser's sandbox for Claude Code's, which still applies to the whole process.
- Add the command to
excludedCommandsso it runs outside the sandbox. The sandboxing docs list excluded commands among the things that run unsandboxed. - Turn on
allowNestedUserNamespaces, and accept that the write denies stop holding for every sandboxed command.
Rootless podman and buildah need user namespaces to work at all, so there is no flag on their side. Your choices are options 2 and 3, or running the build somewhere else.
If you do turn it on, it goes in the sandbox block of a settings file:
{
"sandbox": {
"enabled": true,
"allowNestedUserNamespaces": true
}
}
Put it in the project's .claude/settings.local.json for the one project that needs it, not in ~/.claude/settings.json where every project gets it. The runtime can also grant it for a single wrapped command, but the Claude Code release notes only describe the setting.
A check that is easy to skip
After turning it on, look at what you still rely on. If you used denyWrite to keep the agent away from .env.production, a deploy script or CI files, that deny no longer holds for a command that sets out to get around it. Move those files out of the project, or keep the setting off for that project.
Claude Code 2.1.307, released on October 21, added a claude_code.safety_event OpenTelemetry event "for each tool call a permission rule, auto mode, a safety check, a hook or the sandbox stopped, prompted or sent back." If you export telemetry, those events show how often the sandbox steps in, before and after you change the setting.
Put the whole agent in a box instead
The sandboxing docs are clear that the Bash sandbox covers shell commands only. File tools, hooks and local MCP servers run outside it. For one boundary around everything, the docs say to "run the Claude Code process itself in a container, virtual machine, or the sandbox runtime."
Once the agent is in a container, the question about Chromium changes. The container is the wall, and the agent can run its browser and its builds inside it with the permissions those tools expect. A container has its own limits. It shares the host kernel, and a container that runs Docker inside it can be privileged unless you set it up carefully. Our post on Docker in Docker for coding agents goes through those options, and Claude Code in a dev container or in Docker Sandboxes compares two ready-made boxes.
Where Sessionboxer fits
Sessionboxer runs each session in its own Docker container and lets Claude Code run in bypass mode inside it. The image's Claude Code settings do not enable the Bash sandbox, so neither 0.0.80 nor the new setting changes what happens in a box. The image also pins its Claude Code version, currently 2.1.272, so a release reaches the box only when we ship a new image.
The box has a Linux desktop with Firefox that the agent drives with the mouse and keyboard, which covers most "open the page and look at it" work. The desktop chapter of the guide shows how that works. For container builds, Docker inside the box gives each session its own Docker daemon. With Sysbox on the host the box stays unprivileged; without it, the box runs privileged and Sessionboxer marks it. The Docker inside sessions chapter has the details.
What it does not do:
- It does not ship Chromium in the image. The agent can install it in the box, but we have not documented a tested setup.
- We have not tested rootless podman inside a box, so we make no claim about it.
- A container is a weaker wall than a VM.
The short version
- Since sandbox-runtime 0.0.80, a command in Claude Code's Linux sandbox cannot create its own user namespace. Chromium's own sandbox, Electron, rootless podman and
unshare -rfail there. sandbox.allowNestedUserNamespaces, added in 2.1.305, brings them back and takes away the guarantee of your write denies.- Playwright's Chromium runs without its own sandbox by default and should not be affected.
- Prefer a browser flag or
excludedCommandsfor one command. Turn the setting on per project, not globally. - If you need browsers and container builds all the time, run the whole agent in a container or VM and let that be the boundary. How to run Claude Code with --dangerously-skip-permissions, safely covers what to put around it.