Docker Sandboxes for Agents
Run an agent in a microVM, control its network and keys, get its commits back. sbx 0.47.0, docker-agent 1.149.0.
- Concepts and terms
- Tasks and commands
- Annotated code
- Diagrams
- Defaults and numbers
- Troubleshooting
- Questions and tips
What runs where#
From docker-sandboxes-101 §1.1, docker-sandboxes-101 §2.2, docker-sandboxes-101 §3.4, docker-sandboxes-101 §3.5, docker-sandboxes-101 §2.4
One request leaves the sandbox#
From docker-sandboxes-101 §2.1, docker-sandboxes-101 §3.3, docker-sandboxes-101 §3.4, docker-sandboxes-101 §3.5
Sandbox lifecycle#
| Task | Code |
|---|---|
| Create on a repository | sbx create shell <path> --name <name> |
| Attach again | sbx run --name <name> |
| Run a command as root | sbx exec -u root <name> sh -c '<cmd>' |
| Copy a file in | sbx cp <host-file> <name>:/ |
| Publish a port | sbx ports <name> --publish 18081:8080 |
| Stop and keep state | sbx stop <name> |
| Remove stopped sandboxes | sbx prune --force |
From docker-sandboxes-101 capture: 04-create.txt, docker-sandboxes-101 capture: 07-template-save.txt, docker-sandboxes-101 capture: 06-cp.txt, docker-sandboxes-101 capture: 05-ports.txt, docker-sandboxes-101 capture: 04-stop.txt, docker-sandboxes-101 capture: 04-prune.txt, docker-sandboxes-101 capture: 04-ls.txt, docker-sandboxes-101 §2.1
Secrets, MCP and health#
| Task | Code |
|---|---|
| Bind a secret to hosts | sbx secret set-custom --host <host> --env <VAR> --value <value> |
| Find keys in host env | sbx secret import --dry-run |
| Register an MCP server | sbx mcp add <name> --url <url> |
| Attach it to a sandbox | sbx mcp load <name> --sandbox <sandbox> |
| Run the 13 checks | sbx diagnose |
| Save a template | sbx template save <name> <tag> --output <file>.tar |
| Run an agent file in a sandbox | docker-agent run --sandbox --exec <agent-file> '<prompt>' |
From docker-sandboxes-101 capture: 10-set-custom.txt, docker-sandboxes-101 capture: 10-import-dry-run.txt, docker-sandboxes-101 capture: 11-mcp-add.txt, docker-sandboxes-101 capture: 11-load.txt, docker-sandboxes-101 capture: 02-daemon-status.txt, docker-sandboxes-101 capture: 02-diagnose.txt, docker-sandboxes-101 capture: 07-template-save.txt, docker-sandboxes-101 capture: 27-sandbox-run.txt
Clone mode round trip#
sbx create --clone shell <repo> \private clone, host repo read-only --name <name>source at /run/sandbox/sourcesbx exec <name> sh -c '<edit and git commit>'agent commits in the clonegit -C <repo> remote -vsbx added sandbox-<name>git -C <repo> fetch sandbox-<name>bring the commits backsbx rm --force <name>VM, state and scoped secrets goFrom docker-sandboxes-101 capture: 08-clone-create.txt, docker-sandboxes-101 capture: 08-clone-host.txt, docker-sandboxes-101 capture: 08-clone-rm.txt, docker-sandboxes-101 §3.2, docker-sandboxes-101 §2.1
What the agent sees inside#
| Command | What it does |
|---|---|
HTTPS_PROXY= | Forward proxy for HTTP and HTTPS |
ANTHROPIC_API_KEY= | Sentinel. The real key stays on the host |
M101_RECV_KEY= | Custom secret placeholder |
SSH_AUTH_SOCK= | Host SSH agent, forwarded by default |
forward-bypass | Log proxy type. Tunnel, no inspection |
transparent | Log proxy type. Other TCP, no injection |
"deny_kind": "explicit" | A rule denied it. implicit means no allow |
From docker-sandboxes-101 capture: 04-env.txt, docker-sandboxes-101 capture: 10-env-sentinel.txt, docker-sandboxes-101 capture: 09-policy-log.txt, docker-sandboxes-101 §3.4, docker-sandboxes-101 §3.3
Debug a blocked host#
sbx policy init balancedonce, before the first sandboxsbx create shell --name m101-policyno workspace mountsbx exec m101-policy sh -c \ 'curl -sS --max-time 10 https://example.com'Approval requiredsbx policy log m101-policyforward, default denysbx policy allow network \ --sandbox m101-policy example.comrule for one sandboxsbx policy check network example.com \ --sandbox m101-policy --verbose --jsonread allowed, ruleFrom docker-sandboxes-101 capture: 03-policy-init.txt, docker-sandboxes-101 capture: 09-create.txt, docker-sandboxes-101 capture: 09-blocked-by-rule.txt, docker-sandboxes-101 capture: 09-policy-log.txt, docker-sandboxes-101 capture: 09-allow.txt, docker-sandboxes-101 capture: 09-rm-allow.txt, docker-sandboxes-101 capture: run.py
Defaults#
| Setting | Default | Note |
|---|---|---|
--name | <agent>-<workdir> | Set it, so two agents stay apart |
-m, | 50% of host memory | Clamped from 512 MiB to 32 GiB |
--pull | always | Also missing or never |
--skills | readonly | Also off or readwrite |
secret set --refresh | 55m | Refresh for a dynamic source |
ssh.agentForwardingEnabled | true | Turn off for agents you do not trust |
sandbox.disk.dockerVolume | 10g | Size of /var/lib/docker |
kit.allowedSources | ["docker.io/ | Allowed remote kit sources |
Key concepts#
- Sandbox
- a microVM with its own kernel and a private Docker Engine.
- Clone mode
--clone. The agent works on a private clone. Commits return through a remote.- Preset
allow-all,balancedordeny-all, set once withsbx policy init.- Policy scope
globalfor all sandboxes, or one sandbox with--sandbox.- Deny wins
- a deny rule takes precedence over an allow for the same host.
- Sentinel
- the placeholder the agent sees in place of a secret.
Troubleshooting#
| Symptom | Cause | Fix |
|---|---|---|
Approval required for example.com:443. | No allow rule matches | sbx policy allow network --sandbox <name> <host> |
curl to ::1 fails with exit 7 | Port published as tcp4 | Publish 8080/tcp for both families |
copying between sandboxes is not supported | cp needs a host side | Copy through the host |
Deny conflicts with existing allow rule | Allow and deny in one scope | sbx policy rm network --id <uuid> first |
No API key from ~/.zshrc | Host environment not read since v0.35.0 | sbx secret set or sbx secret import |
ensure daemon: daemon exited unexpectedly | sandboxd problem | sbx daemon status --json, read daemon.log |
From docker-sandboxes-101 capture: 09-blocked.txt, docker-sandboxes-101 capture: 05-ports-curl.txt, docker-sandboxes-101 capture: 06-cp.txt, docker-sandboxes-101 capture: 09-deny-conflict.txt, docker-sandboxes-101 capture: 09-rm-allow.txt, docker-sandboxes-101 capture: 07-template-save.txt, docker-sandboxes-101 §2.2, docker-sandboxes-101 §3.5, docker-sandboxes-101 §3.2, docker-sandboxes-101 §2.4
Q&A#
- Do I need Docker Desktop?
- No. You need
sbx login. Containers of the agent never show in hostdocker ps. - stop or rm?
sbx stopkeeps state.sbx rmdeletes the sandbox, its state and scoped secrets.- Does a host allow block a gist upload?
- No. A host allow passes any method, path and body.
- Does the agent see my key?
- No. It sees
proxy-managed. The proxy adds the key after the VM.
From docker-sandboxes-101 §1.1, docker-sandboxes-101 §2.1, docker-sandboxes-101 §3.4, docker-sandboxes-101 §3.5, docker-sandboxes-101 §3.2
Tips#
- Set memory, ports, skills and static MCP servers at creation. A re-attach ignores them.
- Run
sbx prune --dry-runbefore a prune. - Add narrow rules with
--sandbox. Keep global rules for hosts every agent needs. - Store keys with
sbx secret set, never with-e KEY. - Bind a custom secret to exact hosts. The proxy replaces the placeholder anywhere.
From docker-sandboxes-101 §2.1, docker-sandboxes-101 §3.3, docker-sandboxes-101 §3.5, docker-sandboxes-101 §2.4, docker-sandboxes-101 §2.2