Sandboxes for AI coding agents, compared

Five ways to keep an autonomous coding agent away from your credentials and your home directory, including the ones that are not ours. Cleat is one option below, its weaknesses are listed like everyone else's and every claim is checked against the vendors' own docs. Verified 2026-07-14.

The short version #

Four approaches, same five questions. Details, sources and the honest caveats for each follow below.

Claude Code /sandbox + auto mode

Boundary
OS sandbox around Bash commands only. Read, Edit, MCP servers and hooks stay outside it
Inside by default
Your whole disk is readable, including ~/.ssh and ~/.aws, until you deny or mask paths in settings
Network
Proxy allowlist, prompts per new domain
Unattended
"Not sufficient" on its own, per Anthropic’s docs
In practice
Built in and free. Keep it on. It layers with everything below

Dev container

Boundary
Container around the whole session
Inside by default
Whatever the config mounts, the workspace by default
Network
Default-deny firewall in Anthropic’s reference config
Unattended
Yes, the reference config is built for it
In practice
Bring VS Code or the devcontainer CLI. Edit JSON and a Dockerfile, rebuild to change anything

Docker Sandboxes

Boundary
MicroVM: own kernel, own Docker daemon. The strongest local isolation here
Inside by default
Your workspace only
Network
Own network stack, configurable policies
Unattended
Yes, on by default
In practice
The heaviest local option, tied to Docker’s sandboxes stack (macOS, Windows, Ubuntu)

Cleat

Boundary
Container around the whole session
Inside by default
Your project and nothing else. Credentials are opt-in, per-project capabilities
Network
Full egress, no allowlists yet. Our gap, listed below
Unattended
Yes, that is the point
In practice
Type cleat and you are in. Sessions, clipboard, kits, uid mapping solved. Runs on any Docker engine

What you are actually defending against #

Two failures do almost all the damage in practice. An agent running as you can read ~/.ssh, ~/.aws, .npmrc tokens and .env files and ship a live key to the internet. And one wrong rm can end your home folder. Kernel escapes are real but rare. A leaked key is a Tuesday. Judge every option below by what sits inside the boundary with the agent, not by the fanciest attack it can stop.

Anthropic's own guidance for unattended use is blunt. For --dangerously-skip-permissions, their sandbox environments page says an isolation boundary is the only thing limiting what Claude can do and to "always run it inside a container, a VM, or the sandbox runtime". Every option on this page satisfies that in some form. They differ in what is reachable from inside and in how much workflow you give up to get there.

One caveat applies to all of them, ours included: whatever mounts your project directory writable can modify your code. That is the point of a coding agent. It is why reviewing the diff stays your job no matter which boundary you pick.

Claude Code's built-in /sandbox and auto mode #

The strongest thing about the built-in sandbox is that it is already there. Run /sandbox and Bash commands get an OS-enforced boundary (Seatbelt on macOS, bubblewrap on Linux and WSL2): writes are limited to the working directory and session temp. Network access goes through a proxy that prompts per new domain. Auto mode adds a classifier that reviews each action instead of prompting you. For attended, everyday work this is a genuinely good default and it composes with everything else here. There is no reason not to have it on.

The limits are stated plainly in Anthropic's sandboxing docs and they matter for unattended use. The boundary wraps Bash commands only: the Read and Edit tools, MCP servers and hooks run outside it. The default read policy allows the rest of your disk, including ~/.ssh and ~/.aws/credentials. Since v2.1.187 you can deny or mask specific files and environment variables with sandbox.credentials and that works, but there is no built-in deny list: only what you list is protected. There is also an escape hatch, on by default, that retries failed commands outside the sandbox through the permission flow. And Anthropic itself says the Bash sandbox alone "is not sufficient for fully unattended runs".

Keep /sandbox on. It is free and it layers, including inside a Cleat box. But as your main line of defense it asks you to write and maintain the deny list, accept per-domain prompts and trust an escape hatch you have to remember to close. Cleat's answer to the same problem is to give the agent full permissions in a place your keys never entered. Nothing to list, nothing to prompt, nothing to remember: configuration versus construction.

Dev containers #

A dev container puts the whole session inside the boundary: file tools, MCP servers and hooks included. Anthropic publishes a reference dev container with a default-deny firewall, explicitly built to support --dangerously-skip-permissions for unattended work. Committed to a repo, it standardizes the environment for a whole team. The environment definition gets reviewed like code. That is a real strength no tool-shaped option replicates.

The honest trade is that it is a config, not a product. You bring Docker plus VS Code or the devcontainer CLI, you edit JSON and a Dockerfile to change the boundary and you rebuild to apply it. The daily ergonomics that containers break, clipboard, sessions that survive restarts, switching between projects, are yours to assemble and maintain. And the thing teams actually commit a devcontainer for, a reviewable in-repo record of what the agent may touch, Cleat commits too: each project's .cleat file carries its capabilities and trust settings, versioned like any other file. The difference left over is the loop: edit, rebuild, reopen versus type cleat and you are in the box.

Pick a dev container if you already define your whole toolchain as an image and live in VS Code. If what you want is an agent in a cage with the config in the repo, that is what Cleat already is, one command shorter and no editor required.

Docker Sandboxes and other microVMs #

Docker Sandboxes give each agent a microVM: its own kernel, its own filesystem and network stack, its own Docker daemon. sbx run claude mounts your workspace in and launches Claude Code with skip-permissions on, safely, because the VM boundary holds even if the agent owns everything inside it. This is stronger isolation than Cleat has. If a kernel exploit is inside your threat model, this is the local tool that addresses it. We are not going to pretend otherwise. The CLI is free, including for commercial work. Central governance is the paid part.

The same tier includes the hosted options: Claude Code on the web runs sessions in Anthropic-managed VMs cloned from GitHub. Firecracker-based services rent you the same boundary per API call. Zero local setup, full VM isolation and the trade is that your code runs on someone else's machine.

What you give up locally is weight and workflow: a VM per project with its own daemon is a heavier stack than a container, the feature is young (it shipped in 2026) and it is tied to Docker's own tooling rather than whatever engine you already run.

Pick Docker Sandboxes when the kernel is part of your threat model or the code you are running is untrusted. That concession is real. For your own agent on your own repos, it buys isolation beyond the failure modes that actually bite. It costs you the weight of a VM per project plus Docker's own stack. Cleat covers those failure modes with whatever engine you already run.

Where Cleat fits #

Cleat runs Claude Code in a plain Docker container, one per project, with full autonomous permissions inside. The security model is construction, not configuration: your SSH keys, cloud credentials, tokens and dotfiles are not denied by a rule you wrote, they are simply not in the container. There is nothing to remember to list. When the agent genuinely needs a credential, you grant it as a per-project, opt-in capability and only that project's box gets it.

The rest of the tool is the workflow tax refund. It is docker run plus the parts that each take a weekend to get right: clipboard that works from inside the box, files owned by you instead of root, stop and resume with full session context, named boxes per project, a browser bridge for OAuth logins and kits that preconfigure the agent. One command instead of a flag soup you maintain forever. It works with the Docker engine you already have: Desktop, OrbStack, Colima, native Engine, rootless. And it is a single MIT-licensed Bash file you can read top to bottom before trusting it.

It is also not a launch-week demo. Cleat is how its maintainer runs his own daily, heavy development, months of long unattended sessions and the rough edges you would hit first got hit and fixed already. Per-project configuration lives in a .cleat file you can commit, so a repo can carry its cage settings the same way a devcontainer repo carries its JSON.

The scope is deliberate and worth saying twice: this is a container, not a microVM. The threat model is your own agent inside your own repo, where the expensive failures are a read credential and a stray delete. For "the agent cannot reach my keys or my home folder", a container is the right blast door. If you need kernel isolation, use Docker Sandboxes and we mean that.

$ curl -fsSL https://cleat.sh/install | bash

Where Cleat is weak #

A comparison that hides its author's weaknesses is an ad. These are ours, current as of the verification date above.

Plain containers

The box shares the host kernel. A container stops credential reads and stray deletes. It is not a defense against kernel exploits. MicroVMs are strictly stronger isolation.

No network policy yet

The box has full egress. The built-in /sandbox proxy and the reference dev container's firewall both do better here today. Allow/deny lists are on the list.

Claude-first

Built around Claude Code. There is a shell for anything else, but if your daily agent is not Claude, other options fit better today.

Shared auth

Your Claude login (~/.claude) is shared across boxes. Capabilities and the filesystem are per-box. Auth is not yet.

Choose by situation #

A quick attended session, nothing installed

The built-in /sandbox with auto mode is fine. It also layers inside a Cleat box.

Unattended runs, heavy sessions, your own repos

Cleat. Keys out by construction, sessions survive restarts, one command per project.

The agent config reviewed in the repo

Cleat commits it in .cleat. Pick a dev container only if the whole toolchain image is the point.

Untrusted repos, or the kernel is in your threat model

Docker Sandboxes or a dedicated VM. A shared kernel is not enough there.

No local setup at all

Claude Code on the web: Anthropic-hosted VMs, cloned from GitHub.

Don't take our word for the landscape: Anthropic's own comparison covers the same ground from the vendor's side. If this page and that one disagree, tell us on GitHub and we will fix ours.

Try the container answer

One command to install, one command per project. Your keys never enter the cage. It is one file of Bash you can audit before you run it.

$ curl -fsSL https://cleat.sh/install | bash

Then read the docs for capabilities, boxes and kits.

Install command copied Paste it in your terminal to install Cleat