What each layer covers and misses
Each layer decides on different evidence, so each one misses cases the others catch.How operating-system sandboxes work
Sandboxing implementations vary by platform, but most use the same OS primitives, such as macOS Seatbelt and Linux bubblewrap. They also share a common default posture: broad reads, writes limited to the working and temporary directories, and restricted or disabled network access. Each implementation separates the sandbox, which sets the technical boundary, from the approval policy, which decides when the agent must ask before acting.Different layers of protection
Limits of sandboxing for coding agents
Sandboxing restricts where you can write, but it doesn’t decide what the process may do inside that area. Claude Code’s sandboxing docs scope writes to the working directory by default, sogit reset --hard and rm -rf . on your project land on allowed paths, and the operating system sees permitted writes. git push --force rewrites your remote over the network and writes nothing locally, so a filesystem write scope never had it in range. The following commands are all permitted by the sandbox: they write inside the current working directory, read a file the sandbox allows, or reach an allowed remote.
Whether these commands run automatically or require confirmation depends on your agent’s sandbox mode and approval policy. Network-dependent commands like
git push --force also depend on your allowed-domain configuration.Sandboxing sees
git reset --hard as a safe operation because it modifies files only within the current directory. The command still discards all uncommitted work.~/.aws/credentials and ~/.ssh/ as files it still allows reading. CC Safety Net blocks content access to those paths with no configuration.
The same difference applies to command proxies. A tool that runs a command on your behalf looks like one opaque executable to both layers. After you declare it with cc-safety-net rule wrapper add <command>, CC Safety Net looks through it to the visible child command and applies the same rules. A sandbox does not inspect the child. It limits what the whole process tree can touch.
When sandboxing is the better choice
Sandboxing is the right tool when your primary concern is:- Prompt injection attacks. Restrict outbound network domains to reduce exfiltration risk.
- Malicious dependencies. Limit filesystem writes and network access from untrusted packages.
- Untrusted code execution. Use OS-level containment, which is stronger than command-text analysis.
- Network control. CC Safety Net has no network protection.
Where CC Safety Net cannot help
CC Safety Net interprets supported tool calls; it does not contain a process. Each of these limits needs containment rather than semantic analysis:- Exfiltration over the network. Runtime evaluation makes no network requests and nothing in the pipeline inspects egress. Domain allowlisting is the sandbox’s job.
- Reads outside the recognized set. Sensitive-path protection covers a bounded pattern set across supported command, path, search, and patch shapes. It includes
.envvariants, SSH keys, cloud credential stores, coding-CLI credential files, and configured deny paths. The Secret protection reference lists the full catalog. This is not a general read boundary, so a credential in an unrecognized file is not protected. A sandbox constrains all reads without knowing which file matters. - Behavior hidden inside a binary.
some-tool --task destructive-cleanuplooks benign in the command text, and a proxy that rewrites its child instead of executing a visible one cannot be unwrapped even when it is configured as a transparent wrapper. - Complete filesystem enforcement. A denial stops the tool call; it does not enforce permissions. When you need complete protection rather than best-effort interception, use a trusted write broker, OS permissions, or a sandbox.
Permission prompts and approval classifiers
The layer closest to you is the one that asks. Claude Code’s permission modes describe it: in Manual mode, Claude Code “stops and asks you before most actions that edit files, run shell commands, or reach the network”, while in auto mode “a second model, the classifier, reviews actions instead of you”. The classifier blocks a list of actions by default, and the list includes “git reset --hard, git checkout -- ., git restore ., git clean -fd, git stash drop, or git stash clear, which the classifier presumes would discard uncommitted changes”.
That review is a judgment, and you can turn it off. Anthropic publishes a 17% false-negative rate for the auto-mode classifier on real overeager actions and calls it “not a drop-in replacement for careful human review”. The permission-modes page lists what runs without asking under bypassPermissions as “Everything”, and recommends that mode for “Isolated containers and VMs only”.
Deterministic checks survive the mode switch. The same page states that “Deny rules block in every mode, including bypassPermissions”. A CC Safety Net denial behaves the same way: verified against Claude Code 2.1.251, a PreToolUse deny still fires in default, auto, and bypassPermissions modes (tests/e2e-live/protection.test.ts in the project repository). That is a per-version result, not a standing guarantee, so the suite runs again on every release and host upgrade. Deny rules cover the commands you thought to name, in the format each CLI accepts. CC Safety Net applies one policy and writes one audit trail across 13 CLIs.
Containers, VMs, and checkpoints
A machine you can throw away is real containment, and it is where the permission-modes page points once the prompts are off:bypassPermissions is for “Isolated containers and VMs only”. What a disposable machine does not change is the work inside it. A cloud session clones your repository at a real branch, commits, and pushes back to your real remote, so git reset --hard on uncommitted work costs the same work there that it costs locally, and git push --force lands on a branch your teammates pull. Cloud environments covers the credential side of the same session. A local container that mounts your working tree works the same way. The mount is writable, and your uncommitted work sits inside it.
Checkpoints narrow that gap without closing it. Claude Code’s checkpointing docs say checkpointing “automatically captures the state of your code before each user prompt”, then state the limit: “Checkpointing does not track files modified by bash commands.” The examples given there are rm file.txt, mv old.txt new.txt, and cp source.txt dest.txt. Of those changes, the page says: “These file modifications cannot be undone through rewind. Only direct file edits made through Claude’s file editing tools are tracked.” A destructive git command runs as a bash command, so the work it discards is outside what a rewind restores. The same page positions checkpoints as “quick, session-level recovery” and says to “continue using version control, such as Git, for commits, branches, and long-term history”.
Use sandboxing with CC Safety Net
Sandboxing handles unknown threats by constraining what the agent can do at the OS level. CC Safety Net handles known destructive patterns by intercepting commands before they execute. Together, they cover the gaps that each leaves on its own. The other layers stack the same way. A classifier weighs intent in cases no static check can settle. A disposable machine and its checkpoints limit and undo part of what still gets through. Neither one covers the case the deterministic check is there for. Sandboxes and allowlists also break. CVE-2026-25725 escaped Claude Code’s bubblewrap sandbox throughsettings.json, and CVE-2026-22708 bypassed Cursor’s command allowlist. Run every layer you have.