Run an AI Agent Safely in a Docker Sandbox
You’ve probably felt it already. You fire up Claude Code or Codex, it asks “Can I run this command?”, you say yes. It asks again. And again. Twenty minutes in, you’re approving things without reading them which defeats the entire purpose of the approval.
The tempting fix is to switch off the confirmations and let the agent run free on your machine. Except “your machine” means your SSH keys, your cloud credentials, your browser sessions, and every repo you’ve ever cloned. One malicious instruction hidden in a README the agent reads, and all of that is in play.
Enter Docker Sandbox !!

Docker Sandboxes (sbx) gives you a third option: let the agent run fully autonomously, but inside a microVM where the worst it can touch is the one project folder you handed it. No approval fatigue. No exposed host.
In this guide, we’ll go from zero to a working AI agent running safely inside a sandbox in six steps, with the architecture explained along the way. If you can run git clone, you can do this.
The picture to keep in your head
Before any commands, here’s the whole architecture in one image:

Three things to notice, because everything else in this guide follows from them:
1. It’s a VM, not a container. The sandbox boots its own kernel. This isn’t pedantry – it means the isolation boundary is hardware virtualization, and it’s why docker ps won’t even show your sandbox (you’ll prove this yourself in Step 6).
2. Exactly one folder crosses the boundary. Your project directory is mounted into the VM at the same path. Changes sync both ways instantly. Everything else on your host simply does not exist from the agent’s point of view.
3. Your API keys never enter the VM. They live in your OS keychain and get injected into outbound requests by a proxy on the host side. More on this in Step 3 — it’s my favorite part of the whole design.
Now let’s build it.
Before you start
| Your machine | Supported? |
|---|---|
| macOS on Apple Silicon (M1–M4) | ✅ Yes |
| Linux x86_64 (Ubuntu 22.04+, with KVM) | ✅ Yes |
| Windows 11 x86_64 | ⚠️ Yes, with minor differences |
| macOS on Intel | ❌ No |
You’ll also need Docker Desktop and an API key from one provider ~ Anthropic, OpenAI, or Google. I’ll use Anthropic + Claude Code in the examples; the flow is identical for the others.
Step 1. Install sbx
On macOS:
brew install docker/tap/sbx
On Linux:
curl -fsSL https://get.docker.com | sudo REPO_ONLY=1 sh
sudo apt-get install docker-sbx
sudo usermod -aG kvm $USER
newgrp kvm
Verify it worked:
sbx version
You should see a version string. If you get command not found, the install didn’t complete ~ go back before continuing.
On Windows:
winget install -e --id Docker.sbx
Step 2. Log in and pick a network policy
sbx login
The CLI gives you a one-time device code and a URL. Open the URL, sign in with your Docker account, and the CLI picks it up automatically.
Then comes a choice that most people click through without reading — don’t:
Select a default network policy for your sandboxes:
1. Open - All network traffic allowed, no restrictions.
❯ 2. Balanced - Default deny, with common dev sites allowed.
3. Locked Down - All network traffic blocked unless you allow it.
Pick Balanced. Here’s why it matters: this policy is enforced outside the VM, at the boundary. The agent inside cannot opt out of it, disable it, or route around it — no matter what it’s been prompted to do.

With Balanced, the agent can reach npm, PyPI, GitHub, and the usual dev suspects, but everything else is denied by default. A prompt-injected agent trying to send your code to evil-exfil-site.xyz hits a wall it can’t see over. You can change this later with sbx policy reset.
Step 3. Store your API key (the right way)
Quick Note: If you’ve Claude Code with your Pro subscription (no API key needed at all), then you can skip this step. We’ll using
/loginlater once we enter into the sandbox environment.
This is the step where sbx quietly does something most setups get wrong.
First, set your key in your own shell:
export ANTHROPIC_API_KEY=sk-ant-... # your real key
Then hand it to sbx as a global secret:
echo "$ANTHROPIC_API_KEY" | sbx secret set -g claude
(Using OpenAI or Google instead? Same command with -g openai or -g google.)
Verify:
sbx secret ls
You’ll see the secret listed with its value masked. Now here’s what actually happened, and why it’s worth a diagram:

Your key went into the OS keychain on the host. When the agent inside the VM calls the OpenAI API, the request leaves the sandbox without a key, and a host-side proxy injects it in flight. The agent never sees the raw credential, not in its environment variables, not in its context window, nowhere. Even a fully compromised agent has nothing to steal.
Compare that to the usual approach of exporting the key into the same environment the agent runs in, and you’ll understand why I call this the best feature in sbx.
Step 4. Get a project for the agent to work on
You can point sbx at any codebase you like, but for a first run I recommend the quickstart project — a full-stack FastAPI + Next.js issue tracker with intentional bugs, made for exactly this:
git clone https://github.com/dockersamples/sbx-quickstart ~/sbx-lab
cd ~/sbx-lab
Remember the architecture picture: this folder is the only thing the agent will be able to see.
Step 5. Create the sandbox
From inside the project directory:
sbx create --name=sbxlab claude .
That trailing dot matters – it says “mount this directory.” The first run pulls the agent image, which takes a minute or two.
Hitting a
mount policy deniederror instead? If you see something like this:ERROR: request failed: 403 Forbidden: mount policy denied: /Users/you/sbx-lab: fs:mount:read denied: no applicable policies for op(action=fs:mount:read, ...)it means AI Governance is enabled for your Docker organization, and filesystem access is default-deny ~ every mount needs an explicit allow policy, and none has been defined for this path yet. This is enforcement working as designed, not a bug. (I hit this myself while writing this guide: I’d enabled AI Governance on Docker Hub for my org without defining any filesystem policy, so every mount was denied, including my own lab folder.)
Two ways forward: ask your org admin to add an allow rule for your project path in the AI Governance settings on Docker Hub, or log in with a personal Docker account (
sbx logout && sbx login) where no org policy applies. On a personal account you won’t see this at all.Please don’t forget to run sbx policy reset if you make any change on AI Governance option in Docker Hub.
sbx create --name=sbxlab claude .
9a3bab17aae9: Already exists
2aaaa9a4c1cf: Already exists
fd14358c94c2: Already exists
df0506897b52: Already exists
260181b958eb: Already exists
d7966ccd2c3b: Already exists
b4b1e926fc79: Already exists
a6272837e3cf: Already exists
557981f745f1: Already exists
Digest: sha256:9a3bab17aae9790823ff6c591e97a0608eedbfda26b7e0d4818df909a7c81d32
Status: Image is up to date for docker/sandbox-templates:claude-code-docker
credential for "anthropic" discovered but no domains allowed by your bindings; not injecting (edit /Users/ajeetraina/.config/sbx/credentials.yaml)
✓ Created sandbox 'sbxlab'
Workspace: /Users/ajeetraina/sbx-lab (direct mount)
Agent: claude
To connect to this sandbox, run:
sbx run --name sbxlab
Step 6. Run it
sbx run sbxlab
First of all, type /login. Then choose “Claude account with subscription”, copy the URL to your browser (press c), sign in with your claude.ai account, paste the code back. Verify with /status. That’s it ~ your Pro plan handles the billing, no key anywhere.



Two small things may happen on first launch. The agent might auto-update itself and ask you to restart just run sbx run sbxlab again. Then you’ll see the trust prompt:
Do you trust the contents of this directory? Working with untrusted
contents comes with higher risk of prompt injection.
› 1. Yes, continue
2. No, quit
Select 1. (This prompt exists because the mounted directory is the one thing the agent can act on — sbx wants you to consciously acknowledge that.)
And that’s it. You’re now talking to Claude Code inside a microVM. Give it a real task:
Explore this codebase and give me:
1. A summary of the architecture and tech stack
2. How to run it locally without Docker Compose
3. What the test suite covers
4. Any obvious issues or areas of concern
Watch it work. It’s reading the actual files from your ~/sbx-lab folder — and nothing else on your machine.

Prove to yourself it’s really isolated
Don’t take my word for the architecture diagram. While the agent is working, open a second terminal on your host and run:
docker ps # your sandbox does NOT appear here
sbx ls # your sandbox appears HERE, status: running
The sandbox is invisible to docker ps because it isn’t a container — it’s a VM with its own kernel, managed by sbx.
SANDBOX AGENT STATUS PORTS WORKSPACE
sbxlab claude running /Users/ajeetraina/sbx-lab
ajeetraina@Ajeets-MacBook-Pro sbx-lab %
Then try the mount. Open any source file in ~/sbx-lab in your editor on the host, change a line, save. Ask the agent to read that file. It sees your change instantly — no sync step, no copy. That’s the two-way mount from the architecture diagram, live.
Bonus: watch everything in real time
In a separate host terminal, run sbx with no arguments:
sbx
You get a live dashboard – your sandboxes as cards with CPU and memory usage.

Press Tab to switch to the Network panel: a running log of every outbound connection the sandbox makes, allowed and blocked.

This is the audit trail from the network policy diagram, and honestly, watching an agent’s traffic scroll by in real time is the moment the whole governance story clicks for most people I demo this to.
Press Ctrl-C then Y to exit the dashboard without stopping your sandboxes. To exit the agent session itself, press Ctrl-C twice.
What you just built
Take stock of what’s now true on your machine:
An AI agent is running fully autonomously, no approval prompts and yet your SSH keys, cloud credentials, and other projects are untouchable by design, not by policy honor-system. Your API key never entered the agent’s environment. Every network connection the agent makes is filtered against a default-deny policy and logged. And the only thing the agent can change is one folder you chose, with changes visible to you in real time.
That’s the trade we’ve been looking for since agentic coding tools arrived: full autonomy for the agent, hard boundaries for everything you care about.
Where to go next
This guide is the first module of a longer hands-on journey. If you want to keep going:
- The isolation proof – systematically try to break out of the VM and watch every attempt fail
- Reviewing agent changes – use Git worktrees to inspect the agent’s work before it touches your working tree
- Branch mode and parallel agents – run multiple autonomous agents on the same repo simultaneously
- Local models – swap the cloud API for Docker Model Runner and go fully air-gapped
All of these are covered in my Docker Workshop and the companion AI Governance Labspace — both free, both hands-on.
And if you build something with it, come tell us in the Collabnix community.