Skip to Content

How to sandbox your AI coding agent

August 14, 2026

Everyone with some common sense knows they should be running their your AI coding agent in a sandboxed environment. Somehow, common sense has a habit of not actually being all too common. A lot of setups boil down to either trusting the model to "do the right thing", or hoping that a neat little permission checklist will cover every edge case, every typo, and every clever workaround.

The truth is: you don't need to believe that AI has malicious intent. You just need to believe LLMs are overly confident, inventive, and need only the smallest hole through your guardrails.

That's why I've sandboxed my AI coding agent (opencode). I'm not talking about asking a language model nicely not to touch a specific file or path. We know from experience that that doesn't work.

Defining rules in your AI coding agent isn't enough either; ask/allow/deny is telling the agent what it’s allowed to do. Sandboxing is taking away the physical ability to do anything outside that room—so the agent can’t accidentally (or maliciously) reach the rest of the house. Besides, everyone knows the feeling of acceptance fatigue, where you start not really assessing the risk of a command any more.

I've tried using KVM and firecracker, but that felt too cumbersome in set-up. A microVM isn't easy to set up to run an entire dev environment. Docker was another option, but I've had more than enough interesting behaviour from Docker in Docker to last me a lifetime.

Ultimately, I ended up with bubblewrap!

It wasn't without it's challenges though.

To start, I didn't have internet from inside the sandbox. In my case, the sandbox ended up failing on DNS resolution. The cuprit was resolv.conf: on Fedora, /etc/resolv.conf is a symlink to /run/systemd/resolve/stub-resolv.conf, and since I mounted a tmpfs for /run inside the sandbox, the symlink target didn’t behave the way the host does. That made everything look like “no connectivity” even though it was really “the resolver couldn’t be reached.”

Docker was the next constraint. Most of our projects use Docker containers, so OpenCode needs the ability to run Docker commands as part of normal workflows. The obvious bridg of mounting /var/run/docker.sock into the sandbox is unacceptable to me: that's the same as giving the agent root-level control over the host. So instead of passing the socket straight through, I built a Docker socket proxy. That proxy becomes the choke point: the sandbox can talk Docker, but only through a policy that blocks the genuinely risky operations (like privileged containers and unsafe mounts outside an allowed directory) and forces everything else into a narrower, inspectable path.

In the end, sandboxing an AI coding agent is less about expecting perfect behavior and more about making the consequences predictable. Ask/allow/deny rules help, but they’re still instructions—meant to be interpreted correctly, remembered, and applied every time. A real sandbox gives you defense in depth: it limits reach, reduces blast radius, and forces the agent to operate inside a space you can reason about.

For me, Bubblewrap hit the sweet spot: KVM/Firecracker were too cumbersome for an everyday dev workflow, and Docker-as-sandbox comes with enough sharp edges that I didn’t want to make that my primary boundary. The “no internet” and “Docker access” problems were the practical reminders that isolation isn’t just a simple toggle, but requires actual thought.

It's not perfect yet as network is now still unrestricted, but that's work for another day. Perhaps I'll build a firewall next, so I can restrict what can be accessed from the sandbox.

Share this ARTICLE
Tags