Skip to content

Docker sbx Adoption for Coding Agents

sbx is a microVM-plus-proxy isolation harness, not a hardened container: four layers close most docker run leaks; the workspace mount and default wildcards stay yours.

Related lesson: Two Walls, Not One — this concept features in a hands-on lesson with quizzes.

What sbx actually isolates

Docker sbx (Early Access) does not run agents in containers. Each agent runs in a hypervisor-isolated microVM with its own kernel, and all network traffic routes through a host-side proxy. The Security model documents four layers:

  • Hypervisor isolation — separate kernel per sandbox, and in-VM processes are invisible to the host. The agent has sudo inside the VM, but Docker is explicit that "the hypervisor boundary is the isolation control, not in-VM privilege separation" (Isolation layers).
  • Network isolation — only HTTP/HTTPS leaves the VM, only through the host proxy, which also resolves DNS. Raw TCP, UDP, ICMP, private IPs, loopback, and link-local addresses are blocked (Default security posture).
  • Docker Engine isolation — each sandbox has its own Docker daemon inside the VM, with no path to the host daemon. docker build and docker compose up work without mounting the host socket.
  • Credential isolation — the proxy injects auth headers post-egress. Secrets live in your OS keychain, and the agent sees only a sentinel like proxy-managed in the env var (Credentials).

This closes most container-era leak paths — shared-kernel CVEs, DOCKER_HOST exposure, image-cache cross-contamination — at the design level, before policy.

Where it still leaks

  • Workspace direct mount. The default mount is read-write on the host filesystem. Workspace trust is unambiguous: "Treat sandbox-modified workspace files the same way you would treat a pull request from an untrusted contributor." Files that execute implicitly — .git/hooks/, .github/workflows/, Makefile, package.json scripts, .vscode/tasks.json, .idea/ run configs — land on your host the moment the agent writes them. Git hooks live inside .git/ and "do not appear in git diff output."
  • Broad default allow-list. The Balanced default ships with wildcards like *.googleapis.com and github.com. Docker flags this directly: "Allowing broad domains like github.com permits access to any content on that domain" (Policies).

Adoption checklist

  • Confirm the host can run a hypervisor before you wire sbx into CI. Because it is microVM-isolated, sbx needs host hardware virtualization: Apple Hypervisor.framework on macOS, the Windows Hypervisor Platform on Windows 11, or KVM on Ubuntu 24.04+ — and "if you're running inside a VM, nested virtualization must be turned on" (Get started). This is load-bearing for CI: most hosted runners are themselves VMs, so missing nested virtualization (or KVM) blocks sbx run before any policy applies. Verify with lsmod | grep kvm.
  • Set the policy non-interactively before the first run in CI. First run prompts for Open, Balanced, or Locked Down, and headless contexts hang on this prompt. Call sbx policy set-default <allow-all|balanced|deny-all> first (Policies §Non-interactive environments).
  • Default to Locked Down plus an explicit allow-list. Run sbx policy set-default deny-all, then sbx policy allow network "api.anthropic.com,*.npmjs.org,...". Watch the wildcard syntax: example.com does not match subdomains, and *.example.com does not match the root, so specify both when needed (sbx policy allow network).
  • Mount extra workspaces read-only. Run sbx run claude . /path/to/docs:ro — the :ro suffix forces read-only (sbx run).
  • Use --branch for any task that mutates the working tree. The flag is "a workflow convenience, not a security boundary", but it bounds what you have to review (Workspace trust).
  • Store credentials with sbx secret set, not env vars. Built-in services (anthropic, aws, github, google, openai, and so on) bind to the proxy's domain matchers, and values live in the OS keychain. Sandbox-scoped changes apply immediately; global changes apply only on the next sandbox creation (Credentials).
  • Audit before each release cycle. sbx policy ls shows active rules, and sbx policy log lists every contacted host with its matching rule and proxy type.
  • After every session, check .git/hooks/ and CI configs. git diff will not surface .git/hooks/ changes, so list them explicitly with ls -la .git/hooks/.

Composition with site patterns

sbx is one concrete version of existing site patterns, not a replacement:

Caveats to watch

Every sbx doc page carries an Availability: Early Access banner. These surfaces are still unstable:

  • sbx secret set-custom is hidden from sbx --help, and the docs warn "behavior, flags, and the placeholder format may change" (Custom secrets).
  • CLI surface naming. The reference lists sbx run and sbx create, while internal redirects expose docker sandbox run and docker sandbox create — the longer form may be where it lands at GA.
  • Balanced allow-list contents. The docs describe it as "AI provider APIs, package managers, code hosts, container registries, and common cloud services", but the exact membership shifts release to release, so query it with sbx policy ls.

Pin a known-good sbx version in CI and re-run sbx policy ls after upgrades.

Example

A team adopting sbx for Claude Code sessions in CI starts from Locked Down:

# CI bootstrap, before any sbx run
sbx policy set-default deny-all
sbx policy allow network "api.anthropic.com,api.github.com,github.com,*.npmjs.org,registry.npmjs.org,files.pythonhosted.org,*.pypi.org"

# Credentials in the OS keychain, never in env vars
echo "$ANTHROPIC_API_KEY" | sbx secret set -g anthropic
echo "$(gh auth token)" | sbx secret set -g github

# Run the agent on a separate branch with a read-only docs mount
sbx run --branch=feature/issue-1234 claude . ../shared-docs:ro

# After the session — audit before trusting host-side execution
sbx policy log my-sandbox --limit 50
ls -la .git/hooks/
git diff main..feature/issue-1234

The policy log output names the matched rule and proxy type for every contacted host (forward, forward-bypass, transparent, browser-open), so unexpected destinations are visible without grepping packet captures.

Key Takeaways

  • Docker sbx is microVM-isolated with a host-side proxy — the four-layer model (hypervisor, network, Docker Engine, credential) is what you actually adopt, not "rootless container plus seccomp."
  • The residual leak surface is the workspace direct mount and the Balanced default's broad wildcards. Treat workspace edits as an untrusted PR; audit .git/hooks/ separately because git diff does not surface them.
  • For CI, call sbx policy set-default before the first sbx run to avoid hanging on the interactive policy prompt.
  • Store credentials with sbx secret set, not via env vars — values stay on the host and the proxy injects auth headers post-egress.
  • sbx is Early Access; pin a version, re-audit sbx policy ls after upgrades, and avoid sbx secret set-custom for production until it leaves experimental status.
Feedback