Your AI Agent Can Run rm -rf /. Put It in a Sandbox.
Docker Sandboxes is Docker's tool for running AI coding agents inside an isolated microVM on your own machine, managed by a standalone CLI called sbx. It exists because of an uncomfortable default. When you start Claude Code inside a sandbox, it runs with claude --dangerously-skip-permissions as the standard startup command. Not because someone was reckless, but because that is the mode the sandbox is built to make safe (Docker docs, Claude Code agent page).
That flag is the entire problem this post is about. Every coding agent has an equivalent: Codex bypasses approvals, while Cursor, Copilot and Gemini use what their vendors call YOLO mode. The official tutorial is blunt about it. The built-in sandbox integrations start agents "in their full-autonomy mode," and you don't need to add those flags yourself.
Full autonomy is genuinely useful. At the same time, it is exactly the blast radius you would never hand to a shell prompt that answers to a language model. Docker's own launch post for the microVM release puts the trade in one line: "Since they can't harm your computer, let them run free" (Docker blog, January 2026).
In this post:
- Why a container is not enough anymore
- What actually crosses the trust boundary?
- The 10-minute setup
- How do you control what the agent can reach?
- Which sandbox mode fits your workflow?
- FAQ
Key Takeaways
- Docker Sandboxes (
sbx) runs each coding agent in its own microVM with its own kernel, filesystem, and Docker daemon. The agent gets sudo inside the VM and cannot reach your host outside the files you explicitly share (security model).- Your workspace directory is the exception: a direct mount is read-write, so the agent can still delete your working tree. Use
--clonewhen that matters.- The
sbxCLI and local compute are free, including commercial use, and do not require Docker Desktop (pricing).- Network policy defaults matter more than the VM itself: with the Locked Down preset, even your model provider's API is blocked until you allow it.
Why a container is not enough anymore
The usual answer to "my agent is dangerous" is "put it in a container." That answer was reasonable when the dangerous thing was a build script. A coding agent, however, is a different animal, for one reason: it holds a conversation with you, decides what to run next, and keeps going while you are getting coffee.
Two container-era assumptions break down. First, containers share the host kernel. Namespaces and cgroups give you a lot, but a kernel-level isolation boundary is not a hardware-level one. A microVM is a lightweight virtual machine with its own kernel, booted under a hypervisor, which gives the agent a hardware-enforced boundary instead. Docker describes the microVM as the "primary trust boundary" in its security model. The agent has full control inside the VM, including sudo, and the VM boundary is what stops it from reaching anything else.
Second, an agent that can build containers is an agent that wants the Docker socket. This is the part people forget. I wrote about this class of problem in my post on Compose healthchecks: a tool with host Docker access is a tool with root on the host, because docker run -v /:/host is always sitting there. Sandboxes solve it in an unusual way. Each sandbox runs a private Docker daemon inside the VM, so the agent can build images, pull, and run containers to its heart's content, with zero access to your host daemon. Docker claims this is unique among sandboxing options, and I have not found a counterexample (Docker blog, architecture docs).
One sandbox, meanwhile, is a real Linux environment. The agent installs packages, edits files, and starts services. When a run goes sideways, you delete the whole thing and start a fresh one in seconds. That disposal loop, more than any single feature, is what changes how much autonomy you can comfortably grant.
What actually crosses the trust boundary?
This is the part worth internalizing, because "it's sandboxed" is doing a lot of vague work in most conversations. The security model page is unusually specific about what crosses in, what crosses back, and what never crosses at all. I found it the most useful page in the whole docs set, and it is the reason this post exists.
Into the VM:
-
Your workspace directory, when you run
sbx runfrom a project folder or pass a path. A direct mount is read-write, and the agent's edits land in your working tree in real time. With--clone, the repo is mounted read-only and the agent works on a private clone inside the sandbox. A mountless sandbox shares no host directory at all. - Credentials, but not really. A host-side proxy injects authentication headers into outbound requests. The raw credential values never enter the VM. This is a genuinely clever design: the agent uses your GitHub or Anthropic auth without ever holding the token.
- Outbound TCP to allowed destinations, proxied through the host.
- A shared skills store, mounted read-only by default at the agent's skills directory.
Back to the host:
- Workspace file changes (instant, on direct mounts).
- Outbound connections you allowed.
- Skill store writes, only if you flipped the skills mount to read-write.
Never:
- Your host filesystem outside the workspace and skills store.
- Your host Docker daemon.
- Your host network interfaces directly. Sandboxes cannot talk to each other over the network. Outbound UDP is blocked unless you turn on an experimental flag, and ICMP is blocked outright.
The one honest caveat, and the reason clone mode exists: a direct mount is read-write. The docs say it plainly. Your project directory is the exception to the sandbox boundary, and the agent can modify or delete its files (tutorial). Andrew Lock's hands-on writeup of running Claude Code this way reached the same conclusion. In his words, the sandbox only has access to your working directory, "so yes, it could delete your git repo," and that is basically the extent of the damage it can do (andrewlock.net). Therefore, keep your work under version control, or use clone mode, or both.
The 10-minute setup
sbx is the standalone CLI that creates and manages sandboxes. It does not require Docker Desktop or Docker Engine on the host, and local sandbox compute is free including for commercial work (install docs, pricing).
Install for your OS. macOS uses Homebrew, Windows uses winget, and Ubuntu installs the docker-sbx package from Docker's apt repository:
$ brew trust docker/tap && brew install docker/tap/sbx # macOS
$ winget install -h Docker.sbx # Windows
$ curl -fsSL https://get.docker.com | sudo REPO_ONLY=1 sh # Ubuntu, repo only
$ sudo apt install docker-sbx
Then sign in once with Docker OAuth:
$ sbx login
Next, start an agent from a project directory:
$ cd ~/my-project
$ sbx run --name my-sandbox claude
The first run pulls the agent template (docker/sandbox-templates:claude-code), which takes a moment. Afterwards, it prompts you to choose a default network policy for all your sandboxes: Open (everything allowed), Balanced (default deny, common dev destinations allowed), or Locked Down (nothing allowed until you say so). The get-started guide recommends Balanced as the starting point.
Claude Code then starts inside the sandbox. If you have a Claude subscription, type /login inside the session. The OAuth token stays on your host and is never stored inside the sandbox. If you use an API key instead, sbx secret set anthropic stores it on the host side where the proxy can use it without exposing it to the agent.
Give the agent a real task. While it runs, open a second terminal and look around:
$ sbx ls
SANDBOX AGENT STATUS PORTS WORKSPACE CREATED
my-sandbox claude ● running ~/my-project 2m
That workspace column is the entire filesystem the agent can see of your machine. To drop into a shell inside the VM yourself:
$ sbx exec -it my-sandbox bash
You land in the primary workspace, inside a Linux machine the agent has sudo on. Poke around, run ps, look at what the agent installed. This is the moment the model clicks: it is a computer, not a chroot.
When you are done, the lifecycle commands do what their names say. sbx stop pauses the sandbox and preserves everything inside it across restarts. sbx rm deletes the sandbox and everything in it, while your host working tree stays untouched. Meanwhile, running sbx with no arguments opens an interactive dashboard with live CPU and memory per sandbox, a network panel, and keyboard shortcuts to attach, shell in, stop, or remove.
Replacing claude with codex, copilot, cursor, gemini, opencode, kiro, or droid works the same way. The full supported list is on the agents page, along with a shell agent-less template for manual setup.
How do you control what the agent can reach?
Filesystem isolation is half the story. The other half is network egress, and this is where the preset you picked during first run earns its keep.
Network policy is the allowlist the sandbox applies to outbound connections. Check the rules in effect:
$ sbx policy ls
Allow one more host:
$ sbx policy allow network registry.npmjs.org
The three presets differ in what they block by default, and the differences are the entire security posture of a run:
| Preset | Outbound traffic | Model provider API | Good for |
|---|---|---|---|
| Open | Everything allowed | Allowed | Trusted tasks on machines with nothing to protect |
| Balanced | Denied by default, common dev sites allowed | Allowed | Daily development; the docs' recommended start |
| Locked Down | Everything blocked | Blocked until allowed | Untrusted or unattended tasks; allow exactly what the job needs |
The get-started guide includes a detail I appreciate: with Locked Down, even your model provider's API is blocked until you explicitly allow it. That point is the actual security model in miniature. Locked Down means an agent that goes rogue cannot phone home anywhere, exfiltrate your workspace to a paste site, or quietly download a second stage, unless you allowed that destination. For a task you do not fully trust, the workflow is: locked down, then allow exactly api.anthropic.com (or your provider's endpoint) plus the package registries the task needs, and nothing else. An allowlist you can read in one command beats a permission dialog you learned to click through.
Two related controls are worth knowing. First, secrets, not environment variables: -e VAR=value on sbx run works, but the docs warn that environment variables are readable by processes inside the sandbox, so for API keys sbx secret set keeps the value on the host and has the proxy inject it into outbound requests instead. Second, registry credentials for builds: the sandbox's Docker daemon pulls from Docker Hub using your sbx login session, but for other registries you must store pull credentials first. For example, gh auth token | sbx secret set --registry ghcr.io --password-stdin. Otherwise, private image pulls fail as anonymous.
Which sandbox mode fits your workflow?
The default (sbx run claude from a project directory, read-write mount) is the right choice most days: you watch the agent's edits appear in your working tree as a normal Git diff and commit what you want. The usage guide documents the rest of the toolbox:
-
--clonemounts your repo read-only and hands the agent a private clone. This is the mode for running several agents against one repository, and the mode for the days you do not trust the diff. The clone lives inside the sandbox; remove the sandbox and the clone is gone. -
Mountless sandboxes (
sbx create --name scratch claude, no path) share no host directory at all. The agent works in/home/agent/workspaceinside the VM, files persist across stops, andsbx cpmoves things in and out. Good for experiments you want fully disposable. -
--rmmakes the whole session a throwaway: the sandbox is deleted the moment the agent exits, andsbx runreturns the agent's exit status. This is the CI shape of the tool. -
Detached sandboxes (
sbx run -d) keep running after your sessions end, which pairs with published ports when the agent is running a service you want to poke at. -
sbx moverecreates a sandbox's filesystem on Docker-managed cloud infrastructure, or back. This is how a heavy build migrates off your laptop without changing anything about the environment.
That list is also the honest sizing of the tool. Sandboxes are a laptop-and-workstation product with a cloud escape hatch, not a fleet-management layer. What you get locally is the free tier, and it is the part that matters: a hard boundary between "things the agent can ruin" and "everything else."
FAQ
Do I need Docker Desktop to use sbx?
No. The CLI installs standalone and local sandbox compute is free, including for commercial work. Cloud compute is a separate pay-as-you-go subscription, and organization-wide policy governance is a separate paid plan (pricing).
Can the sandbox agent still destroy my code?
Inside a direct mount, yes: the workspace is shared read-write and the agent can delete files there. That is why the docs tell you to keep your work under version control, and why --clone exists when you want the repo protected.
How is this different from just running the agent in a container?
A container shares your host kernel and, if you give it the Docker socket, effectively owns the host. A sandbox is a microVM with its own kernel and its own Docker daemon, so "build and run containers" and "isolate from the host" stop being mutually exclusive.
Can the agent reach the internet?
Only through the network policy you allow. Sandboxes cannot reach your host network directly, cannot talk to each other, outbound UDP is blocked unless you enable an experimental feature, and ICMP is blocked.
Where do my API keys live?
On the host. A proxy injects credentials into outbound requests, and the raw values never enter the VM. Environment variables, by contrast, are readable inside the sandbox, so use secrets for anything sensitive.
The five commands that matter
Install, log in, run, inspect, delete: brew install docker/tap/sbx (or your OS equivalent), sbx login, sbx run claude, sbx ls, sbx rm my-sandbox. Everything else in this post is nuance on top of that loop.
The trade you are making is explicit now instead of implied. The agent runs at full autonomy, with sudo, on a machine it cannot escape, that you can delete with one command when the run goes wrong. The alternative is a permission prompt you have trained yourself to approve without reading, on a machine that has your SSH keys on it. I know which one I let run overnight.
Verified against docs.docker.com (Sandboxes overview, install, get-started, usage, security model, architecture, agents, Claude Code agent page), the Docker Sandboxes product page, and the Docker launch blog post, all retrieved 2026-10-25. Every factual claim links to its source. I did not run the walkthrough on this machine; instead, each claim traces to the linked documentation, and I flag anything I could not verify.
Sources
Every claim above traces to these primary sources. Where I could not verify something hands-on, the post says so.
- Docker docs, Claude Code agent page
- official tutorial
- Docker blog, January 2026
- security model
- pricing
- architecture docs
- Cutaway diagram of the microVM trust boundary: what crosses in, what crosses back, what ne
- andrewlock.net
- install docs
- get-started guide
- agents page
- usage guide
- Isometric diagram of the four sandbox working modes: direct mount, clone, mountless, and d
- GitHub
About the author
Kunal Das writes operations engineering notes as he learns them, always against primary sources. Contact: GitHub and Dev.to. Follow the Docker tag for the next posts in this series.


Top comments (1)
The read-write workspace mount is the honest caveat. A sandbox that can delete your working tree is not a sandbox for that tree. Clone mode plus version control is the only combination I would trust for an agent running in full autonomy mode.