In November 2026 AWS launched Nitro Sandboxes, lightweight VMs that run alongside workloads on almost any Nitro-based EC2 instance. EKS pods and ECS tasks can each run in their own sandbox. AWS designed them to run untrusted or LLM-generated code, including AI coding agents, on machines shared with other workloads.
We build Brig, an open-source sandbox that runs a coding agent inside its own microVM on a laptop or a Linux server. Nitro Sandboxes put a hypervisor boundary around those same workloads. Their architecture separates the VMM frontend from the hypervisor that enforces isolation. We examine that separation here, then use the escape record to explain why we chose a hypervisor boundary over containers or Seatbelt.
TL;DR
- A Nitro Sandbox is a sibling VM beside your EC2 instance. The Nitro hypervisor carves CPU and memory out of the running instance and boots a guest in that slice. Firecracker inside the instance manages the lifecycle and serves the virtio queues.
- The hypervisor enforces isolation. No vCPU threads in the parent, memory donated from a driver pool, PCIe only, no snapshots. In confidential mode the parent cannot read the sandbox's memory at all.
- Shared kernels keep producing escapes. runc in 2019, 2024 and three advisories in one day in November 2025, containerd in 2026, kernel bugs like Dirty Pipe in between. Seatbelt also uses a shared kernel on macOS. Apple marks
sandbox-execas deprecated. Its advisories describe five sandbox-escape CVEs since 2025. - Hypervisor escapes live in the device model. The eight we cite are in device emulation or in-kernel accelerators, three of them in minimal VMMs this year. None is in the hardware virtualization path.
- Boundary and policy are two layers. AWS's Strands Box combines OS isolation with semantic policy. Marc Brooker recommends a per-session microVM around it for multi-tenant use.
- Brig runs on hvi for these reasons. Its small device model runs in userspace, on Hypervisor.framework and KVM.
What is a Nitro Sandbox?
A Nitro Sandbox runs beside your EC2 instance, rather than nested inside it. The AWS documentation states:
A Nitro Sandbox runs as a first-level, hardware-virtualized guest alongside your instance.
The EKS guide makes the distinction explicit:
Each sandbox runs as a first-level guest with direct hardware-assisted virtualization, not through emulation or nested virtualization.
The Nitro hypervisor allocates CPU and memory from your running instance to a sibling guest. The EKS launch post calls that slice a "Nitro Partition". Your instance becomes the parent that operates the sandbox.
Figure 1 separates the frontend from the hypervisor.
Firecracker is the frontend. Firecracker 1.18 added a Nitro mode. Instead of opening /dev/kvm, it opens /dev/nitro_enclaves, the Linux driver that AWS Nitro Enclaves have used since 2020, extended with sandbox support. Firecracker checks the driver's capabilities, creates the sandbox, adds vCPUs, donates memory regions and writes the boot image into them, registers each virtio device with the driver, and starts the sandbox. From then on its job is to serve virtqueues. The Firecracker docs put it plainly:
Firecracker is not in the guest's CPU path and vCPUs are not threads of Firecracker.
There is no vCPU run loop in the parent. Nothing in the parent handles a VM exit. The cpu.max of the Firecracker cgroup does not throttle the guest, because the guest is not running on the parent's scheduler at all.
The Nitro hypervisor manages CPU, memory and boot. The sandbox vCPUs are "first-level, hardware-virtualized CPUs scheduled by the Nitro System". The driver zeroes and donates all sandbox memory at startup from a physically contiguous pool, in 2 MiB-aligned regions. The memory returns to the pool only when the sandbox exits. There is no overcommit and no demand paging. Nitro boots the guest through UEFI firmware from an EIF image (the Enclave Image Format, kernel plus initrd plus command line), supplies the ACPI tables and the PCIe topology, and relays virtio notifications between the guest and the backends in the parent.
Direct and confidential modes. In direct mode the parent keeps read and write access to the sandbox's memory. Virtqueues live in ordinary guest RAM, allowing an unpatched guest kernel to work. AWS describes its trust model as "equivalent to a standard nested virtual machine". In confidential mode, the default, "the Nitro System moves the Nitro Sandbox's memory out of the parent instance, so the parent can't read it". Each virtio device then gets a Device Memory Buffer, a region shared between guest and backend. The guest needs patched virtio drivers to use it. Confidential sandboxes also get an NSM device, so the guest can measure what booted and present a signed attestation to KMS. The signature comes from Nitro, "not the parent", so the parent cannot forge it.
Supported operations and limits. The transport is PCIe only; the legacy MMIO transport is gone. Snapshots, pause and resume, balloon, huge pages, CPU templates, dirty-page tracking and virtio device reset are all rejected. A sandbox stops when the guest shuts down or the Firecracker process dies. The total vCPUs across all sandboxes on an instance may not exceed 5x the instance's vCPU count. Memory is never overcommitted.
Nitro Sandboxes extend Nitro Enclaves. They share the hypervisor primitive, driver, EIF format and NSM device. The difference is the device model: an enclave gets a single vsock to its parent, a sandbox gets a PCIe topology with virtio-net, virtio-blk, virtio-vsock and hotplug. Firecracker's API endpoint is PUT /enclave; the docs use "enclave" to mean "sandbox". Firecracker manages these guests through the Nitro driver.
The public documentation leaves some details open. It gives no boot-time or overhead measurements. The ioctl set beyond NE_ADD_DEVICE is undocumented. The doorbell path is described only as "the Nitro System relays notifications". GPU passthrough is "currently unavailable".
Why use a hardware boundary?
AWS already ran containers on EKS and ECS. It already had Firecracker on KVM, the VMM it wrote for Lambda. Nitro Sandboxes now use the hypervisor that isolates EC2 tenants to isolate individual pods.
The key difference is which kernel runs the untrusted code. Figure 2 compares the three designs.
One kernel. In the first shape, the kernel that runs the agent's curl | sh is the kernel that holds your SSH keys, your browser cookies and the other tenants' processes. Every syscall the agent makes lands in that kernel. Isolation depends on the kernel's own controls: namespaces, cgroups, seccomp, an LSM or a Seatbelt profile. A reachable kernel bug or a gap in those controls can allow an escape.
A kernel of its own. In the second shape, the agent has its own kernel. KVM still runs in the host kernel. A userspace VMM implements the device model and parses guest-controlled data. An escape must exploit that device model or KVM itself.
The hypervisor below both. In the third shape, the hypervisor is below both kernels. The parent kernel never sees a sandbox vCPU and, in confidential mode, cannot read sandbox memory. A bug in the parent's kernel does not reach the sandbox, and a bug in the sandbox's kernel does not reach the parent. What is left to attack is the hypervisor and the virtio backends.
This is the same argument we made in the sandboxing manifesto: ask where enforcement executes. The escape record below illustrates why that matters.
The boundary and the policy are two layers
Strands Box combines OS isolation with policy. Marc Brooker, one of the Firecracker authors and now working on agent safety and policy at AWS, published Strands Box: The Big Picture in October 2026. Strands Box is AWS's open-source local sandbox for agents. Brooker describes it as "a kernel-enforced sandbox, using the same OS-provided mechanisms as many other sandbox offerings". It pairs OS isolation with the Dogwood policy language so that the policy layer is "the only way out of the box".
MicroVM isolation does not enforce tool policy. Brooker writes: "MicroVMs have a great security posture, a small, trusted compute base, and excellent performance." He adds: "This approach is great for performance and minimizing the TCB, but not great for policy." A VM boundary sees virtio rings and TLS ciphertext; it cannot express "allow this agent to git push, but only if tests are passing". Box provides what Brooker calls "semantic policy: the ability to set policy at a per-tool level, and have it deterministically enforced".
Policy code is attack surface. Box "has more code it needs to trust", and "more code means more opportunity for bugs, and in this space, bugs could mean bypassed policy". Brooker recommends adding a microVM: "But we recommend for multi-tenant deployments in the cloud that you pair it with a dedicated per-session MicroVM."
Brig separates isolation from policy. The hypervisor isolates each agent in its own guest kernel, even without tool-level policy. Egress rules and allowlists control which tools, paths and hosts the agent may access. These rules depend on the microVM boundary holding. With only a seccomp filter or Seatbelt profile around a host process, the host kernel must enforce both isolation and policy.
The shared-kernel record
Containers. Container escapes continue to exploit both the runtime and the shared kernel.
The runtime. CVE-2019-5736 let a container overwrite the host runc binary through /proc/self/exe and "consequently obtain host root access". CVE-2024-21626 leaked file descriptors into runc init, including a handle on the host's /sys/fs/cgroup. The advisory's third attack variant gives "full control of the host system". On 5 November 2025 three advisories landed at once, CVE-2025-31133, CVE-2025-52881 and CVE-2025-52565, all mount races that end in a write to /proc/sys/kernel/core_pattern and "complete root privileges over the host". In 2026, containerd's CVE-2026-53488 propagated image-config labels without validation, which "may result in executing an arbitrary command on the host" via a plugin that consumes them. The advisory credits "Anthropic Research, in collaboration with Claude".
The kernel. A kernel privilege escalation reachable from an unprivileged container process can allow a container escape. Dirty Pipe (CVE-2022-0847) let an unprivileged process overwrite read-only files in the page cache. The bug was present since 5.8 and fixed in 5.16.11. CVE-2022-0492 exposed the cgroups v1 release_agent, which runs as root on the host, without a capability check. The cgroups escape only worked where no seccomp, AppArmor or SELinux profile stood in the way, so those controls could block the escape. Dirty Pipe needed nothing special at all.
Container isolation depends on both the shared kernel and the controls that restrict access to it.
Seatbelt. On macOS the shared-kernel option is Seatbelt, the sandbox behind sandbox-exec and the App Sandbox. It is a TrustedBSD MAC policy: "The Sandbox is implemented as a policy module for the TrustedBSD mandatory access control (MAC) framework." That is the same shape as an LSM on Linux, a per-process policy evaluated in the one kernel everything shares.
Apple deprecates sandbox-exec in the macOS man page:
sandbox-exec – execute within a sandbox (DEPRECATED)
The sandbox-exec command is DEPRECATED. Developers who wish to sandbox
an app should instead adopt the App Sandbox feature described in the App
Sandbox Design Guide.
Apple's security releases also repeatedly report: "An app may be able to break out of its sandbox". In 2025 and 2026 alone that line appears for CVE-2025-31244 and CVE-2025-31258 (macOS 15.5), CVE-2025-43329 and CVE-2025-43332 (macOS 26) and CVE-2026-43772 (macOS 26.6). Mickey Jin's POC2024 talk describes a whole class of them: XPC services registered in the app's PID domain with "no additional entitlement checks or sandbox checks for the incoming XPC clients", leading to "10+ new vulnerabilities" from that surface.
Claude Code's sandboxing documentation says that on macOS "sandboxing uses the built-in Seatbelt framework" and on Linux "the sandbox relies on bubblewrap and socat". It also recommends running "the Claude Code process itself in a container, virtual machine, or the sandbox runtime" for additional isolation. Brig provides the VM option.
Where hypervisor escapes live
VM escape vulnerabilities show which parts of a VMM need the most scrutiny.
Device emulation in userspace. VENOM (CVE-2015-3456, 2015) was a buffer overflow in QEMU's virtual floppy controller, a legacy device through which a guest could execute code on the host. CVE-2020-14364 was an out-of-bounds write in QEMU's USB emulation. CVE-2021-3929 was a DMA reentrancy use-after-free in QEMU's NVMe emulation; Red Hat's enterprise QEMU was "not affected" because it does not ship NVMe emulation at all. The Firecracker paper describes the size of QEMU: QEMU is "> 1.4 million LOC as of QEMU 4.2". Firecracker's approach was to "keep KVM, but entirely replace QEMU".
In-kernel accelerators. CVE-2019-14835 was a buffer overflow in vhost_net, the in-kernel virtio-net backend, present since 2.6.34 and fixed in 5.3; a guest could "increase their privileges on the host" by exploiting code in the host kernel. ITScape (CVE-2026-46316), which we reproduced earlier this year, is a race in KVM's in-kernel GIC ITS emulation on arm64 that allows host-kernel code execution. Every VMM we tested exposed the ITS, except Firecracker up to v1.12.1, where the device simply did not exist in the codebase.
Minimal VMMs are not exempt. In April 2026 Firecracker published CVE-2026-5747, an out-of-bounds write in its virtio-pci transport: a root guest could change a queue size after activation and write up to 524,284 bytes past the queues. On a stock guest kernel the write lands in guest memory; reaching the Firecracker process needs more. In November 2026 it published CVE-2026-122192, where a failed memory discard after a snapshot restore with a balloon or virtio-mem device leaves a root guest able to read and modify Firecracker process memory. In May 2026 Cloud Hypervisor published CVE-2026-45782, a use-after-free in virtio-block async I/O completion that the advisory says "can be escalated to arbitrary code execution and a full guest-to-host (VM) escape", with the default configuration affected.
Figure 4 groups these vulnerabilities by layer. Three design choices follow.
Audit the device model and its in-kernel helpers. This is where the cited bugs occurred. We could not find a 2024 to 2026 guest-to-host escape in the hardware virtualization path itself. The boundary that Nitro Sandboxes, KVM and Hypervisor.framework all rely on, the CPU's second-level address translation and the exit mechanism, is holding. What breaks is the code that interprets what the guest wrote into a ring.
Omit devices the workload does not need. The floppy, the USB stack, NVMe, the ITS absent from Firecracker before v1.13, the balloon in the snapshot path, the PCI transport: each escape lived in a feature the sandboxed workload did not need.
Keep the host kernel out of the data path where possible. vhost_net and the vGIC ITS put guest-facing parsers in the kernel for performance. Both produced kernel-context escapes. Nitro removes the parent kernel from the sandbox's CPU path. In confidential mode, the unprivileged backend process accesses the shared device buffers.
What that means for a VMM
Firecracker's design document states the threat model in one sentence: "all vCPU threads are considered to be running malicious code as soon as they have been started". The device model includes only what the workload needs. The VMM process is confined with seccomp and a jailer, because it parses guest data. Nothing guest-facing goes into the kernel that does not have to.
Nitro can also move the vCPUs and memory out of the parent instance. The frontend stays where it was, but its blast radius shrinks to the queues it serves. In confidential mode, the guest's private memory is outside the parent's address space. This design is available only on EC2.
For everyone else, the design target is the same with one fewer layer: a small VMM with a device model you can read end to end, confined on the host, on top of the platform's own hypervisor, KVM on Linux and Hypervisor.framework on macOS. That is what hvi is.
Why Brig runs on hvi
Brig runs each agent session in its own microVM. The agent sees a private home directory and the project you pass it. Running brig rm discards the VM while preserving your project files. On macOS the VM runs on Apple's Hypervisor.framework; on Linux it runs on KVM. The VMM in both cases is hvi, which we wrote and described earlier. Every hvi statement below is at commit 02e187f.
hvi has a small device model. Under src/devices/virtio/ there is block, net over a tap, vsock and virtio-fs, over the virtio-mmio transport. Under src/devices/legacy/ there is a 16550 UART and a PL011, two RTCs, an i8042 and an ACPI power button. There is no PCI transport, no USB, no NVMe, no balloon, no snapshots, no hotplug. Omitting these features removes several components implicated in the escapes above. If a bug of the Cloud Hypervisor virtio-block kind exists in hvi, it is in a file you can read in an afternoon. Figure 5 puts the two lists side by side.
The host kernel is not in the data path. hvi is its own virtio backend on every host. It does not use vhost. On arm64 KVM the GIC configuration is hvi's; the interrupt controller surface the guest reaches is the one we chose to create. On macOS the hypervisor itself is Apple's framework, which exposes no device emulation at all, so every device the guest sees is ours.
The VMM confines itself. The src/sandbox/ module installs a seccomp-bpf allowlist per thread on Linux and enters a Seatbelt profile on macOS, before the process serves any guest I/O. The module's own comment gives the reason: "The virtio devices parse guest-controlled data in the same process as the vCPU threads, so hvi confines that process." Seatbelt adds confinement around the VMM process. The agent itself remains behind the hypervisor boundary.
One device model on two hosts. The guest sees the same devices on a MacBook and on a Linux server. This keeps sandbox behaviour consistent between local development and server execution. A port of Firecracker would have meant a long-lived fork; the earlier post has the details and the measurements.
hvi is young. Its lack of published advisories is no evidence of security. Its SECURITY.md explains how to report vulnerabilities privately.
The small device model also limits functionality: up to four disks and one NIC, all attached at boot, no PCI, no hotplug, and no snapshots yet. Pause, checkpoint and restore are on the hvi roadmap. For a workload that needs those today, Firecracker or Cloud Hypervisor are the better tools. A coding agent needs a shell, a filesystem, a network interface and a vsock. hvi has all four, and that is more than enough.
Would hvi run on Nitro?
hvi could support Nitro through a third backend. Its virtio backends would still serve virtqueues, with notifications arriving through the Nitro relay instead of a KVM ioeventfd or a Hypervisor.framework exit. The new backend replaces the vCPU threads with driver ioctls, adds a virtio-pci transport and an EIF loader, and takes guest RAM from the driver's pool instead of a memfd.
We are prioritizing laptop use, so a cloud-only backend is not next on the list. A Nitro port would test how cleanly hvi separates its frontend from the hypervisor: most changes should fit within the new backend.
Conclusion
Put the agent behind a hypervisor. AWS now offers this for EKS pods. Marc Brooker recommends a per-session microVM around Strands Box for multi-tenant use. Claude Code's documentation also lists a VM as an option for isolating the agent process. The shared-kernel record shows recurring escapes through both the runtime and the kernel.
Keep the boundary small and policy separate. The hypervisor escapes we could find live in device emulation and in in-kernel accelerators, none in the hardware path. That record supports a small device model in a confined VMM process, with the host kernel kept out of the data path. Policy controls what the agent may do. It runs in a separate layer that depends on the isolation boundary holding.
Brig applies this design on macOS and Linux. hvi provides the small VMM on Hypervisor.framework and KVM, with the device list in Figure 5. Nitro moves vCPU and memory management to the cloud hypervisor. hvi could support it through a third backend.
The boundary is the part a laptop and a cluster can share. What a team needs on top is one policy set for every place an agent runs, and a record of what each agent attempted. Our enterprise offering around Brig adds that: the same egress and tool policy on laptops, in CI and in clusters, host-side observation with an action history per sandbox, and records exported as OpenTelemetry and OCSF to your SIEM, with the cluster collector in private beta. The enterprise agent security page lists what is available.
Brig is open source under Apache 2.0. Boot an agent, run uname -r inside the sandbox, and try to reach the host from there. For one policy across a fleet and SIEM integration, talk to us about your deployment.



