Skip to content

Isolating agentic AI coding tools with Docker Sandboxes

Provisional

Docker Sandboxes are one approach the DevOps Tech Lead Forum is trialling, not an agreed standard for the division. Treat the reasoning here as a snapshot of an ongoing experiment rather than a settled recommendation, and expect it to change as we learn more.

We're experimenting with ways to secure agentic AI coding tools such as Claude Code. This page explains what Docker Sandboxes are, how they isolate an agent from the host, and why we've chosen the network settings we recommend.

Tip

Looking for setup steps instead? See our tutorial on using docker sbx to run Claude Code sandboxes.

Why isolate agentic coding tools from the host?

An agentic coding tool doesn't just suggest text. It runs shell commands, installs dependencies, edits files, and makes outbound network requests, all with only loose supervision. Content the agent reads while doing this, a web page it fetches, a file in a cloned repository, the output of a command it runs, can also steer its next action. A tool that follows instructions hidden in that content is said to be vulnerable to prompt injection, and there's no reliable way to guarantee an agent will never be steered this way.

For a DevOps division, the host machine running an agent is rarely just a laptop. It usually holds cloud credentials, SSH keys, GitLab tokens, and access to infrastructure that can affect production systems. If an agent is tricked into running a malicious command or exfiltrating data, the damage it can do is bounded by what it can reach. Isolating the agent from the host shrinks that reach before anything goes wrong, rather than relying entirely on the agent behaving as intended.

What is a Docker Sandbox? MicroVMs, not containers

A Docker Sandbox isn't a container in the usual sense. Where a normal container is a process that shares the host's kernel, isolated by namespaces and cgroups, a Docker Sandbox boots a lightweight virtual machine with its own kernel, using a hypervisor. This is often called a microVM.

The distinction matters for what an escape looks like. A container escape needs to break out of namespace and cgroup isolation to reach the host kernel directly, something that has happened in practice via kernel vulnerabilities. A microVM escape has to break out of hardware-enforced virtualization first, a materially stronger boundary that isn't affected by the same class of container-escape bugs.

The isolation goes further than the kernel. The Docker daemon that builds and runs containers inside the sandbox is itself running inside the microVM, not shared with the host. An agent working inside a sandbox that happens to run docker build or docker run is talking to a daemon that only exists inside that VM. It has no way to see, control, or pivot through the host's own Docker daemon, containers, or images.

What is and isn't available inside the sandbox

Available inside the sandbox Not available inside the sandbox
The working tree of the project you started the sandbox from The host filesystem outside that project
A Docker daemon internal to the microVM The host's own Docker daemon, containers, or images
Outbound network access, limited by the active network policy Host processes
Anything you explicitly bring in, for example via sbx skills import Host environment variables or secrets you haven't explicitly passed in

The isolation works in both directions. For example, when you sign in to Claude from inside a sandbox, the resulting session token is stored on the host, never inside the sandbox itself, so a compromised sandbox can't walk away with it.

Network profiles: default-deny, then widen deliberately

By default, we suggest that sandboxes start on the Balanced network profile, which permits traffic to common development services and blocks everything else. We recommend starting every sandbox here rather than on a fully open profile, then widening it per project with a kit, a small YAML file checked in beside the code listing the extra domains that project needs. The tutorial walks through writing one.

This default-deny, widen-on-demand approach matters because an agent's outbound network access is exactly the kind of thing prompt injection can try to abuse, for example by getting the agent to send data somewhere it shouldn't. Starting from a small allowlist and growing it per project keeps that attack surface as small as the project needs, instead of open by default and hoping nothing goes wrong. Other, more or less restrictive profiles exist for cases that need them, but Balanced plus a per-project allowlist is our current standard starting point.

Declaring that allowlist in the repository rather than adding it with one-off CLI commands also makes it reviewable. A new domain arrives in a merge request where someone else sees it, instead of accumulating on one engineer's machine where nobody can tell what a sandbox is permitted to reach.

What this does and doesn't protect against

Running an agent in a Docker Sandbox contains the blast radius if the host is what you're worried about, and it narrows the paths available for data to leave the machine. It doesn't replace reviewing the agent's changes before you merge them. An agent that has network access to an allowlisted service can still misuse that access within the sandbox, and isolation from the host says nothing about whether the code the agent wrote is correct or safe to ship.

Does the agent get access to my other repos or projects on this machine?

Not by default. Only the working tree of the project you ran sbx run from is mounted into the sandbox, and the rest of your filesystem stays invisible to it. You can widen this deliberately by passing extra paths to sbx run, for example sbx run claude ~/project-a ~/shared-libs:ro, which mounts each additional directory into the sandbox too, appending :ro mounts one read-only. Only reach for this when the agent genuinely needs that extra context, since every additional workspace widens what it can read or change.

What happens when the agent needs to reach a domain that isn't allowed?

The request is blocked. Run sbx policy log to see what was blocked and why, then allow the domain with sbx policy allow network <domain> if it's one your project genuinely needs. See the tutorial's section on allowing network access for the full walkthrough.

Summary

Docker Sandboxes isolate agentic coding tools from the host using microVMs rather than containers, with their own kernel and their own Docker daemon, so an agent can't reach the host's filesystem, processes, or Docker environment. Combined with a default-deny network profile that we widen deliberately per project, this is our current experimental answer to letting agentic tools run usefully without handing them the keys to the host.

See also