ExGuardian

Guide · Isolation for agent-run code · Sources read on 29 October 2026

AI agent sandbox: pick the boundary by what can go wrong.

Short answer. An AI agent sandbox limits what code run by the agent can touch. There are four layers. An OS process sandbox (Seatbelt, bubblewrap, seccomp) is what Codex and Claude Code use. A container shares the host kernel. gVisor answers system calls in user space. A microVM such as Firecracker runs its own kernel, and E2B and Vercel Sandbox are built on it. Choose the layer by how untrusted the code is and what sits on the host. Then close the two settings most setups leave open whatever the layer: outbound network and the secrets inside the sandbox.

What does an agent sandbox need to stop?

Agent code fails in two ways: the model makes a mistake, or someone steers it through indirect prompt injection. Either way the sandbox has the same six jobs:

Which isolation layer stops what?

LayerHow it isolatesShares the host kernelStopsLeaves openExamples
Process sandboxSeatbelt on macOS; bubblewrap namespaces, seccomp and Landlock on LinuxYes, and the same user accountWrites outside allowed paths, network outside a proxy allowlistKernel exploits; reads unless denied; anything the agent runs outside the sandboxCodex, Claude Code, sandbox-runtime
ContainerNamespaces, cgroups, capabilities and a seccomp profileYesHost filesystem and processes, when hardenedKernel exploits; anything a mounted socket or volume exposesDocker, Podman
User-space kernelgVisor's Sentry answers system calls itself instead of passing them to the host kernelNo direct access: a small, seccomp-restricted host surfaceMost kernel attack surfaceSome syscalls and /proc files are not implemented; slower on syscall-heavy workgVisor (runsc), Modal's gvisor runtime
MicroVMHardware virtualization through KVM, with a minimal device model and its own guest kernelNoGuest kernel exploits reaching the host, short of a hypervisor escapeNothing at the boundary itself; network and secrets are still yours to closeFirecracker, Kata Containers, E2B, Vercel Sandbox, Cloudflare Containers

Every layer can block writes and persistence if you configure it, and containers and VMs add resource limits. Kernel escape is the one that separates them. Untrusted code that shares your kernel is one kernel bug away from the host. That is acceptable on a developer laptop running the developer's own agent, and not on a service that runs code for many customers.

How do process sandboxes work in Codex and Claude Code?

Both coding agents wrap each shell command in an OS sandbox and leave the agent process itself outside it. Codex uses Seatbelt on macOS, bubblewrap with seccomp on Linux and WSL2, and MXC or a dedicated sandbox user on Windows. Claude Code's sandbox is off by default and is built on the open-source sandbox-runtime, which you can also use on its own to wrap any process, a local MCP server included:

~/.srt-settings.jsonsandbox-runtime
{
  "network": {
    "allowedDomains": ["github.com", "*.github.com", "registry.npmjs.org"],
    "deniedDomains": []
  },
  "filesystem": {
    "denyRead": ["~/.ssh", "~/.aws"],
    "allowWrite": [".", "/tmp"],
    "denyWrite": [".env"]
  }
}

sandbox-runtime denies all network by default and routes allowed traffic through HTTP and SOCKS5 proxies on the host. On Linux the sandboxed process gets no network of its own, so the proxies on the host are the only way out. Without a settings file, reads stay unrestricted, so add denyRead entries for credential folders. On Linux, socket blocking relies on seccomp (x64 and arm64), and if seccomp is missing sockets stay open with a warning. Windows support is alpha.

A process sandbox shares your kernel and your user account. Whatever the agent starts outside it also runs with your full access: hooks, MCP servers, language servers. Run the whole agent in a dev container or VM when the repository is not yours.

Is a container enough for agent-generated code?

A container is a process with namespaces, cgroups, dropped capabilities and a seccomp filter. Docker's default seccomp profile disables around 44 system calls out of more than 300, and --security-opt seccomp=unconfined removes it. The rest of the kernel stays reachable. For an agent's own commands on a machine you control, a hardened container is a solid boundary. These flags remove most of what a default docker run leaves open:

docker runhardened agent runner
docker run --rm -it \
  --user 1000:1000 \
  --cap-drop ALL \
  --security-opt no-new-privileges \
  --read-only --tmpfs /tmp \
  --network none \
  --pids-limit 256 --memory 2g --cpus 2 \
  -v "$PWD":/work -w /work \
  agent-runner:latest

What does gVisor add?

gVisor is an application kernel written in Go that runs in user space. Its main component, the Sentry, services the application's system calls and does not pass them through to the host kernel. File access goes through a separate Gofer process, and the Sentry itself runs under a restrictive seccomp filter without direct filesystem access. It ships as an OCI runtime, runsc, so it works with Docker and Kubernetes: register it, then run the same container with --runtime=runsc.

The gVisor documentation states the cost. Workloads heavy on system calls can run slowly, and not every system call, /proc or /sys file is implemented, so some tools fail. Test the agent's real toolchain under runsc before you rely on it. Modal's sandboxes offer gVisor as one of two runtimes, and GPU sandboxes there use gVisor only.

When do you need a microVM?

Use one when the code is untrusted, the host is shared, or the agent needs privileged tools. Firecracker, built by AWS for Lambda, uses KVM to start microVMs in under 125 ms with under 5 MiB of overhead each. It exposes only five emulated devices, and a companion jailer adds a second layer of Linux isolation in case the virtualization barrier fails. Kata Containers packages lightweight VMs that behave like containers, on QEMU, Cloud Hypervisor or Firecracker.

Most hosted sandboxes for agent code use one of these designs:

ServiceIsolationWhere it is stated
E2BFirecracker microVMsListed as a Firecracker adopter on the Firecracker project site; infrastructure code in e2b-dev/infra.
Vercel SandboxFirecracker microVM per sandbox, own filesystem and networkVercel Sandbox documentation.
Cloudflare Sandboxes (Containers)MicroVM with its own kernel and network per instance; internet access set by your Worker (enableInternet)Cloudflare Sandboxes documentation.
Modal Sandboxesruntime="gvisor" or runtime="vm" (own kernel); GPU sandboxes use gVisor onlyModal Sandboxes guide.
DaytonaDedicated kernel, filesystem and network stack per sandbox, per its documentationDaytona documentation.

A microVM boundary does not make the session safe by itself. A microVM with open internet and your API key inside is a well-isolated place to leak that key.

Why do egress and secrets matter more than the boundary?

Exfiltration needs no kernel exploit, only an outbound request. Misuse needs only a credential the agent can read. Three rules apply at every layer:

  1. Deny outbound by default, then allow by domain. sandbox-runtime and Claude Code start with an empty allowlist. Codex keeps network off in workspace-write and offers a domain proxy. Cloudflare's example starts containers with enableInternet: false. Keep the list to package registries and the APIs the task needs. Every allowed host is a possible exit, especially one that accepts uploads or user content.
  2. Keep long-lived secrets out of the sandbox. Pass short-lived, narrowly scoped tokens, or inject credentials at the proxy so the code never holds them. Claude Code's sandbox can mask credentials and substitute the real value only on requests to the hosts you name. Cloudflare's guidance is to keep credentials in the Worker and decide which services a sandbox reaches.
  3. Block the metadata endpoint and the internal network. A sandbox on a cloud VM that can reach 169.254.169.254 or private ranges can pick up the instance's role credentials or talk to internal services. Codex blocks local and private destinations by default (allow_local_binding = false).

How do you choose an agent sandbox?

SituationPick
Coding agent on a developer laptopThe built-in process sandbox in strict mode, plus a dev container for repositories you did not write.
Agent in CI running code from pull requestsA fresh hardened container or gVisor per job, no network or an allowlist, no long-lived secrets in the job.
Product that runs code written by an agent for many usersOne microVM, or one gVisor sandbox, per session or per tenant. Never a shared container.
Agent that needs Docker, FUSE or a VPN insideA microVM, where those privileged processes stay inside a guest kernel.

Whatever the layer, make each sandbox ephemeral, one per task or session. Do not let state carry over unless you chose to keep it: a snapshot or persistent volume carries a planted file into the next run as well.

How do you test that the sandbox holds?

Run these commands inside the sandbox, the way the agent would, and keep the output as evidence. Each line should fail, print nothing, or be refused by the proxy.

escape-test.shrun inside the sandbox
# Run inside the sandbox, as the agent would. Every line should fail or print nothing.
touch ~/escape-test                                   # write outside the workspace
cat ~/.ssh/id_ed25519 ~/.aws/credentials              # read credentials
env | grep -i -E 'key|token|secret'                   # secrets in the environment
curl -sS https://example.org                          # host outside the allowlist
curl -sS -m 3 http://169.254.169.254/                 # cloud metadata endpoint
ls -l /var/run/docker.sock                            # container runtime socket
echo 'echo pwned' >> .git/hooks/pre-commit            # code that runs later, outside

Then test from the other side. Check the proxy or firewall log for the refused requests, confirm a resource limit stops a runaway process, and make sure the sandbox is gone after the task ends. A test that only reads the agent's final answer will miss most of what matters here.

AI agent sandbox questions.

What is an AI agent sandbox?

An isolated environment that limits what code run by an agent can touch: which files it can read and write, which hosts it can reach, which secrets it can see and which kernel it talks to. It ranges from an OS process sandbox on a laptop to a microVM per session in the cloud.

Is Docker enough to sandbox an AI agent?

For trusted code, a hardened container is a reasonable boundary. For untrusted or agent-generated code, remember that a container shares the host kernel: Docker's default seccomp profile blocks about 44 of more than 300 system calls, and a kernel bug reachable from the rest is a path out. Use gVisor or a microVM when the code is untrusted and the host matters.

gVisor or Firecracker for agent code?

gVisor runs as an OCI runtime, so it drops into Docker and Kubernetes and shrinks the kernel surface without a VM, at a cost on syscall-heavy workloads and some compatibility gaps. Firecracker gives each sandbox its own guest kernel behind KVM, boots in under 125 ms with under 5 MiB of overhead per VM, and suits multi-tenant services.

Do Codex and Claude Code sandbox their commands?

Yes, at the process level. Codex uses Seatbelt on macOS, bubblewrap and seccomp on Linux and MXC or a sandbox user on Windows. Claude Code's optional sandbox is built on the open-source sandbox-runtime, using Seatbelt or bubblewrap. Both still share the host kernel and your user account.

Does a sandbox stop prompt injection?

No. It limits what an injected instruction can achieve once the agent runs a command. The agent can still be steered, and anything it can reach from inside the sandbox, including allowed hosts and secrets you put there, stays exposed.

Sources