The permission asks are the slowest part of Claude Code. That's why the first thing I was looking for was --dangerously-skip-permissions, it was a breaking moment for me but also a new risk. My first thought was what if it does read my private keys from ~/.ssh? What if it accesses my other projects or sensitive resources shared by my clients? One wrong action and it can remove not relevant files. What's even worse for me - it will install python libs used for the dev session and flood my Mac with that, it's terrible for people like me who love to keep the workstation clean!
I'm letting Claude Code to work for hours or even night without me around, the permissions prompt issue was solved by the flag but how not to risk my Mac and confidential files? After reading Anthropics docs I have found it's pointing to the containers direction, VMs or sandboxes. Ok but which one? What are the differences? That's the overview for September 2026 as I'm writing this.
The mental model, rate each answer with a short question: what are the boundaries of the agent inside? Two biggest problems I've noticed are making the biggest damage. Leak of our sensitive/confidential data and the unrecoverable removal. Breaking the kernel isolation is real but rare and almost never happens during a day-to-day work, it has to be intentional. Keys leaks are normal these days and happens all the time. So what really matters is the boundary between your agent and your data, not between your agent and the virtualization kernel.
Auto mode moved the starting point
Since I published this Anthropic made auto mode the built in starting permission mode on Pro, Max and Team plans. If you are on one of those you are not seeing the old prompt on everything any more, so the reason I went looking for the flag in the first place is mostly gone.
That does not change the answers below, it sharpens the question. In auto mode a second model reviews the actions instead of you. That removes the clicking, it does not remove the reach. The agent still runs as you, with your keys and every other repo on the machine one path away. A reviewer is not a boundary. It decides what should happen, a boundary decides what can.
The flag is still there and still documented, --permission-mode bypassPermissions with --dangerously-skip-permissions as the equivalent. It is what you reach for when you want the thing running for hours with nobody watching. So read the rest of this from auto mode rather than from the prompts.
Option 1: built in /sandbox
Claude Code has its own system level sandbox (seatbelt on macOS, bubblewrap on Linux). It's free, it's there and it's worth keeping it enabled. The catch, read the fine print how does it work when working without the permission prompts: only bash commands are included (files tools, MCP servers and hooks work outside of it), your hard drive is available for read (except a few default-denied dirs) unless you block it or mask the paths, one by one. There is also a gate so it retries failed commands outside the sandbox. Anthropic says: it's not enough to run the agent unsupervised. Great pick if you plan to sit staring at the terminal. It's not solving my case, running the Claude Code with the bypass permissions flag.
Option 2: sandbox runtime (beta)
@anthropic-ai/sandbox-runtime wraps the Claude Code with the same system mechanism without containerisation. That's the most interesting thing Anthropic released in that area. It's still in beta, research preview which you have to assemble yourself bit by bit. Other way round than the option 1, tell us what you want to open: writes and the network are denied by default so you point at your project, ~/.claude and /tmp in the configuration. In order to protect your key you have to remember about it, if you add a new one there you have to remember about it :) on Linux the rules are computed on start so a fresh git clone during the session lands outside of it. Worth watching, I won't run the night session on it, not yet.
Option 3: dev container
Real boundary around the whole session. Anthropic has published a complete configuration with a firewall by default rejecting everything, made directly for the skip permissions flag. Cost: you have to use a devcontainer compatible editor (VS Code, JetBrains, Cursor, Codespaces) or the CLI. You have to edit a JSON and a Dockerfile and rebuild the image to apply the changes. You have to handle and make yourself the support for clipboard, session persistence and switching between project. If this is your way, defining the toolchain as an image and VS Code is your home, this might be something for you.
Option 4: Docker Sandboxes (micro VMs)
Dockers own product to run the agent in microVM: custom kernel, custom daemon, the strongest local isolation from the list. If you are going to work with untrusted codebase or kernel exploits - take it and don't read further. The costs are relevant to the solution, its heaviest from all the options, it has its own stack and does run on macOS (Sonoma 14+, Apple Silicon), Windows 11 and Linux (Ubuntu 24.04+, needs KVM). For your own agent and your own repositories its over-engineered, you don't need such a strong boundaries for the real incidents that actually happens.
Option 5: you run your own docker container
Mount single project to the container, put the code inside, install the Claude Code and start it with the bypass protection flag. There are good articles how to do that with real examples. A good and clean writeup is a claude-pod. Building it you can really deep dive and understand how does it work, it really does. Then while using it you are finding the gaps. You cannot paste a screen into the terminal. Files are root owned. Sessions are destroyed when docker is restarted. The tool you install disappears with the container. Every fix takes time, needs multiple iterations and you're starting to be frustrated by this used to be perfect solution. And now you have to maintain that!
This is what I'm using now
I have built the Cleat. I wanted the Option 5 without weekends spent on covering the gaps and maintaining the containers. It's a single bash file on MIT license. Type cleat in your project and you land in Claude Code with the bypassed prompts flag enabled, inside a Docker container associated with a single project.
The security model is a construction, not a configuration. Your SSH keys, cloud files and dotfiles are not blocked by a rule you wrote. These are just not available in the container! There is no list to maintain and there is nothing to remember. When a project needs your identity, a git access or ssh key you can opt-in these with per project capabilities, only one single container receives that.
The rest is a boring stuff which makes your cleat container work the same way as vanilla Claude Code: working clipboard, ctrl+v shortcut to paste image or screenshot from your host into the containers Claude, files belongs to you on the file system ownership level, stop and resume with a full context, [setup] section to make your tools to survive, works with every engine you already have (Docker Desktop, OrbStack, Colima, rootless Linux and more).
brew install cleatdev/tap/cleat
cd your-project && cleat
Honest scope
A comparison which hides the weak points is an advertisement: it's a container, not a microVM so it's not protecting you against kernel exploits. For now the box has a full egress to the network. The box can also hand my host a URL to open. With the hooks capability on it can hand it a command to run. Both are being narrowed right now. The project you mount is fully available inside so secrets stored inside are still accessible and vulnerable. The boundary is between the agent and everything you have.
Choose by situation
| Use case | Option |
|---|---|
| Quick session with supervision | built-in /sandbox with auto mode enabled |
| Unsupervised work on your own repositories | Cleat |
| Team with a toolchain as an image in VS Code | dev container |
| Untrusted code base, kernel risk | Docker Sandboxes or VM |
| No Docker available on the machine | today /sandbox, sandbox runtime once it becomes mature |
I'm holding a complete version of this comparison, with the sources and the weaknesses of every option (mine too) under cleat.sh/compare. If you find some falsy or outdated parts or statements please report that on the GitHub and I will address that as fast as possible.
Top comments (3)
Really good comparison, Marcin. 🔐
I especially like the framing of the security model as construction rather than configuration. Making sensitive host state unavailable by design is much stronger than maintaining an ever-growing denylist of paths the agent should remember not to touch.
The part I would push one step further is network egress.
Filesystem isolation answers “what can the agent read?”, but once an autonomous agent can reach the network, the next security boundary becomes “where can anything it reads go?”
So for me the full model starts looking like:
filesystem exposure → credential scope → network egress → execution privileges
A project-only mount gives a very useful host boundary, but secrets already inside the repository or credentials deliberately granted to that container still need their own controls. Short-lived scoped credentials and outbound allowlists would make that boundary considerably stronger.
I also appreciate that you explicitly call out Cleat’s limitations instead of presenting containers as perfect isolation. That makes the comparison much more useful.
This is very close to the kind of boundary reasoning I have been exploring around autonomous AI systems: don't just ask whether the agent is “sandboxed”, ask which capabilities and information flows remain possible inside that sandbox. 🔍
Really enjoyed this one.
Thanks Marco, this is a strong point!
Your model (filesystem → credential scope → network egress → execution privileges) is basically the backbone of this project. First two phases are done. The container sees the project and nothing else, plus my Claude login. This is required not to authenticate every time you start the cleat. Access to keys and tokens is opt-in, per project. For now it has six capabilities: git, ssh, env, hooks, gh (GitHub CLI) and docker.
The next two are gaps I document publicly:
The fourth gap was added today to the article above, it was missing there as you pointed out.
As for the secrets in the repository, you're right again, it's in the article in the Honest scope section. What you mount will be available for the agent.
I have to push back in one place. The grant is the control: opt-in, per project, per box. Compromised agent in one box won't see the other project's keys because these are not there. It's the architecture, not a gap.
What's interesting, you independently came to the same conclusion as I did while designing the egress. The grant has to be session scoped by default and it will expire together with the box, it won't live permanently.
Whereas the short-lived scoped credentials is something that isn't there anywhere. Short-lived egress grant is in the design phase. Short-lived credential, token which is expiring instead of permanently mounted key is something I don't have, even in design for now. This is the most valuable point for me in your comment, thank you for that!
A question about egress since you work in this area professionally. What would you expect from an allowlist? Per host or per process? And more importantly: where to enforce that? Box has passwordless sudo so everything that is inside might be modified by the agent. Enforcement has to be outside the netns and on rootless engines the standard mechanisms do not work. I haven't solved that yet.
This is exactly the boundary I would worry about.
I would not make the primary policy per-process, because inside a box with passwordless sudo the process is not a trustworthy identity. The agent can spawn another process, change execution path, or simply move the action somewhere else.
I would make the default grant destination-scoped, capability-scoped and session-scoped, then enforce it outside the box.
So something closer to:
box/session -> allowed capability -> allowed destination -> expiry
For example, a GitHub-enabled box could reach github.com and the required API endpoints for that session, but not arbitrary outbound hosts.
The cleanest enforcement point to me is an external egress proxy or gateway that the box cannot reconfigure. Ideally the box has no direct network path at all, and outbound traffic must cross that policy layer. That also gives you one place for DNS policy, destination allowlists, logging and expiry.
Per-process controls become interesting only if the process identity is anchored outside the guest, for example through a host-side cgroup/eBPF policy. Otherwise the process name or PID is just another thing the agent can influence.
Rootless definitely makes this harder, but I think the architectural rule survives: if the agent has root inside the box, the egress authority cannot live inside the box.
And I agree with your distinction on grants. Your current per-project capability grants are already a real isolation control. What I was pointing at is the next layer: once a credential is intentionally granted, can we also make that credential itself ephemeral and narrower than the lifetime of the project?
That combination would be very strong:
project isolation + explicit capability grant + short-lived credential + external egress enforcement
I think that is the direction I would trust most for autonomous agents. 🔐🔍