- Shell 100%
| cwrap.sh | ||
| README.md | ||
cwrap - Claude Code in bubblewrap
Run Claude Code confined to a single project folder using bubblewrap (bwrap).
The script launches Claude inside an unprivileged Linux namespace that starts from a fresh, empty home directory (a tmpfs). Nothing in your real $HOME is visible to the agent. Only a handful of paths are bound back in (mostly read-only) and the only two writable locations are the project folder and ~/.claude.
Because you launch the jail from outside, the agent cannot escape it by changing its own settings. You may also want to consider using the built-in /sandbox for network ACL in conjunction with this script.
Pronunciation
The project name is pronounced as you would expect: "crap" (/kræp/) — but we'll also accept "cwap" (/kwæp/)
What's isolated
Everything not explicitly bound does not exist inside the sandbox. For example: ~/.ssh, browser profiles, other projects, other users' home directories, and so on.
Read-only / fresh isolated
Bound in but not modifiable, or replaced with a fresh per-sandbox copy:
| Path | Access | Why |
|---|---|---|
/usr, /etc, /lib*, /bin, /sbin |
read-only | system tree needed to run |
/proc, /dev, /tmp |
fresh / isolated | per-sandbox, not the host's |
/etc/resolv.conf target (e.g. /run/systemd/resolve/...) |
read-only | DNS — the real file behind the symlink, so name resolution works |
the claude binary (e.g. ~/.local/share/claude/...) |
read-only | just Claude's own install, not all of ~/.local |
/usr/local |
read-only | host tools the agent may run |
Read-write
The only two locations the agent can modify:
| Path | Access | Why |
|---|---|---|
~/.claude, ~/.claude.json |
read-write | Claude's settings, credentials, session state |
| the project folder | read-write | the code you're working on |
Networking is kept (--share-net) so Claude can reach the API; all other namespaces are dropped (--unshare-all). The environment is cleared (--clearenv) so no host secrets leak in, and the sandbox dies with the launching script (--die-with-parent). The sandbox also runs in a fresh session (--new-session), which blocks the TIOCSTI input-injection escape (CVE-2017-5226); the tradeoff is that job control is unavailable inside the sandbox.
Requirements
bwrap(bubblewrap)claude(Claude Code) in thePATH
Usage
./cwrap.sh [--allow-settings-edit] [PROJECT_DIR] [-- <args passed to claude>]
The first non-flag argument is the project directory (defaults to the current directory). --allow-settings-edit may appear before or after it (see Settings lockdown). Anything after -- is forwarded verbatim to claude.
Examples
./cwrap.sh # sandbox the current directory
./cwrap.sh ~/code/myrepo # sandbox a specific folder
./cwrap.sh ~/code/myrepo -- --resume # pass --resume through to claude
./cwrap.sh ~/code/myrepo -- --dangerously-skip-permissions # not as dangerous
./cwrap.sh --allow-settings-edit # let the agent edit settings.json
Shell Alias
A simple shell alias can be used:
~/.bashrc:
# Add an alias to where you cloned the project to
alias cwrap='/home/user/projects/cwrap/cwrap.sh'
Then you can call cwrap.sh like:
cwrap
cwrap ~/code/myrepo
cwrap ~/code/myrepo -- --resume
cwrap ~/code/myrepo -- --dangerously-skip-permissions
Authentication
Credentials stored in ~/.claude work inside the sandbox without extra setup. If you authenticate with an API key instead, ANTHROPIC_API_KEY is passed through automatically when it is set in your environment. Other environment variables are not inherited — add them explicitly in the script if you genuinely need them.
Settings lockdown
A self-modification guard re-binds ~/.claude/settings.json read-only on top of the writable ~/.claude mount, preventing the agent from rewriting its own config. It is enabled by default; pass --allow-settings-edit if you need the agent to edit settings.json.
Usage Notes
What the agent can do is intentionally limited. We work in a variety of different types of environments, so we're keeping those specifics out of our sandbox as it exposes a variety of surface areas we don't think are manageable.
Only a minimal set of paths are bound in, so dev tooling that needs your host config or credentials to properly function — git (commits, signing), package managers (private-registry auth), and similar auxiliary tasks — should generally be run outside the sandbox from your normal shell.
System-tools are generally available, while per-user tools (like nvm) won't be available to the agent. This is intentional for our use case.
"Yeah, well, you know, that's just, like, [my] opinion, man." —The Dude [writing this]