Isolation architectures · 2026

The kernel is the real wall.Everything else is a policy.

yolobox, Docker sbx, microsandbox, hypeman, Cloudflare Sandbox, GhostVM, UTM, agent-sandbox-vm, Cua Sandbox, Lume, Claude Code, Codex, nono, Incus, code-on-incus, OpenShell, and discobox sit on five isolation primitives. Process, app container, system container, microVM, full VM — one question: whose kernel is it, and whose OS? That question decides whether a compromise reaches your host. It does not decide what a desktop agent can see, spend, or click.

Shared kernel
Process · app · system
Dedicated kernel
MicroVM · Full VM
Wrappers
nono · yolobox · sbx · coi · discobox
Machines & planes
Incus · msb · hypeman · CF · GhostVM · OpenShell

01 · Spectrum

Five families. Seventeen products. One question: whose kernel is it?

Process sandboxes, app containers, and system containers all ask the host kernel to please isolate a workload. A microVM boots a second kernel so that question never reaches the host. System containers are the missing row: a full Linux machine, still that kernel. Full VMs are the row Linux sandboxes skip: the guest is macOS or Windows, because the agent's job is Xcode or MSVC. Two of the seventeen, OpenShell and discobox, are control planes that can sit on more than one row, so read the row of the driver or pool you will run. Two primitives sit off this axis — gVisor's user-space kernel and V8/Wasm runtimes with no kernel at all — and the hosted sandboxes you can rent (E2B, Vercel Sandbox, Modal, Cloudflare Sandbox) are one of these four or those two, run on someone else's fleet. Read left to right and the product changes: the first two families subtract from your machine — a policy or a namespace around a process — and the other three hand the agent a machine of its own.

  1. 01

    Process sandbox

    OS MAC / LSM policy on one process tree

    Kernel
    Shared host kernel
    Start
    Near zero
    Escape
    A kernel bug or a missed syscall is a host bug
  2. 02

    Container

    Namespaces, cgroups, seccomp

    Kernel
    Shared host kernel
    Start
    Hundreds of ms to a few seconds
    Escape
    A kernel exploit escapes every container on the host
  3. 03

    System container

    Unprivileged LXC: full distro, user namespace, AppArmor, idmap

    Kernel
    Shared host kernel
    Start
    Milliseconds from a CoW snapshot; seconds from an image
    Escape
    A kernel exploit escapes every container on the host — same as Docker
  4. 04

    MicroVM

    Hardware virtualization (KVM / HVF / WHP)

    Kernel
    Dedicated guest kernel
    Start
    Sub-100ms (libkrun) to a few seconds (full agent VM)
    Escape
    A guest kernel bug dies in the guest. The remaining bets are VMM bugs.
  5. 05

    Full VM

    Hardware virtualization around a whole macOS or Windows guest

    Kernel
    Dedicated guest kernel — and a different OS
    Start
    Tens of seconds to boot; seconds from a saved state or CoW clone
    Escape
    A guest kernel bug dies in the guest. Remaining bets: the VMM, and each host-guest channel you enabled

02 · Stack

The same attack, five different walls.

Click a layer. Then trace a kernel CVE upward from the agent. On a process sandbox, an app container, or a system container the pulse reaches the host kernel. On a microVM or a full VM it stops at the guest — and on a full VM the guest is not even Linux.

Click a layer · Dedicated guest kernel

Layer

Guest kernel — dedicated

Each sandbox boots its own Linux kernel. A kernel CVE inside the agent is now the guest's problem. This is the Kernel Line.

A kernel CVE inside the agent dies in the guest unless the VMM is also wrong. That is the MicroVM impact: you moved the trusted computing base from 'every syscall on this laptop' to 'this VMM plus the hypervisor'. Systems marked with a setting are here only when configured that way: OpenShell's VM driver boots one guest per sandbox, and discobox gets a wall per box only when each box has its own libkrun pool, because boxes in one pool share its guest kernel.

03 · Layers

The kernel line is one layer of six.

It decides whether a compromise reaches your host. It does not decide what kind of machine the agent gets, what survives, what it may reach, what comes back, or who can watch. Heavier agents make those the hard part.

Click a layer · the kernel line is layer 1

Layer 02

Machine fidelity

Is it enough like a real machine for the job?

  • OS and architecture. Every Linux sandbox hands the agent a Linux userland. An iOS build, a signed macOS app or an MSVC binary needs a full-OS guest: GhostVM, UTM, Lume and agent-sandbox-vm boot macOS on Virtualization.framework or Windows on Hyper-V and Parallels. Apple caps macOS guests at two per host, and none can host a VM of its own.
  • Accelerators. Firecracker's device model is virtio network, block and vsock, with no GPU passthrough. hypeman inherits that: Firecracker and qemu-microvm cannot pass PCI, its macOS backend refuses VFIO, and vGPU wants QEMU. Cloud Hypervisor and QEMU pass a whole GPU with VFIO, sbx's path is experimental VFIO, and containers take GPUs through device nodes or CDI. Incus has a gpu device for containers and VMs, macOS guests get paravirtualized Metal, and gVisor's nvproxy forwards a filtered set of NVIDIA ioctls to the host driver.
  • A display and a browser. Anthropic's computer-use demo is Xvfb, a window manager, x11vnc, noVNC and Firefox in a container. discobox ships an Xfce desktop over noVNC in each box, E2B Desktop ships Xfce in its sandbox, and Cua Sandbox puts a screenshot, click and type API over a container, a QEMU VM or a Lume macOS guest.
  • Nested Docker, systemd, real core counts: what makes the agent's machine feel like a laptop.
microVM helps

The lightest VMMs stay small by giving devices up. Choosing one is choosing which machines you cannot have.

Who leads here

  • Cua SandboxA computer-use API over any of its guests
  • discoboxA desktop and Chromium over noVNC, plus nested Docker
  • GhostVMA real macOS desktop, within the two-guest cap
  • hypemanVFIO or vGPU, on QEMU or Cloud Hypervisor only
  • OpenShellGPUs through CDI, Kubernetes, or one VFIO device
  • IncusA full distro and gpu devices; you image the desktop in

What is still open

Most Linux rows on this page are headless, with no accelerator, unless you build that in. The full-VM rows give you a real desktop at workstation size.

04 · Workloads

Heavier work changes which layer breaks first.

A coding CLI in a repo is the easy case for a wall. A browser, a desktop, a macOS app or a GPU job moves the difficulty to fidelity, state and observation, where a microVM is silent or in the way. Pick a workload.

Is a microVM enough?

Computer-use agent

Necessary at best, far from sufficient

Anthropic's own reference is a container, and its README lists four controls: a dedicated machine, no sensitive data, a domain allowlist, and a human confirming consequential actions. Only the first is a boundary.

What breaks first

  • Pixels as instructions: text in a page or an image steers the agent
  • A signed-in browser profile is a credential no header-swapping proxy covers
  • The screen and the model's context are an egress channel
  • The irreversible click
  • The agent loop running inside the machine it controls

A workable stack

A disposable dedicated machine (a VM if the target is hostile, a container if it is not), an X display with a viewer, a fresh profile with no sensitive logins, an egress allowlist, a human gate on consequential actions, and the loop kept outside the box.

Real setups for this

Anthropic computer-use demo

Docker container

Ubuntu with Xvfb, mutter, x11vnc, noVNC and Firefox. The agent loop runs inside the container it controls.

The reference is a container, and its README says the components are weakly separated. It recommends a dedicated VM or container, no sensitive data, a domain allowlist, and human confirmation.

Source

E2B Desktop

Firecracker microVM (hosted)

An Xfce desktop template with an SDK for screenshots, input and streaming apps.

A microVM per desktop with the display, the input API and the stream as the product. Layers 2 and 6 are what you are buying.

Source

discobox desktop

A systemd box in a pool

Xfce on an Xorg dummy display, x11vnc, and a noVNC viewer. A region drawn on screen becomes something the agent can read.

Viewer, takeover and an audit proxy are built in. The kernel wall is whatever the pool host is.

Source

05 · Seventeen systems

Wrappers, harnesses, a machine runtime and its wraps, microVM runtimes, five full VMs, two control planes.

nono, yolobox, sbx and discobox wrap existing CLIs. Claude Code and Codex sandbox themselves. Incus is the machine you install an agent into — Pere Villega's Sandbox for Claude is the worked example, code-on-incus the packaged one, with nftables egress and a monitor that pauses or kills the box. microsandbox and hypeman are VM runtimes you operate; Cloudflare Sandbox is one you rent. GhostVM, UTM, Lume and agent-sandbox-vm boot a macOS or Windows guest, for the jobs no Linux box can do. Cua Sandbox is the computer-use version: one machine the agent both codes in and clicks through, from a Docker container up to a Lume macOS guest. OpenShell is a policy gateway over Docker, Kubernetes or a microVM, and discobox is a box manager over a pool host that is a VM or a Docker daemon depending on your OS.

yolobox

Container YOLO box

container

Launch Claude, Codex, Gemini, or Copilot in a container that never mounts your home.

Finbarr · wrapper · shared kernel

Isolation
2
Untrusted
2
Harness
5

Incus

Linux system containers

system

Give the agent a machine — apt, systemd, sudo, nested Docker — without paying for a second kernel.

Linux Containers · runtime · shared kernel

Isolation
3
Untrusted
2
Harness
3

code-on-incus

Incus wrap with active defense

system

Give every agent its own machine, then watch it: nftables on egress, a threat monitor on the box, auto-pause on HIGH, auto-kill on CRITICAL.

Maciej Mensfeld · wrapper · shared kernel

Isolation
3
Untrusted
3
Harness
5

Docker sbx

Laptop microVM + private daemon

microvm

Treat the coding agent like a human developer: full docker build, no path back to the host.

Docker · wrapper · dedicated kernel

Isolation
4
Untrusted
4
Harness
5

microsandbox

Embeddable libkrun runtime

microvm

Virtual machines that feel like containers, with an SDK your agent can call.

Super Rad Company (formerly Zerocore AI) · runtime · dedicated kernel

Isolation
5
Untrusted
5
Harness
3

hypeman

Multi-hypervisor OCI runtime

microvm

docker run, but the unit is a VM — snapshots, ingress, vGPU, and a remote API.

Kernel (kernel.sh) · runtime · dedicated kernel

Isolation
5
Untrusted
5
Harness
2

Cloudflare Sandbox

Rented Firecracker VM per sandbox ID

microvm

getSandbox('user-123').exec('npm test') — a Firecracker guest on Cloudflare's network, with the secrets held by your Worker.

Cloudflare · runtime · dedicated kernel

Isolation
5
Untrusted
5
Harness
3

GhostVM

A macOS workspace per agent

vm

Your agents need more than a container. Give them a Mac — one .GhostVM bundle per agent, project, or client.

groundwater · runtime · dedicated kernel

Isolation
5
Untrusted
4
Harness
3

agent-sandbox-vm

Scripted Hyper-V · VZ · Parallels clean room

vm

Build real Windows binaries with MSVC, or real Mac binaries with Xcode, inside a VM the agent cannot leave — then copy the artifacts out.

glslang · wrapper · dedicated kernel

Isolation
5
Untrusted
4
Harness
4

UTM

QEMU + Apple Virtualization, any guest OS

vm

Securely run operating systems on your Mac — Linux, Windows, macOS, or a PowerPC from 1999.

utmapp (osy) · runtime · dedicated kernel

Isolation
5
Untrusted
4
Harness
2

Cua Sandbox

One computer the agent codes in and clicks through

vm

A desktop per agent — Linux, macOS, Windows or Android — where a shell command and a mouse click land on the same files.

Cua (trycua) · runtime · kernel per image

Isolation
4
Untrusted
4
Harness
2

Lume

Headless macOS VMs from an IPSW, shipped as OCI images

vm

lume create macos-tahoe --ipsw latest --unattended tahoe, then lume ssh — a vanilla Mac you can script, clone and push to a registry.

Cua (trycua) · runtime · dedicated kernel

Isolation
5
Untrusted
4
Harness
2

Claude Code

Seatbelt / bubblewrap + hooks

process

Don't approve every ls. Let the kernel police bash, and let hooks police the rest of the harness.

Anthropic · harness · shared kernel

Isolation
2
Untrusted
2
Harness
5

Codex

Kernel sandbox, two surfaces

process

Local: the kernel says no. Cloud: the machine isn't yours. Network starts off on both.

OpenAI · harness · shared kernel

Isolation
3
Untrusted
3
Harness
5

nono

Capability shell · Landlock / Seatbelt

process

Zero-setup wrap of any agent: session sandbox plus a brokered sandbox per tool, with secrets that never enter the child.

nolabs (Luke Hinds) · wrapper · shared kernel

Isolation
3
Untrusted
2
Harness
5

OpenShell

Policy gateway over Docker · K8s · microVM

container

Declare what each agent may touch in a policy. A supervisor outside the workload enforces it, injects credentials only at approved endpoints, and a prover checks policy changes before they apply.

NVIDIA · runtime · kernel per driver

Isolation
3
Untrusted
3
Harness
4

discobox

Parallel agent boxes, git as the sync layer

system

Give each agent session its own box with its own clone of the repo, and get the work back as ordinary git commits.

discobox-ai · wrapper · kernel per pool

Isolation
3
Untrusted
2
Harness
4

06 · System containers

When the agent needs a Linux machine, not a process.

App containers (Docker, yolobox) isolate a process. System containers (Incus LXC) isolate a distro that still shares your kernel. Click a job. The Pere Villega setup is the canonical 'I wanted a laptop' case; code-on-incus is the same case as a product.

system container

Pere Villega · Sandbox for Claude

The agent must feel like a laptop: apt install, systemd, sudo, a nested Docker daemon, several long-lived boxes. `sandbox my-api --claude` drops Claude Code into its own Incus system container. `sandbox backend frontend --claude` is a tmux of two machines, each with its own dockerd. Golden images are btrfs CoW clones — milliseconds, not a rebuild.

vs app container (Docker / yolobox)
Docker's unit is a process. You fake a machine with compose, privileged, and a custom image. Incus's unit is already a distro with PID 1 = init.
vs microVM
sbx / libkrun also give you a machine, plus a dedicated kernel. Use them when the threat includes a kernel CVE. Villega is optimizing for density and clone time on a Linux host he already operates, not for hardware isolation.
vs process sandbox (nono / Claude / Codex)
nono, Claude's bash sandbox, and Codex never become a machine. They cannot apt, cannot nest Docker, cannot snapshot a full OS.

07 · Matrix

Architecture, performance, environment, security, harness — side by side.

Toggle columns. On a phone, pick two. The Environment group covers what the kernel line does not: GPU, state and restore, guest OS. Scores elsewhere in this page are relative, not a benchmark.

  • Primitive

    Purpose-built VMM microVM

    Seatbelt + bubblewrap

  • Kernel

    Dedicated guest

    Shared host

  • Role

    Agent wrapper

    Harness (built-in)

  • Control plane

    sbx + in-guest dockerd

    None

  • Harness placement

    Whole CLI inside the VM; stdio MCP servers on the host via gateway

    Harness outside; Bash children inside. MCP + hooks on the host

08 · Threats

Isolation is a claim until you name the failure.

A sandbox that survives rm -rf ~ can still lose a kernel CVE, a docker socket, the repo you mounted, the host's localhost, the next session via a planted git hook, or an authorised push with a real token. Pick a failure and read the blast radius.

Why it matters

This is the actual MicroVM thesis. Shared-kernel designs lose together.

  • yoloboxexposed

    Shared host kernel. A kernel bug is a host bug. yolobox says so.

  • Incusexposed

    System containers share the host kernel. Unprivileged uid maps soften an escape-to-root; they do not stop a kernel LPE. Incus --vm would contain this; that is not this row.

  • code-on-incusexposed

    Incus LXC on the host kernel. The hardened profile's syscall deny list narrows the surface and an Incus VM mode is an open follow-up; a monitor does not stop an LPE.

  • Docker sbxcontained

    Guest kernel. Escape now requires a VMM/hypervisor bug, not a generic kernel LPE.

  • microsandboxcontained

    Dedicated guest kernel via libkrun. Same hardware story.

  • hypemancontained

    Guest kernel on Firecracker, Cloud Hypervisor, QEMU, or Apple virt.

  • Cloudflare Sandboxcontained

    Each container instance runs in its own VM — Firecracker per Cloudflare's launch. A kernel LPE lands in the guest; the remaining bets are the VMM and Cloudflare's host.

  • GhostVMcontained

    Guest XNU on Virtualization.framework. A macOS kernel bug in the guest is the guest's; escape needs a VZ or HVF bug.

  • agent-sandbox-vmcontained

    Hyper-V, VZ or Parallels guest kernel — same thesis, with Windows or macOS as the guest.

  • UTMcontained

    QEMU on HVF or VZ; a guest kernel bug stops at the hypervisor. QEMU's device emulation is the larger VMM surface of the two backends.

  • Cua Sandboxpartial

    Image.linux(kind='container') shares the host kernel — on a Mac, Docker Desktop's Linux VM. Every other Image boots its own: QEMU, Lume, Hyper-V. Pick the VM kind if this threat is in scope.

  • Lumecontained

    A Virtualization.framework guest with its own XNU or Linux kernel. Escape needs a VZ or HVF bug.

  • Claude Codeexposed

    Seatbelt/bubblewrap are policies on the host kernel.

  • Codexpartial

    Local CLI: host kernel, exposed. Cloud task: contained in OpenAI's isolated environment.

  • nonoexposed

    Landlock and Seatbelt are still this kernel. no daemon, no VM — and no second kernel.

  • OpenShellpartial

    Docker, Podman and K8s drivers: exposed — Landlock and seccomp are this kernel. VM driver or a Kata runtimeClass: contained. The driver decides, not the product.

  • discoboxpartial

    The pool host decides. macOS and Windows pools contain it to the pool VM, which holds every box in that pool. On Linux the default pool is the host Docker daemon: exposed. Boxes in one pool lose together.

Beyond the kernel line

Failures a microVM does not see.

These do not cross any boundary, so no row above can be graded on them. They matter most for agents that drive a screen. What helps is in the other layers.

Pixels are instructions

kernel line helps: none

A web page, an email or an image on screen says: ignore the task, open the account page, paste the token.

Anthropic's computer-use README warns that Claude will sometimes follow commands found in content even when they conflict with the user's, including instructions in webpages or images. The attacker writes on the same screen the agent reads.

  • MediationAllowlist egress to the domains the task needs
  • Observation & controlA human confirms consequential actions
  • State & lifecycleA fresh, minimal environment per task

The signed-in session is the credential

kernel line helps: none

The browser profile is logged in to mail, a bank, a cloud console.

A proxy that swaps an API key or header keeps a token out of the box. Cookies and SSO sessions live in the browser, and the agent acts as the user on any page that profile can open.

  • State & lifecycleA fresh profile per task; never restore a signed-in snapshot across tenants
  • MediationTask-scoped accounts and destination allowlists
  • Work & dataKeep account logins off the machine, as Anthropic's README advises

The screen leaves the box

kernel line helps: little

Screenshots stream to the model API. A viewer, the clipboard or a recording carries the screen to people and logs.

For a computer-use agent, what is on the display is the data. Every screenshot is model input, and every recording keeps it.

  • Work & dataKeep sensitive data off the machine entirely
  • Observation & controlDecide who may attach to the viewer and how long recordings live
  • MediationEgress only to the model endpoint and the task's domains

An irreversible click

kernel line helps: none

Accept the terms. Submit the payment. Send the email.

A wall bounds what a compromised process can reach. It does not know that this click cannot be undone, or that the agent was asked to make it.

  • Observation & controlA human confirms financial, consent and outbound-message actions
  • MediationMethod and path rules that deny the write
  • State & lifecycleSnapshots undo local state, not the world

The loop lives in the box it controls

kernel line helps: little

The agent process holds the model key and decides its own actions inside the machine it steers.

Anthropic's demo README says its components are weakly separated: the agent loop runs in the container Claude controls. A page that takes over the session takes the loop's credentials with it.

  • MediationInject the model credential at a proxy so the box holds a placeholder
  • Compute boundaryKeep the loop outside and give the box only actions

The runaway session

kernel line helps: none

The agent retries the same captcha for six hours.

Cost and time are resources no boundary meters. A desktop session is expensive to leave running.

  • State & lifecycleIdle timeouts and hard lifetimes
  • Observation & controlStep and spend budgets enforced outside the box

09 · Harness

Who actually runs Claude, Codex, a browser agent, and a desktop.

Compatibility is not transitive. A great untrusted-code runtime is a poor YOLO wrapper, and a great YOLO wrapper is a poor multi-tenant control plane.

AgentyoloboxIncuscode-on-incusDocker sbxmicrosandboxhypemanCloudflare SandboxGhostVMagent-sandbox-vmUTMCua SandboxLumeClaude CodeCodexnonoOpenShelldiscobox
Claude CodeWrap + skip-permissionsInstall inside the machineDefault tool; ~/.claude seeded, login screen if no keyFirst-class sbx runRun inside a guest if you image itRun inside a guest if you image itTutorial: clone the repo, run Claude Code in the guestInstall in the guest; vmctl remote exec drives itProvisioned by the scripts; OAuth lives in the snapshotInstall in the guestInstall in the guest; the Cua agent loop drives a computer-use model insteadInstall over lume ssh; no wrapperNative—Wrap + signed profileInstall in the image + a provider profileHarness image
Codex CLIWrap + bypass approvalsInstall inside the machineOne config line; TOML config, so no settings-file injectionFirst-class sbx runRun inside a guest if you image itRun inside a guest if you image itBring your own image; OpenAI Agents SDK tutorialInstall in the guestProvisioned by the scriptsInstall in the guestInstall in the guestInstall over lume ssh—NativeWrap + signed profileInstall in the image + a provider profileHarness image
Gemini CLI / CopilotWrap + --yoloInstall inside the machineNot a supported tool (Aider and Cursor are next)First-classBring your own imageBring your own imageBring your own imageInstall in the guestNot provisioned; install yourselfInstall in the guestInstall in the guestInstall over lume ssh——Wrap + signed profileCopilot CLI documented; others by imagePackage it in an image
OpenCodeNative wrapInstall inside the machineSupported; sessions live in .opencode/ in the workspaceFirst-classBring your own imageBring your own image-opencode base image variantInstall in the guestNot provisionedInstall in the guestInstall in the guestInstall over lume ssh——Wrap + signed profileThe quickstart agentHarness image
Custom agent / SDKNot the pointOCI or a full distropi and omp supported; anything else you install in the boxPossible, not the DXFirst-class SDKs + MCPFirst-class OCI + APIFirst-class: getSandbox() from a Worker, HTTP bridgevmctl + Unix socket APIScripts, not an APIutmctl / AppleScript / ShortcutsFirst-class: Python + TypeScript SDKs, MCP; shell, PTY, venv and GUI actionsCLI + REST API (lume serve); SSH execNoNoAny CLI via a profileAny process; SDKs drive the gatewayPackage an image; drive via OpenAPI / CLI
Browser agentNoIf you image a browser into the machineIf you image a browser into the boxNoPlaywright-in-VM possibleKernel's production pathChromium in your image; Browser Rendering is the separate productSafari on a real macOS desktopEdge in a Windows guestAny guest browser, no hooksThe product: screenshots, a11y tree, clicks in any guest OSVNC and a real macOS desktop; bring the driverComputer-use is the hostNot this productNoNot a documented pathDesktop + Chromium in the box (VNC)
Computer use (full desktop)Not the point. Headless unless you add a displayImage a desktop into the machineNot a documented featureNot documentedBring a desktop imageKernel's browser path: snapshots + ingressNot documentedThe guest's own macOS desktop; GhostTools adds clipboard and file transferA full Windows or macOS desktop guest, restored from a snapshot each sessionA full desktop guest window; utmctl sends keystrokes, Shortcuts and AppleScript automateThe point: a screenshot / click / type API over Docker, QEMU, Lume or Hyper-V guestsA macOS desktop over VNC; driven through lume serve or the Cua SDKComputer use drives the host desktop, unsandboxedNot this productNoNot a documented pathXfce desktop + Chromium over noVNC, in the box

Wrappers

nono, yolobox, discobox, and Docker sbx launch someone else's CLI. nono is a process policy — as are sandbox-runtime, fence and landrun, the smaller wrappers this site folds into that row. yolobox is an app container — as is Anthropic's reference dev container with its iptables egress allowlist, and Litterbox on Podman. sbx is a microVM with a private engine. In all of them the harness and its own API token live inside the box.

Harness sandboxes

Claude Code and Codex sandbox themselves — the harness stays outside, only the commands go in. Claude's box covers Bash; MCP servers and hooks run on the host unless you use sandbox-runtime. Codex leans on default-on kernel policy, default-off network with an allowlist proxy once opened (a limited mode MITMs HTTPS to clamp methods to GET/HEAD/OPTIONS), read-only .git / .agents / .codex, and an approval layer (untrusted, on-request, never, or a reviewer agent). Wrap either with nono/yolobox/sbx for a thicker outer box.

System containers

Incus is not a wrap. You install the agent inside a full Linux machine. Pere Villega's Sandbox for Claude is that pattern: one Incus box per project, nested Docker, CoW clones. discobox is a second wrap of the same shape, with a pool, a per-box proxy and a git hand-back instead of a bind mount. code-on-incus is the wrap: coi shell puts Claude Code, Codex, opencode, pi or omp in the box, seeds that tool's credentials into it, and watches it with nftables and a threat monitor.

Runtimes

microsandbox and hypeman run OCI as a VM on hardware you own. OpenShell is a control plane over runtimes like these: you image the agent, and it supplies policy, credentials and audit. Cloudflare Sandbox runs it as a Firecracker VM on Cloudflare's, with your Worker as the control plane and the egress proxy. You image Claude Code or OpenCode into any of them; their native client is your code, not Anthropic's CLI.

Full VMs

GhostVM, UTM, Lume and agent-sandbox-vm boot a whole macOS or Windows guest and you install the agent inside like on any Mac or PC. Nothing here wraps a CLI; the host-side handles are vmctl remote exec, utmctl, lume ssh, PowerShell Direct or prlctl exec. Cua Sandbox is the exception in kind: its native client is a computer-use agent that clicks and types, with a shell and a Python venv on the same machine. The harness and its login live in the guest, which is why the products push one workspace per client.

10 · Mac

Darwin is not a Linux kernel. Nested virt is the bill for pretending twice.

Incus containers need Linux, so a Mac first boots a Linux VM — no nested virt. Incus --vm needs KVM inside that VM, so nested virt, M3+, macOS 15+. Two Apple Containers are two machines on Darwin, not two machines inside a machine — HVF does not live in the Linux guest. A macOS guest (GhostVM, UTM, Lume) is the one box that is not Linux at all: two per host, none nested.

Where do the two machines sit?

cannot

No. Apple Container does not live inside a machine

container talks to Virtualization.framework on Darwin. The guest is thin Linux + vminitd — no Darwin, no HVF, no Apple Container CLI. You cannot run Apple Container inside Colima, Incus, or another Apple Container. Nested virt on M3+ would only expose KVM in that Linux guest, which is Incus --vm's world, not Apple's.

Click a layer

nested virt n/aVM per container

HVF — sibling VMs, not nested

container run is a new lightweight VM on Darwin. A second container is a second sibling on the same hypervisor. They are two machines on the Mac, not two machines inside a machine.

Not used, and nested would not help. Each container is already a Virtualization.framework VM on Darwin. The guest is a thin Linux (vminitd). There is no HVF inside that guest, so you cannot run Apple Container inside Apple Container, Colima, or Incus. Two boxes are sibling VMs on the Mac, not machines inside a machine.

Two boxes
Sibling VMs: yes. Two `container run` are two HVF guests on Darwin — that is the design, no nested virt required. Nested: no. Apple Container is a Darwin client; you cannot stash it inside another VM. yolobox still cannot compose those siblings: no dockerd, no shared docker0, no derived-image build, virtiofs-on-the-same-path is sharp, macOS 15 networking was broken (26 is better). A fixed --name still collides.
yolobox
yolobox --runtime container is auto-detected on Tahoe+. One prebuilt box works. A second yolobox with a different name is a second VM on the Mac — it can run, it is not 'inside' the first. What fails is treating them as compose: derived images, --platform, exclude/copy_as, and docker-from-inside-the-agent.

11 · The kernel line

Inside the kernel line: what a microVM buys, and what it costs.

Hardware virtualization changes which bugs can reach you. It does not change which files you chose to share, what the agent may reach, or what the machine can be. Use it when the unit of trust is a machine, not a process.

01

What a MicroVM actually buys

A dedicated guest kernel and a hardware privilege boundary. Guest syscalls never become host syscalls. Firecracker, Cloud Hypervisor, QEMU microvm, libkrun, and Docker's sbx VMM are different monitors on the same idea. The agent can be root. That is fine. Root is not the boundary anymore.

02

What it does not buy

It does not save the files you deliberately shared. Docker sbx and yolobox both mount the project at the real path; a confused rm is still a confused rm. It does not save you from a VMM bug. It does not make a 4 GB laptop VM free. And a snapshot restore that is fast is still a machine you have to patch.

03

What it costs: fidelity

The wall's price is the machine you can no longer have. Firecracker's device model is virtio network, block and vsock, with no GPU passthrough, and it stays small on purpose. hypeman inherits that: Firecracker and qemu-microvm cannot pass PCI, its macOS backend refuses VFIO, and vGPU wants QEMU. Cloud Hypervisor and QEMU pass a whole GPU through with VFIO, at a density cost of one GPU per VM, and Docker's sbx offers only an experimental, feature-flagged VFIO path on x86_64 Linux with NVIDIA. Containers reach GPUs through CDI or device nodes, with the shared kernel and driver stack that implies. Choosing a VMM is choosing which devices you can have, before the OS question in the card after next.

04

Why nested Docker forced Docker's hand

Coding agents develop the way humans do: they build images and run compose. Doing that in a container means mounting the host socket or running privileged Docker-in-Docker — both punch the isolation story. Putting a private engine inside a microVM is the first design that lets the agent have Docker without having your Docker. Once the agent runs its own containers, the egress policy has to follow it in: discobox puts the pool proxy's CA into every nested container with a runc wrapper, because each build step and each docker run has its own trust store and would otherwise either fail TLS or route around the proxy.

05

The shared-kernel tools are not obsolete

Seatbelt, Landlock, bubblewrap, a well-cut container, and unprivileged LXC are the right default when the operator is you, the threat is accident, and latency must be low. nono, Claude Code, and Codex ship that as a process. yolobox hides $HOME. Incus gives the agent a machine. Use them. Just do not confuse their policy with a hardware wall.

06

Your host is probably already a VM

The Mac section's lesson generalises. On macOS every Linux container sits in a Colima or Docker Desktop guest; on Windows, WSL2 is a Hyper-V utility VM; in CI and on most cloud instances you are inside someone's KVM or Nitro guest. A shared-kernel sandbox there shares that guest kernel, which is a smaller blast radius than the site's Linux-laptop rows suggest — but a microVM sandbox there needs nested virt (/dev/kvm in the guest, .metal or nested-enabled instances, an M3+ Mac), which is the bill the Mac section itemises. Firecracker inside a Firecracker guest without /dev/kvm is not a thing.

07

Off the axis: user-space kernels and no kernel at all

Two primitives do not fit the four rows. gVisor runs a Go kernel in user space that answers the workload's syscalls, so a Linux kernel LPE has no Linux kernel to land on — Modal, Cloud Run and Google's Agent Sandbox default to it, and it can sit on KVM or on a seccomp'd host process. Its nvproxy (runsc --nvproxy) is the one GPU story on this list that is neither passthrough nor paravirtual: the sandbox forwards a filtered set of NVIDIA ioctls to the host driver, T4 through H100 supported. V8 isolates and Wasm runtimes have no syscall surface to begin with; Cloudflare Workers and Deno Deploy live there. Both trade compatibility for a narrower attack surface. If you rent a sandbox — Cloudflare Sandbox, E2B, Vercel Sandbox, Fly (all Firecracker), Modal (gVisor) — the buyer question is which of these you got, and who holds the secrets. Cloudflare is the clean case: the Worker calling getSandbox is an isolate, the sandbox it gets is a microVM, and the egress handler between them is where the secret lives.

08

The guest OS is a use case, not a detail

Every Linux sandbox on this page — microVM, container, process — hands the agent a Linux userland. That is the wrong machine when the job is an iOS build, a signed macOS app, a Simulator run, or an MSVC binary with a kernel debugger attached. GhostVM, UTM's Apple backend, Cua's Lume and glslang's vmctl boot macOS on Virtualization.framework; Hyper-V and Parallels boot Windows. Cua Sandbox puts a computer-use API on top of any of them — the agent clicks and types in the same machine it runs code in, which is the other thing a Linux container's headless userland never gave you. Same hardware wall as a microVM, a different OS behind it, and a different bill: gigabytes and tens of seconds per guest, Apple's licence capping macOS guests at two per host, no nesting inside a macOS guest, and every convenience — clipboard, VirtioFS, port forwarding, file transfer — a hole you chose. This is a workstation answer, not a fleet primitive, and no Linux runtime substitutes for it.

09

Two products share the word sandbox

Subtraction: nono, Claude Code's Seatbelt profile, Codex's bwrap+seccomp, sandbox-runtime, fence, landrun — and the app containers, yolobox and Litterbox, which are a namespace fence around a process on your kernel with your files bind-mounted in. A fence around your machine, everything else on it left as you had it. Addition: sbx, microsandbox, hypeman, Cloudflare, GhostVM, Lume, Incus, code-on-incus — a machine you hand over, nothing of yours inside it unless you mounted it. The first cannot survive a kernel bug and does not need a kernel. The second cannot see your Metal GPU, your keychain, or your dockerd, and the whole product is deciding which of those to pass back through. Most of the rough edges on this site — live mounts, docker.sock, the Mac GPU, two-guest caps — are one side borrowing the other's promise. OpenShell can be either, by driver: a Landlock-and-seccomp fence inside a container is subtraction, its VM driver is addition. discobox is addition, with the machine's kernel set by the pool host.

010

The kernel line is becoming a setting, not a product

OpenShell and discobox break the one-product-one-family reading of this page. Both put one policy and credential layer over swappable isolation. OpenShell runs the same supervisor and policy engine over a Docker container, a Podman container, a Kubernetes pod (Kata if you set the runtimeClass), or a libkrun microVM, and its own RFC says the runtime builds the boundary but never decides what is allowed. discobox makes isolation a pool attribute and picks a different pool host per OS. The five families still describe a deployment. They no longer describe a product: ask which driver or which pool you will actually run before reading its row.

011

How many sandboxes share each kernel

Once a VM is in the picture the question is per what. One VM per machine: Docker Desktop, Colima, OrbStack. One VM per pool: discobox on a Mac or Windows PC, many boxes inside sharing that kernel on purpose. One VM per sandbox: sbx, microsandbox, hypeman, Apple Container, OpenShell's VM driver. discobox's own design record states the principle that this page has been circling: what shares a kernel and a cache with my sandbox must be a declared, user-visible fact, and mutually untrusted work belongs in a different pool. A VM you share with your other agents is a wall against the host, not against them.

012

Pick the unit of isolation to match the unit of trust

A bash child is the unit for pair-programming (Claude, Codex, nono). An app container is the unit for a YOLO CLI that is still a process (yolobox). A system container is the unit for a laptop-shaped agent that must apt and nest Docker (Incus, Pere Villega, code-on-incus, discobox). A microVM is the unit for untrusted code, a nested build with a kernel wall, or a tenant. A snapshot-restorable VM is the unit for a browser session. A full-OS guest is the unit for a desktop or a macOS or Windows app. A GPU job's unit is set by the VMM, not by the threat. Match the unit to what is being trusted, then check the other five layers.

12 · Pick

Tell it the job. It will not recommend a hypervisor for ls.

What are you doing
What are you defending against
Nested docker build
Where it runs