[Feature] Add configurable sandbox write paths (additionalWriteDirectories)

Status Fixed / completed
Maintainer reply None cached
Activity 5 comments · opened Feb 2, 2026 · closed Feb 3, 2026

Summary

There's no way to configure sandbox write paths for bash commands. Write paths are hardcoded, and additionalDirectories only grants read access.

Background

This was discussed in #10377 (now closed/locked). A commenter found the write paths are hardcoded:

B = [
    "/dev/stdout", "/dev/stderr", "/dev/null", "/dev/tty",
    "/dev/dtracehelper", "/dev/autofs_nowait",
    "/tmp/claude", "/private/tmp/claude",
    iJ.join(A, ".npm/_logs"), iJ.join(A, ".claude/debug"),
    ".",
]

Reproduction

Config:

{
  "permissions": {
    "allow": ["Edit(/Volumes/Casa/**)"]
  },
  "sandbox": {
    "enabled": true,
    "autoAllowBashIfSandboxed": true,
    "additionalDirectories": ["/Volumes/Casa"]
  }
}

Result:

$ touch /Volumes/Casa/test.txt
# Operation not permitted

$ mv /tmp/claude/file.txt /Volumes/Casa/file.txt
# Operation not permitted

Expected behavior

additionalDirectories should grant both read and write access, or there should be a separate additionalWriteDirectories setting.

Current workarounds

  • Use Edit/Write tools instead of bash (requires read+write, inefficient)
  • Ask user to run the command
  • Add to excludedCommands (security tradeoff)

Proposal

The underlying sandbox-runtime already supports filesystem.allowWrite. Expose this in Claude Code settings, e.g.:

{
  "sandbox": {
    "additionalWriteDirectories": ["/Volumes/Casa", "/path/to/other"]
  }
}

Or make additionalDirectories grant write access too (simpler, matches user expectation).

Environment

  • macOS Darwin 24.5.0
  • Claude Code (latest as of 2026-02-02)

View original on GitHub ↗

5 Comments

olearydj · 8 months ago

Investigation from sandbox-runtime

I investigated this from the sandbox-runtime side (anthropic-experimental/sandbox-runtime) and can confirm:

sandbox-runtime already fully supports configurable write paths via filesystem.allowWrite:

{
  "filesystem": {
    "allowWrite": ["/Volumes/Casa", "."],
    "denyWrite": []
  }
}

Evidence:

  • Schema: Defined in sandbox-config.ts:126-128 with Zod validation
  • Documentation: README.md documents it with examples (glob patterns supported on macOS)
  • Tests: 60+ test references confirm it works

The fix should be straightforward - Claude Code just needs to expose this existing configuration option via a user-facing setting like additionalWriteDirectories that maps to sandbox-runtime's filesystem.allowWrite.

Related investigation: SANDBOX_ISSUES.md (Issue 3)

tomdale · 8 months ago

Maybe I'm misunderstanding you, but you can configure sandbox filesystem and network restrictions via the standard permissions configuration. Example from my config that allowed sandboxed Bash commands to read/write to the specified paths:

{
  "permissions": {
    "allow": [
      "WebFetch(domain:api.github.com)",
      "WebFetch(domain:api.linear.com)",
      "WebFetch(domain:github.com)",
      "WebFetch(domain:registry.npmjs.org)",
      "WebFetch(domain:registry.yarnpkg.com)",
      "WebFetch(domain:crates.io)",
      "WebFetch(domain:docs.rs)",
      "WebFetch(domain:productionresultssa*.blob.core.windows.net)",
      "WebFetch(domain:vercel.com)",
      "Read(~/.local/config/claude/**)",
      "Edit(~/.local/share/cargo/**)",
      "Edit(~/.local/share/pnpm/**)",
      "Edit(//tmp/claude*/**)"
    ],
  }
}

I found this quite confusing since it implies granting the permission only to the WebFetch/Read/Edit tools exclusively, but I can confirm that the above settings allowed arbitrary sandboxed commands that were getting blocked from accessing these domains and reading/writing to these directories now successfully run while still being sandboxed. And this behavior is documented:

How sandboxing relates to permissions

Filesystem and network restrictions are configured through permission rules, not sandbox settings: Use Read and Edit deny rules to block access to specific files or directories Use WebFetch allow/deny rules to control domain access * Use sandbox allowedDomains to control which domains Bash commands can reach
olearydj · 8 months ago

@tomdale's solution works! The key insight I was missing is the path syntax:

| Pattern | Meaning |
|---------|---------|
| //path | Absolute filesystem path |
| ~/path | Home-relative path |
| /path | Relative to settings file (NOT absolute!) |

I was using Edit(/Volumes/Casa/.uv-cache/**) which became the invalid path /Users/djo/.config/claude/Volumes/Casa/.uv-cache/**.

After changing to Edit(//Volumes/Casa/.uv-cache/**), sandboxed uv commands work perfectly.

This distinction isn't obvious in the docs - might be worth emphasizing in https://code.claude.com/docs/en/permissions#read-and-edit

wjordan · 8 months ago

As a related note to this issue (which noted macOS environment), I continued to experience a similar issue on Linux (Ubuntu 25.10, Claude Code 2.1.38).

It appears that the sandbox utility used on Linux (bubblewrap) doesn't support globs in its bind-mount paths, and (due to a Linux-platform bug in sandbox-runtime) are not properly filtered out when setting up the read-write bind mounts. I submitted a PR that would fix this bug (anthropic-experimental/sandbox-runtime#128).

For now, the Linux workaround is to remove all glob suffixes (/**) from config permission rules - they appear to be redundant anyway, since the permission system already treats directories recursively.

github-actions[bot] · 7 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.