Picture this. You’ve just given an AI coding assistant a task, and a minute later it’s running commands, installing packages and rewriting files. You watch the terminal scroll and wonder whether you should have let it do this on your real laptop.
That worry is the reason Docker Sandboxes exist, and kits are what make them practical to live with. Here’s what kits are, what’s inside one, and how the whole thing works.

Start with the sandbox
A Docker Sandbox is a walled-off workspace where an AI agent can do its work without touching the rest of your machine. Docker launched the feature in March 2026, and you drive it with a command-line tool called sbx. It’s a standalone program, so you don’t need Docker Desktop to use it.
The usual comparison is an apartment with a locked door. The agent can rearrange the furniture all it likes, and when it’s done you can demolish the apartment and start fresh.
The catch is that a fresh apartment is empty, with no furniture, no tools and no Wi-Fi password. Docker’s own engineers say as much. One of them wrote that an empty sandbox is a good boundary, but that kits are what make sandboxes survivable as a development tool. Without them you’d redo the same setup every time.
So what is a kit?
A kit is a small, shareable bundle that describes what a sandbox needs. It can also include credentials and instructions for the agent. Docker’s docs list what a kit can carry:
Tools to install
Environment variables to set
Credentials to inject
Network rules that allow or block websites
Files to drop in
Startup commands to run
Instructions for the agent
All of it goes in one text file called spec.yaml, plus an optional files/ folder for anything you want copied in. You point the sbx command at it, and the sandbox applies it and enforces it at runtime. One writer put it nicely: kits are to agent environments what Dockerfiles are to app environments. If you know Dockerfiles, you already have the right instinct.
The community repo you shared, docker/sbx-kits-contrib, is a shared shelf of these kits. Each top-level folder is one kit.
Two kinds of kit
Mixins add something to an agent that already exists, like plugging a lamp into the wall. You can stack several on one sandbox.
Sandbox kits (in the repo’s older terminology, “agent” kits) define a whole agent from scratch, including its image and the command that launches it. You’d use one to package a custom agent so others can run it.
A third idea is worth knowing. A kit can use extends: to make a variant of a built-in agent, such as Claude Code with a different permission mode. The child inherits everything from its parent, and the parent’s setup steps run first.
One note on versions. Docker is moving fast here. The v0.45.0 release notes introduce “v3 kits,” which separate the main workload from reusable mixins, while v2 kits keep working. The README itself warns that the format is experimental and may change. Treat anything you build today as something you’ll revisit.
A kit, line by line
Here’s the shape of a simple kit in the current v2 style, based on Docker’s docs:
setup:
install:
- command: "apt-get update && apt-get install -y jq"
startup:
- command: ["my-daemon"]
background: true
environment:
variables:
MY_TOOL_WORKSPACE: /home/agent/my-tool
permissions:
network:
allow:
- api.example.com
deny:
- telemetry.example.com
agentInstructions:
content: |
jq is installed. Use it to inspect JSON before editing it.Reading it top to bottom:
Install commands run once, when the sandbox is created. This is where you put anything the agent needs on the machine.
Startup commands run every time the sandbox starts. They’re meant for background services, and they must be safe to run repeatedly.
Environment variables are simple settings the agent can see.
Network rules say which websites are reachable. If a domain matches both an allow and a deny rule, deny wins.
Agent instructions get appended to the agent’s memory file (
CLAUDE.mdorAGENTS.md, depending on the agent). It’s a way to tell the agent, “hey, this tool is here, here’s how to use it.”
Files in the files/home folder get copied into /home/agent/ inside the sandbox. This suits shared linter rules, editor settings and helper scripts.
The clever part: secrets stay out of the sandbox
Handing an API key to something running inside a sandbox is a bit nerve-wracking, and Docker’s design handles it well.
A kit declares which service it needs and how the credential should be attached to requests. The real key lives on your computer. Inside the sandbox, the agent only sees a placeholder. When the agent makes a request, a proxy on your machine swaps the placeholder for the real key before the request leaves. Docker’s tutorial for packaging Claude Code as a mixin shows this: ANTHROPIC_API_KEY inside the sandbox holds a placeholder, and the host proxy inserts the real key into the request header.
The real secret never enters the sandbox. One consequence is that you shouldn’t put secrets in environment.variables, because anything there is visible inside.
A second consequence is that credentials and network access are separate permissions. Declaring a credential doesn’t let the agent connect to that service, so you have to allow the domain too.
Using a kit
You pass kits with the --kit flag, and it accepts several kinds of source: a local folder, a ZIP file, a Git repository, or an OCI registry such as Docker Hub.
# From a local folder
sbx run claude --kit ./my-mixin/
# From a registry
sbx run claude --kit ghcr.io/myorg/my-kit:1.0
# From a Git repo, pinned to a tag
sbx run claude --kit "git+https://github.com/docker/sbx-kits-contrib.git#ref=v0.1.0&dir=code-server"Pinning matters. Without ref, you follow the repo’s default branch and the kit can change under you. A tag or an exact commit keeps things reproducible.

Join the conversation! Your thoughts help the community grow.