# Deliberately exposed and out of scope Anything not in the lockdown list (see the [threat model](../explanations/threat-model.md)) is potentially reachable from inside Claude. This page reproduces the two reference tables: what the sandbox deliberately exposes, and what is out of scope. Paths below are inside the container. The PyPI launcher mounts only the project directory, writable in the container. With `--peers` it also mounts the parent directory writable, except when the parent is your home. Each agent's sandbox still binds only its own project. The launcher also mounts shared agent state, git identity, and explicitly added paths from the workstation. For its read-only host config mount, see [Configuration](configuration.md). ## Deliberately exposed These paths are bound into the sandbox on purpose. Modes are `r` (read-only) or `rw` (read-write). | Path | Mode | Why | |---|---|---| | Workspace | rw | The whole point of Claude. Default: `$PWD` (only the current project is writable). Override: set `CLAUDE_SANDBOX_WORKSPACE_ROOT=/workspaces` in `remoteEnv` to restore the old broad bind and make sibling devcontainer projects writable. Extra paths: `allow-write = ` lines in `/etc/claude-sandbox.conf` (one path per line; blank lines and `#` comments ignored) | | `/etc/claude-sandbox.conf` | r | Host-global sandbox config (`workspace-root`, `no-forge`, `allow-write`, `pass-env`, `egress-jail`, `allow-ip`), seeded by `install.sh` from the installing clone's `.devcontainer/claude-sandbox.conf` and read by the shadow at launch. Lives at `/etc`, **not** in the rw-bound workspace, so a compromised session can't rewrite it to widen the next launch's binds. Edit `/etc/claude-sandbox.conf` directly (unsandboxed root shell) to change it; edits are per-devcontainer and reset by a rebuild/re-install | | `/etc/claude-gitconfig` | r | Curated gitconfig: gh/glab credential helpers for `https://github.com` and `https://gitlab.diamond.ac.uk`, ssh→https `insteadOf` rewrites, regenerated at every shadow launch from your host's current `user.name`/`user.email` | | `/etc/gitconfig` | r | Host's system gitconfig is reachable read-only but neutralised for `git` because `GIT_CONFIG_SYSTEM=/dev/null` | | `/root/.claude/` | rw | Claude's state, settings, skills, hooks. `install.sh` symlinks this to `/user-terminal-config/.claude` so the tree persists across rebuilds and is shared with every other devcontainer that mounts the same `terminal-config` dir | | `/root/.claude.json` | rw | Account-level state (OAuth token, recent-projects list, settings). Symlinked alongside `~/.claude/`; without it the strict-under-/root tmpfs would swallow the token and re-prompt login every launch | | `/root/.agents/skills/` | rw | Skills shared by every agent (Claude, Codex, Pi), in **every** session. Codex and Pi load them natively; Claude via symlinks in `~/.claude/skills`. Symlinked to `/user-terminal-config/.agents/skills` when that is mounted. Any agent can write a skill here that the others then load, so treat it like your own `~/.claude`. The rest of `/root/.agents/` is NOT bound ({ref}`adr-shared-agent-skills`) | | `/root/.cache/` | rw | Tool caches Claude needs across runs (if present) | | `/root/.config/gh/` | rw | `gh` CLI's token store. Required so `gh auth status` works and the curated gitconfig's `gh auth git-credential` helper can authenticate `git push` to GitHub without an OAuth popup | | `/root/.config/glab-cli/` | rw | `glab` CLI's token store. Same reason as `gh`. Sibling paths under `/root/.config/` (VS Code state, other cred helpers, etc.) are NOT bound | | `/root/.local/share/` + single files `/root/.local/bin/{uv,uvx}` | rw | Bulk-bound XDG data dir: host-installed plugins for `helm`, `kubectl`/`krew`, `uv`-managed Python, etc. just work inside the sandbox without per-tool allowlist additions. `applications/` and `claude/` are tmpfs-masked so Claude Code's own writes (URL handler `.desktop`, versioned binary cache) stay ephemeral. `.config/` stays strict-allowlist — credentials live there, not under `.local/share/` | | `/usr/libexec/claude-sandbox/claude` | r | The real Claude binary, relocated here by the installer from `~/.local/bin/claude` so plain `claude` on the user's PATH always resolves to the shadow. The shadow exec's this same file via `bwrap`; a bind back to `~/.local/bin/claude` inside the sandbox keeps Claude Code's `installMethod=native` self-check happy | | Network (egress-jailed by default, ADR 0015) | — | Claude runs in a private network namespace (pasta-bridged) with a routing allowlist: the internet, DNS, and configured `allow-ip` devices stay reachable so Claude works (`api.anthropic.com`, GitHub/GitLab), while RFC1918 (10/8, 172.16/12, 192.168/16) and 169.254/16 are blackholed so a compromised session cannot pivot to internal hosts. **On by default**; an operator opt-out (deliberately not documented here) restores the shared host netns (`--share-net`, {ref}`adr-network-egress-open`). See {ref}`adr-network-egress-jail` | For the rationale behind the XDG split, the uv bind discipline, the gitconfig redirect, and the egress jail (and the network-identity disclosure that remains when an operator disables the jail), see the [threat model](../explanations/threat-model.md) and {ref}`adr-network-egress-jail`. ## Out of scope The sandbox does not defend against the following. Each row names the mitigation expected from you. | Exposure | Why | Mitigation expected from you | |---|---|---| | **Workspace contents** | Claude has to read your workspace to do its job | Keep secrets outside the workspace (e.g. `~/.config/` mounted via your devcontainer's `mounts`). Don't put `.env` files with production credentials at the workspace root and expect them to be invisible | | **Container host kernel** | A bwrap-aware kernel exploit is out of scope; this is a credential-isolation tool, not a sandbox against arbitrary native code | Keep your kernel patched; treat the devcontainer host as the trust boundary | | **Internet exfiltration / domain filtering** | The default egress jail (ADR 0015) blocks lateral movement to internal RFC1918 hosts, not outbound exfil — the internet, DNS, and `allow-ip` devices stay reachable so Claude works. Restricting *which* internet domains Claude reaches (a hostname allowlist) is Claude Code's native sandbox's job, not this tool's | If outbound exfil is in your threat model, run the devcontainer behind your own egress filter, and/or layer Claude Code's native `allowedDomains` sandbox on top — the two are complementary (see [the egress jail and the native sandbox](../explanations/threat-model.md#the-egress-jail-and-the-native-sandbox)). See {ref}`adr-network-egress-jail` | | **Non-standard credential paths** | The installer scans `mount` and warns about `/kubeconfig`-style binds at install time, but cannot enumerate every custom mount | Audit your devcontainer's `mounts` block | | **Non-root devcontainers; rootful Docker w/ default AppArmor** | v1 targets rootless podman + Debian/Ubuntu + `remoteUser=root` | Tracked for v2 |