Which Sandbox Can Actually Hold an AI Agent? (Docker, gVisor, Firecracker)

summarized

TLDR

The real difference between Docker, gVisor, and Firecracker as AI agent sandboxes is who answers a system call: the host kernel, a Go-based user-space kernel, or a separate guest kernel. Docker is fast but its runC layer has three high-severity escape bugs, while gVisor shrinks host exposure to roughly 68 system calls and Firecracker puts a VM boot between the code and the host. The practical verdict: patched Docker for your own reviewed code, gVisor for compute-heavy loads, and a microVM for untrusted code or agent container builds.

Key points

The CVE-2024-21626 advisory says all four Leaky Vessels attacks can give full host control.

A 2019 measurement found gVisor's sentry implements 237 of Linux's roughly 350 system calls.

Firecracker's design targets include 125ms guest init, 5MB monitor memory, and about 0.06ms network latency.

Docker's Sandboxes product runs each agent session in a dedicated microVM with its own kernel.

The CNCF accepted gVisor as a sandbox-stage project after Google's donation.

Tools mentioned

Techniques

  • System-call interception with a user-space application kernel
  • Linux namespaces and cgroups for container isolation
  • Gofer helper processes for host file system access
  • Hardware-virtualized microVMs using KVM
  • Seccomp filters and privilege-dropping jailers
  • Docker-in-Docker agent workflows
Transcript (captions)

0:00 Your AI agent writes code and runs it on your machine. A Docker container is supposed to keep that code away from your files. In January 2024, a bug in runC, the tool that starts Docker

0:11 containers, let code in a container work from the host's own folders. The advisory says all four attacks it covers can give full control of the host. That code can be buggy, hostile, or steered

0:22 by a prompt injection. People use the words container, sandbox, and micro VM as if they mean the same thing. They give very different isolation and they cost different amounts of speed. By

0:33 the end, you can pick one box for your agent and say what you give up. What decides it is a system call. A program can't open a file, use the network, or get more memory by itself.

0:43 It asks the kernel, the core of the operating system, with a system call. So, the question is who answers that call? The three boxes give three different answers. In one, the host

0:53 kernel answers. In another, a program written to act like a kernel answers. In the third, a separate kernel answers. In this video, sandbox is the general word for any of the three. In box one, a

1:05 Docker container, the host kernel answers. Docker's docs say namespaces give each container its own view of processes and network. Cgroups limit its resources. Because these are kernel

1:15 features, every container uses the same host kernel. So, namespaces limit what a process can see and cgroups limit what it can use. Neither one answers the call. The call goes straight into the

1:26 host kernel. If the code finds a bug in that kernel or in the tool that starts the container, it can reach the host. That tool is runC. It starts containers for Docker, Containerd, and Kubernetes.

1:37 A bug in runC can let code escape the container. Three of its advisories matter here. In February 2019, runCE announced CVE-2019-5736. Adam Ivnuyk and Boris Popov found it. A

1:52 malicious container could overwrite the host's runC binary. The cause was a mishandled file descriptor, the handle a process holds for an open file. That gave the attacker root on the host. NVD

2:03 rates it 8.6, high, and Docker fixed it. This bug had limits. The attacker needed root inside the container. That could come from a malicious image or from Docker exec into a container that

2:14 attacker could write to. A correct user namespace setup, where host root is not mapped, blocked it. The default AppArmor policy in Fedora's SE Linux policy did not block it. The bug that opened this

2:25 video is CVE-2024-21626, called Leaky Vessels, published on January 31st, 2024. An internal file descriptor leak caused it. A process started by runc exec or by a malicious

2:40 image could have its working directory in the host file system. The working directory is the folder a process works from. The advisory rates it 8.6, high, the same score as the 2019 bug. It

2:51 covers four attacks. It says all four can give full control of the host. In November 2025, runc disclosed another escape bug. So, this isn't only history. CVE-2025-31133

3:04 is a timing bug in how runc hides sensitive host paths from a container. It scores 7.3, high. Patch releases fix it, and the versions are on screen. Bugs could exist in a hypervisor and in

3:16 gVisor, too. So, no box is unescapable. The real comparison is how much software stands between the code and the host. gVisor says Linux sandboxing tools alone leave the code only one system call away

3:28 from host compromise. Think of the agent's code as a visitor to a house. In Docker, the visitor stays in the same house with a door in between.

3:36 In gVisor, a receptionist answers every request, and the visitor never comes in. In a micro VM, the visitor works in a separate building. Now, follow one call, the code asks to write a file. In

3:48 Docker, that call goes to the host kernel. In gVisor, it goes to the sentry. In a micro VM, it goes to a guest kernel. The call is the same, but three different things answer it. Box

3:59 two is Gvisor. Its core is the sentry, an application kernel written in Go. It runs in user space, outside the host kernel. The sentry catches the code system calls and memory access requests.

4:11 It answers them with its own code for system calls, memory, file systems, networking, and processes. In the house, the sentry is the receptionist. Gvisor says it never passes any system call

4:22 from the code through to the host. The sentry does need the host for its own work, so it makes a limited set of host calls. Anything the sentry can't do itself, such as file access, goes to a

4:32 gofer helper process. These numbers come from a 2019 Gvisor post, measured against Linux 5.3.11. So, the current list may differ. In that count, Linux has about 350 system calls.

4:45 The sentry implements 237 of them for containers. It may use only 68 different host system calls. That's 53 without networking and 15 more with it. The sentry can't open or create host files.

4:58 All file input and output goes through gofers. So, a file request travels from the code to the sentry, then to a gofer, and the gofer touches the host file. Now, the

5:08 picture breaks. The receptionist is software, and software can have bugs. A bug in the sentry could let the visitor reach further than the design intends. Gvisor shrinks the host exposure, but it

5:18 doesn't remove it. In Docker, the code's calls go to the host kernel. In the 2019 count, Linux had about 350 system calls. In Gvisor, the calls go to the sentry, and the host sees at most 68 kinds of

5:31 call from the sentry. These numbers measure different things, but they show the size of each opening. Gvisor has a setting called the platform that chooses how it catches calls. Since mid-2023,

5:42 the default is seccomp, a Linux feature that sets rules for a program's system calls. One rule, called a program's system calls. One rule, called return trap, makes the host kernel send a

5:52 sigsus signal to the calling thread. That signal hands control to gVisor. gVisor has older ways to catch calls. One is ptrace, which gVisor's docs call obsolete. In gVisor's 2023 post, systrap

6:05 ran about 10 times faster than ptrace on a loop of getpid calls. That compares gVisor with itself, not with Docker. Systrap was about two times faster than ptrace on a compile and two to three

6:17 times faster on Redis. The FFmpeg run barely changed. gVisor's performance guide splits the cost into two parts. The structural cost is the extra sentry layer and the gofer path for files. The

6:28 implementation cost comes from gVisor's own file system and network stack, which are less mature than Linux's. Apps bound by system calls pay the most, such as data stores and static network

6:39 services. Memory overhead is a small, mostly fixed amount. Compute-bound code and raw memory access have no extra cost once the memory mappings are in place. So, the price depends on your agent's

6:50 work. Box 3 is a microVM and Firecracker is the example. AWS built it for Lambda and Fargate. Firecracker is a virtual machine monitor, a program that runs guest machines. It uses KVM, the Linux

7:03 feature that lets the CPU run a guest with its own kernel, to create microVMs. The code system call now lands in a guest kernel, a separate kernel inside the VM. The host sees KVM and a small

7:15 device model, not the call. The device model is small. Firecracker exposes only virtio network and block devices, a vsock device, a serial console, and a partial keyboard controller. Virtio is a

7:27 standard for virtual devices. A vsock device is a channel between the guest and the host. The keyboard controller only signals a reboot. So, the host side has few devices to emulate. Each

7:38 Firecracker process has three kinds of thread. The API thread takes commands. The VMM thread emulates the devices in one event loop. Each guest core gets one VCPU thread, and that thread asks KVM to

7:51 run the guest again and again. A jailer sets up C group and namespace isolation for the process, then drops its privileges. Firecracker also loads seccomp filters for each thread before

8:02 any guest code runs. So, Firecracker itself runs under Linux limits, too. Firecracker publishes design targets. The targets come from AWS bare metal hosts with a guest that has one VCPU and

8:14 128 MiB of memory. On those hosts, the guest init process, the first program the guest Linux runs, starts 125 ms or less after the API call that starts the instance. The VMM thread adds 5 MiB or

8:28 less of memory overhead. The 125 ms ends when init starts, not when your agent's code runs. The spec doesn't state a number for a full agent image. Firecracker also states about 0.06 ms of

8:41 network latency from virtualization. It also states guest CPU speed above 95% of bare metal, but the spec marks that test as pending. Each box costs something different. In Docker, system

8:53 calls go straight to the host kernel, so there's no extra layer on calls. gVisor adds the sentry and the gofer, so work with many system calls pays more. A microVM adds a VM boot and memory for

9:05 each VM. Now, the twist about Docker itself. Docker Desktop on a Mac runs containers in a Linux virtual machine. Docker's docs list three options. The first is Docker VMM, a

9:16 container-optimized virtual machine manager. The others are the Apple virtualization framework and legacy hyperkit. Docker marks hyperkit as deprecated and Intel-only. On October

9:26 3rd, Dave Scott argued that Docker Desktop has used microVMs since 2016. He defines a microVM as a workload on a stripped-down Linux kernel. It runs on a minimal VMM such as Firecracker on top

9:38 of a hypervisor, the software that runs virtual machines like KVM or Xen. Docker's own docs say Linux VM, not micro VM, so the label is his. His lineage starts with HyperKit and

9:49 LinuxKit. HyperKit is a VMM and LinuxKit supplied the minimal kernel and user space. The line then evolves into Docker VMM. On a Mac, the containers run inside that Linux VM, so a runC escape lands in

10:02 the VM first, not in macOS. That's my reading of the docs. The docs don't say what shared folders change. They also don't say how Docker VMM compares with Firecracker. Docker's own agent product

10:14 uses a micro VM. Docker sandboxes, described in a blog dated April 16th, 2026, runs each agent session in a dedicated micro VM. The micro VM has its own kernel and a

10:26 private Docker daemon, the background program that runs containers. Docker says there's no path back to the host. It uses hypervisor.framework on macOS, the Windows Hyper-V Platform on Windows,

10:37 and KVM on Linux. Docker gives a reason beyond escape risk. An agent that builds containers needs Docker in Docker, which means running Docker inside a container. That needs privileges that weaken

10:48 container isolation. The post gives no startup or memory numbers. On October 2nd, Google announced that it's donating gVisor to the CNCF, the Cloud Native Computing Foundation. The

10:59 CNCF accepted it on September 28th. gVisor starts at the CNCF's first maturity level, which is named sandbox, with a plan for incubation. Governance moves to maintainers with

11:11 organization-based voting, so Google can't decide alone. The announcement has no technical detail and no performance numbers, so it changes who governs gVisor. It doesn't

11:21 say if gVisor's security or speed will change. For an agent builder, the mechanism you just saw is what matters. For code you wrote and reviewed, I'd use a normal Docker container. The call goes

11:32 straight to the host kernel, so calls have no extra layer. If you use docker, update run C because each bug above has a fixed version. If an agent reads web pages or files you don't control, a

11:43 prompt injection can steer its code. So treat that code as hostile and don't use a shared kernel. Pick G Visor if the work is mostly compute and you can't pay for a VM boot. Otherwise, pick a micro

11:54 VM. If your agent runs a database or a network server, test G Visor on that work first. System calls drive the cost there. A micro VM is my choice when the

12:04 agent builds containers or when the code comes from people you don't know. Firecracker's target is 5 MB or less of monitor memory plus the memory you give the guest. You also pay a VM boot. In

12:15 return, the code gets its own kernel behind hardware virtualization. If you run untrusted code, I'd rank a micro VM first because it gives the code its own kernel. Docker chose the same

12:25 for its agent product. No source here compares escape bugs across the three. Use G Visor for mostly compute work and a patched docker container for code you wrote and reviewed.

12:36 The docs we used don't compare docker, G Visor, and firecracker on one machine. So what does your own agent's workload cost in each box?

Frontier News · by Hyperjump Technology