Running an AI coding agent on your host machine is a bit like hiring a contractor and handing them your house keys, your car keys, and your office keycard — just in case they need any of them.
There's a better way. This article is about what that looks like in practice.
Your agent is an optimizer, not a rule-follower
When working with agents you might noticed that if an agent hits a blocker or a problem, it tries to find their way around it. Setting up permission is a good way of catching obvious ways to reach the goal.
Unfortunately, give an agent a goal and it will find a path. Looking at the concrete example with blocking access to reading the env variables, an agent found a way to create a python script to fetch the variables.
We can't block the agent from generating Python. Why would we?
This isn't malicious behavior. The agent isn't trying to attack you — it's trying to complete the task you gave it. If one path is blocked, it tries another. If that's blocked, it tries a third. It has more patience and creativity for this than you have for writing rules.
The result is a game of whack-a-mole you will eventually lose. Block environment variables, it uses the filesystem. Block the filesystem, it uses network calls. Block direct network calls, it finds a binary that makes them. There's always another path.
This is why the answer isn't better guardrails. It's removing the surface entirely.
Put it in a box
Docker Sandboxes run your AI agent in a microVM — a lightweight virtual machine with its own kernel, filesystem, and network stack. It's not a container (which shares the host kernel). It's not just a namespace (which can be escaped). It's a separate machine.
The agent runs inside. Your host is outside. Full stop.
What the agent can access:
- The project folder you explicitly mount
- The tools and versions you baked into the sandbox image
- Network requests through a proxy you control
What it can't access:
- Other projects on your machine
- Your home directory, dotfiles, credentials
- The host filesystem at all (except the mounted project)
- Raw network — all traffic goes through a policy-enforced proxy
This isn't a permission system the agent can negotiate with. It's an isolation boundary enforced by hardware virtualization.
![]() | ![]() |
How Docker Sandboxes compare
| Approach | Isolation | Docker access | Use case |
|---|---|---|---|
| Sandboxes (microVMs) | Full (hypervisor) | Isolated daemon | Autonomous agents |
| Container with socket mount | Partial (namespaces) | Shared host daemon | Trusted tools |
| Docker-in-Docker | Partial (privileged) | Nested daemon | CI/CD pipelines |
| Host execution | None | Host daemon | Manual development |
Containers are fast but not truly isolated. VMs are isolated but slow. Sandboxes split the difference — fast enough for interactive development, isolated enough to stop an escaping agent cold.
Give the agent your exact setup
Isolation is half the battle. The other half is reproducibility. When the agent runs in a sandbox, it sees a fresh environment every time. If that environment doesn't match yours, it will make wrong assumptions. It'll expect Python 3.11 when you have 3.9. It'll reach for a CLI that isn't installed. It'll fail in ways that work perfectly fine on your machine.
mise solves this. It's a polyglot version manager — nvm, pyenv, and rbenv rolled into one tool. You commit a mise.toml to your repo, and anyone — or anything — running in that project gets the exact same versions of Node, Python, Go, or whatever your stack needs.
But the real trick is baking mise into the sandbox image itself. When the agent starts, the tools are already there. No installs, no waiting, no "let me just grab the right version first." It can build, test, and iterate from the first command — without you standing by to fix the environment.
Putting it together: sbx-toolkit
I built sbx-toolkit as a thin wrapper that makes this all composable. Two scripts: one for setup, one for running.
Setup — once per machine:
./sbx-setup --agent claude-code --config ~/.claude
This bakes your ~/.claude agent config and mise tool versions into a local Docker image. Every sandbox on your machine gets the same environment. Like dotfiles — set once, benefit forever.
Runtime — per project:
Add a .sbx.toml to your repo:
[sandbox]
agent = "claude"
template = "localhost:5000/sbx-toolkit:mise-claude-code"
network_policy = "balanced"
required_secrets = ["ANTHROPIC_API_KEY"]
allowed_domains = ["api.github.com"]
Then start the agent:
sbx-start
It reads the config, verifies secrets, applies network policy, and launches the sandbox. The agent gets an isolated filesystem, preconfigured toolchain, and controlled network from the first command.
The payoff: real autopilot
Without isolation, you have to babysit the agent. Watch what it does. Verify it's safe. Approve the next step. This is slow and defeats the point.
With isolation + reproducible environment + network policy, you can let it run unsupervised:
- It has all the tools it needs from the start — no waiting for installs
- It can't reach your other projects or credentials
- Network is locked to what you allow
- The environment matches yours exactly, so it won't fail due to version mismatches
You shift from "let me watch carefully" to "let me review the final output." That's a real productivity gain. And you haven't traded safety for speed — you've actually improved both.
Getting started
Install sbx from the Docker releases, then:
# 1. Install sbx-start
curl -fsSL https://raw.githubusercontent.com/maxkrivich/sbx-toolkit/main/install.sh | bash
# 2. Set up your sandbox environment
git clone https://github.com/maxkrivich/sbx-toolkit
./sbx-setup --agent claude-code --config ~/.claude
# 3. Set required secrets
sbx secret set ANTHROPIC_API_KEY
# 4. Start a project
cd /your/project && sbx-start
The toolkit is at github.com/maxkrivich/sbx-toolkit. Issues and PRs welcome.



SOCIAL SHARE CARD GENERATOR