bwrap sandbox for the Bash tool binds the entire /home directory, causing Permission denied on writes outside the invoking users own home (e.g. /home/.mcp.json)
Summary
When the Bash tool's sandbox (bwrap) is active, its mount setup binds the entire /home directory into the sandbox rather than scoping it to the invoking user's own home directory. Since a bind mount does not change underlying ownership, and /home itself is typically root:root with mode 755 on Linux, any code path that resolves a path relative to a truncated/bare /home (instead of /home/<user>) fails with a permission error when attempting to write there — observed concretely as:
bwrap: Can't create file at /home/.mcp.json: Permission denied
Environment
- Claude Code CLI v2.1.224, native install, Linux (Debian/Ubuntu-based)
- Triggered with
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1and--safe-mode $HOMEcorrectly set to/home/<user>for the whole invocation (verified via/proc/<pid>/environ)
Reproduction
- Run
claudewith--safe-mode,CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1, and--tools Bash --allowedTools Bash. - Prompt it to run any shell command via the Bash tool.
- Trace the resulting process tree (
strace -f -e trace=execve). Observed:
```
execve("/bin/bash", ["bash", "-c", "bwrap --new-session --die-with-parent ..."])
execve("/usr/bin/bwrap", ["bwrap", "--new-session", "--die-with-parent",
"--ro-bind", "/", "/",
"--bind", "/tmp/claude", "/tmp/claude",
"--bind", "/home/<user>/.npm/_logs", "/home/<user>/.npm/_logs",
"--bind", "/home", "/home",
"--bind", "/root", "/root",
"--bind", "/tmp", "/tmp",
"--bind", "/var", "/var",
"--bind", "/opt", "/opt",
"--bind", "/run", "/run",
"--bind", "/mnt", ...])
--bind /home /home
Note — the whole directory, not --bind /home/<user> /home/<user>`.
Impact
Any internal path resolution inside the sandbox that lands on bare /home/... instead of the actual $HOME (e.g. /home/<user>/...) — whether from an env var mishap upstream or internal logic — fails with a permission error that's non-obvious to debug from the caller's side, since $HOME itself can be completely correct in the invoking environment.
Suggested fix
Scope the sandbox's home-related bind mount to the actual $HOME (e.g. --bind $HOME $HOME) rather than binding the parent /home directory wholesale.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗