Sandboxing AI Agents, Part 3: The Landscape, Compared by Threat Model
There is no single right sandbox for a coding agent. The options trade isolation strength against overhead, setup cost, and capability. The useful question is not "which is strongest" but "which boundary fits my adversary." So this is a fair survey, from nothing/YOLO to full VMs, not a ranking with one winner.
- There is no single right sandbox: isolation strength, overhead, setup cost, and capability move together, so pick by threat model.
- Egress control and provenance are axes orthogonal to isolation strength, and they are where most tools under-deliver.
- h5i is honestly a medium-to-high boundary (kernel confinement plus a hardened rootless container, L7 egress, no VM tier) whose differentiator is Git-native provenance.
Every coding agent you run executes shell commands on your behalf: it installs packages, runs build scripts, hits the network, and edits files. The moment one of those commands comes from an attacker-controlled source (a poisoned dependency, a prompt-injected README, a malicious test fixture) the only thing between that command and your credentials is whatever sandbox you put around it. That is why the sandbox question stopped being academic in 2025 and 2026: agents now run unattended, in parallel, against repositories full of untrusted text.
This survey is intentionally architectural and current as of June 12, 2026. Specific flags, SDK names, and product limits change; the stable question is where the enforcement boundary sits and what each boundary actually defends against. There is no single right answer. Stronger isolation costs more in boot latency, memory, setup, and compatibility, and the strongest boundary is the wrong choice for a trusted local refactor just as the weakest is irresponsible for hostile code. Pick by threat model.
What you already know, and what to weigh
If you have shipped containers, you already know the rough isolation ladder: a bare process is weaker than a container, a container is weaker than a VM. What is easy to underweight when sandboxing an agent specifically is four things. First, where the boundary breaks matters more than where it sits: a misconfigured strong boundary is worse than a well-configured weaker one. Second, egress control is a separate axis from process isolation, and most "sandboxes" are weak on it. Third, overhead is a security property: a sandbox so slow that engineers turn it off protects nothing. Fourth, provenance, meaning what evidence survives for a human to review, is absent from almost every execution substrate, yet it is the whole point of letting an agent work unattended.
So the comparison below scores each approach on five axes that actually drive the decision: isolation strength, runtime overhead, setup cost, egress control, and the failure mode where it breaks.
The sandbox landscape at a glance
The rows are approaches, not products; most real tools are an approach plus a workflow. Ratings are deliberately coarse and assume a reasonable configuration of each; a misconfiguration moves any row down a tier.
| Approach | Isolation strength | Overhead | Setup | Egress control | Where it breaks |
|---|---|---|---|---|---|
| Nothing (YOLO) | none | none | none | none | the first malicious command or prompt injection |
| Git worktree only | none (workspace, not execution) | near-zero | trivial | none | any host-permissioned process |
| Language/runtime sandbox (WASM/WASI, V8 isolates) | medium for in-runtime code | low | medium (embed it) | via host bindings only | native escapes, host FFI, anything that shells out |
| Kernel confinement (seccomp + Landlock + namespaces) | medium-high (shared host kernel) | low | medium (Linux-only, kernel ABI) | namespace + proxy; no built-in L3/L4 | host-kernel vulns, policy gaps |
| Container: runc default (Docker) | medium (shared kernel) | low | low | net namespace + iptables/proxy | kernel escapes; docker.sock, privileged, caps, bind mounts |
| Hardened container (rootless Podman, cap-drop, ro rootfs, userns) | medium-high (shared kernel) | low | medium | as configured (proxy/firewall) | kernel escapes; NAT bypass of an L7 proxy |
| Userspace kernel (gVisor) | high (syscall interposition) | medium (syscall cost, compat) | medium | netstack-filtered | Sentry bugs, unsupported syscalls, perf-sensitive I/O |
| Lightweight VM (Kata) | high (HW virt per container) | medium | high (VM-capable infra) | VM network policy | hypervisor vulns, nested-virt/infra limits |
| microVM (Firecracker; E2B managed) | high (guest kernel + KVM) | medium (sub-second boot) | high (substrate) / low (managed) | VM network policy | hypervisor/KVM vulns, side channels; you still build the workflow |
| Full VM (QEMU/KVM, cloud VM) | very high | high (boot, RAM) | high | full network-stack control | hypervisor vulns; too heavy for fast iteration |
Two things stand out. The isolation column climbs smoothly, but the overhead and setup columns climb with it. There is no free strength. And the egress column is uncorrelated with isolation strength: a hardened container can have weaker real egress control than a humble process sandbox that drops the network namespace entirely. The next sections walk the approaches in roughly increasing order of escape resistance, with each one's honest gap.
Nothing (the YOLO baseline)
The most common "sandbox" is none. The agent runs as you, with your shell, your keys, and your network. Good: zero overhead, zero setup, full capability; every tool just works. For a trusted model editing a throwaway repo on a machine with nothing to steal, this is a defensible choice, and pretending otherwise is its own kind of dishonesty. Gap: there is no boundary at all. One prompt-injected instruction in a fetched web page or a dependency's post-install script reaches your SSH keys, your cloud credentials, and every writable path. YOLO is the correct baseline to measure everything else against, not a strategy for untrusted input.
Git worktree: workspace isolation, not execution isolation
A git worktree is rarely marketed as a sandbox, but it is the base layer of many coding-agent systems. It gives each agent its own directory, branch, index, and working state while sharing one object store, so parallel agents do not stomp each other's checkout. Good: cheap, native, ideal for running several attempts at once. Gap: the security claim is essentially zero. A process launched in a worktree still holds your host permissions: it can read your home directory, open sockets, inspect other processes, and modify any writable path. A worktree isolates changes, not execution; it needs a real boundary layered on top.
Language and runtime sandboxes
A different family confines code inside a runtime rather than around a process: WebAssembly with WASI (Wasmtime, Wasmer), V8 isolates (the model behind Cloudflare Workers), or restricted interpreters such as Pyodide. The capability model is explicit: a WASI module reaches only the files, environment, and host functions you pass it. Good: fast startup, embeddable, and a clean deny-by-default capability surface; excellent for executing untrusted snippets. Gap: it only confines code that runs in the runtime. A coding agent's whole job is to shell out to native tools (npm, cargo, pytest) that live outside the WASM boundary, and every host import you add to make real work possible widens the surface. Useful as a component, rarely sufficient as the agent's sandbox.
Kernel confinement: seccomp, Landlock, and namespaces
This is the lightest boundary that still defends a real host. seccomp-bpf filters which syscalls a process may issue; Landlock restricts which filesystem paths it may touch; and namespaces isolate its view of PIDs, mounts, users, and the network. Anthropic's sandbox-runtime sits here: a native-OS wrapper to run agent bash commands, MCP servers, and other processes with defined directory and network access, no container required.
Good: low overhead, fast startup, and a sharp rise in escape cost using only kernel primitives. Gap: the workload still runs on the host kernel, so a kernel vulnerability or a hole in the policy defeats it; it is Linux-specific and sensitive to kernel and ABI versions; and on its own it is a confinement primitive, not a branch lifecycle or review system. If your problem is "confine this command," it is close to ideal. If it is "run five agents, compare their diffs, keep evidence, merge one," you need workflow on top.
Containers: runc, and hardening it
Containers are where most agent platforms actually live. Dagger's container-use and the Zed integration in Zed's background-agents post pair a container with a git worktree per agent: isolated execution plus an inspectable branch, a natural shape for coding agents. Good: the workflow ergonomics are hard to beat, with parallel agents in familiar dev environments without re-cloning. Gap: a default runc container shares the host kernel, so the boundary is medium and configuration-dependent. A mounted docker.sock, privileged mode, retained capabilities, broad bind mounts, or a shared PID namespace can collapse the claim entirely.
Hardening narrows that gap without changing the kernel-sharing reality: run rootless Podman, --cap-drop=ALL, --security-opt=no-new-privileges, a read-only rootfs with a private /tmp, and user namespaces. That is a meaningfully stronger posture than a careless docker run, but it is still a shared-kernel boundary. For hostile code, you want a second boundary under the container, which is exactly what the next two approaches add.
Userspace kernels and lightweight VMs: gVisor and Kata
gVisor is not an agent product; it is a container runtime that puts a Linux-compatible kernel (the Sentry) in userspace and intercepts the workload's syscalls, so a guest rarely talks to the host kernel directly. Good: a much smaller host-kernel attack surface than runc, with container-like ergonomics. Gap: syscall interposition costs performance and not every syscall or /proc detail is faithfully implemented, so I/O-heavy or exotic workloads can be slower or incompatible, and the Sentry itself is software that can have bugs.
Kata Containers takes the other path: each container or pod runs in a lightweight VM, adding hardware virtualization as a real second boundary while keeping the container interface. Good: close to VM-strength isolation behind familiar tooling. Gap: it needs VM-capable infrastructure (KVM, sometimes nested virtualization) and carries more overhead than a plain container. The practical lesson: when a tool says "container," ask which runtime. runc, gVisor, and Kata are three different security claims wearing the same word.
microVMs and full VMs: Firecracker, E2B, and the top of the ladder
Firecracker is a minimal KVM-based microVM monitor built for serverless workloads, advertising sub-second boots and a deliberately small device model. Its value is category-level: the workload runs behind a separate guest kernel and the KVM boundary, not merely inside host namespaces. That is the usual answer when code may be hostile, not just risky. E2B packages this as a managed, Firecracker-backed cloud sandbox with SDKs, so you get the isolation ceiling without operating the substrate. A full VM (QEMU/KVM or a cloud instance) sits one notch further: maximum isolation and complete network-stack control, at the cost of boot time, memory, and slow iteration.
Good: the strongest escape resistance available short of physical separation, and full control over the network boundary. Gap: a microVM or VM is a substrate, not an agent workflow. You still need root filesystems, networking, file transfer, snapshots, policy, logging, identity, a merge path, and cleanup. Managed services like E2B trade that work for a remote dependency with account, SDK, and data-placement considerations. And no boundary is absolute: hypervisor vulnerabilities and side channels exist. The top of the ladder buys strength, not a workflow and not omniscience.
Platforms vs. primitives
Some projects are neither a single boundary nor a single product but a control plane over several. OpenSandbox presents itself as a general sandbox platform for AI applications, with SDKs and Docker/Kubernetes backends for code execution, GUI agents, evaluation, and training. Good: it standardizes create/execute/file/network/lifecycle across backends, which is real leverage at scale. Gap: footprint, meaning Docker or Kubernetes infrastructure and a control plane to operate, plus a center of gravity that is a service for applications, with git-native review and reasoning provenance outside the core model.
nothing (YOLO) -> git worktree only (workspace isolation, no execution boundary) -> language/runtime sandbox (confines in-runtime code only) -> kernel confinement (seccomp + Landlock + namespaces) -> container (runc) -> hardened (rootless, cap-drop, ro rootfs) -> userspace kernel (gVisor) -> lightweight VM (Kata) -> microVM (Firecracker / E2B) -> full VM (QEMU/KVM, cloud instance)
Read this as escape resistance, not developer experience, and remember that a misconfiguration drops any rung. The two axes the ladder hides, egress and provenance, deserve their own sections.
Network control is a separate axis
Almost every approach can claim some filesystem isolation; network policy is what separates a mature sandbox from a directory wrapper, and it does not track isolation strength. Ask whether egress is unrestricted, denied outright, proxy-filtered, DNS-filtered, packet-filtered, or VM-network-filtered. Then ask the harder follow-ups: what happens with raw IP literals, DNS rebinding, IPv6, Unix sockets, package-manager mirrors, and tools that ignore the HTTP(S)_PROXY environment variables.
The honest framing is by OSI layer. An L7 proxy allowlist gates the dominant HTTP/HTTPS path and is useful for cooperative tooling, but it does not stop a process that ignores the proxy variables and opens a raw socket to an IP the NAT permits. L3/L4 packet filtering or a VM network boundary is what makes egress airtight against non-cooperative code. A tool should say which one it provides; "egress allowlist" without the layer is marketing.
Provenance: the column nobody fills in
The agent-sandbox field is strong on execution substrates and weak on durable review evidence. When an agent worked unattended, a reviewer needs more than "it was isolated": which branch changed, what prompt or context caused the work, which command output mattered, what policy was enforced, which operations were denied, and why the resulting diff is safe to merge. None of that falls out of a microVM or a container by itself.
This is not a luxury. Without a replayable audit trail, a sandbox is a safe place to do work but not a good place to review it, and unreviewable work from an autonomous agent is its own risk. The strongest systems will pair a clear boundary with provenance, which is precisely the gap the next approach targets.
Where h5i sits: tiered, not strongest
h5i's env feature does not try to win the isolation ladder. It spans two rungs of it and adds the column everyone else leaves blank. Its process and supervised tiers are kernel confinement: a Landlock filesystem allowlist, a seccomp-bpf syscall deny-list, namespaces, and rlimits, with the process tier forking a supervisor under a fresh PID namespace. Its container tier is a hardened rootless Podman backend: --cap-drop=ALL, --security-opt=no-new-privileges, a read-only rootfs, a private /tmp tmpfs, and --userns=keep-id. There is a lighter workspace tier (worktree only) and, honestly, no microVM or full-VM tier today. For hostile code that needs a guest-kernel boundary, reach for Kata, Firecracker, or E2B.
The container tier does add the one network feature the static kernel tiers cannot: a non-empty net.egress allowlist enforced by a host-side, DNS-pinned HTTP/HTTPS CONNECT proxy that the container reaches over the rootless NAT, fail-closed with a 403 for anything off the list. That is L7 enforcement, and h5i's own source says so plainly: it blocks proxy-respecting tooling but does not by itself stop a process that ignores the proxy variables and opens a raw socket; airtight L3/L4 filtering is explicitly out of scope for the shipped tiers. Under-claiming here is the point.
What h5i does differently is bind the sandbox to a review record. Every env is a code branch, a reasoning/context branch, and a policy manifest at once; runs are captured, denials are recorded, the policy is digested, and a reviewer inspects or applies the diff through a mediated propose -> apply lifecycle (part 4 covers the mechanics). So the right way to read h5i in this landscape is: a medium-to-high boundary on the kernel-confinement and hardened-container rungs, paired with the git-native provenance that the stronger substrates omit. If your threat model needs a guest kernel, h5i is not the tool; if it needs reviewable, auditable agent work on a shared-kernel boundary you can run locally, that is the niche it targets.
Choosing by threat model
Map the adversary to the boundary, then add workflow where the substrate stops:
- Trusted model, throwaway repo, nothing to steal: YOLO is defensible; just be honest that it is YOLO.
- Parallel trusted edits: git worktrees for workspace isolation; no execution boundary needed.
- Untrusted snippets inside your own program: a language/runtime sandbox (WASI, V8 isolates).
- Local commands that need quick confinement: kernel confinement (seccomp + Landlock + namespaces).
- Multi-agent coding in familiar environments: hardened container-plus-worktree systems.
- Hostile or multi-tenant code: gVisor, Kata, or microVM/full-VM isolation.
- Hosted execution inside an application: a managed API such as E2B, or a platform such as OpenSandbox.
- Local agent work where audit and merge evidence matter: a git-native model such as h5i env on its kernel or container tier.
Conclusion
The honest summary of the landscape is that strength, overhead, and capability move together, and no row dominates the others. A microVM buys escape resistance you will pay for in boot time and operational weight; a process sandbox buys speed you pay for in a shared kernel; a language runtime buys a clean capability model you pay for the moment the agent shells out. The two most under-served axes, egress control measured by OSI layer and provenance that survives for a reviewer, cut across all of them and are where most tools under-deliver.
So do not shop for "the strongest sandbox." Write down what your agent might execute and what it could reach if it turned hostile, pick the lightest boundary that contains that, and make sure the result is reviewable. h5i takes a deliberate position in this space, with kernel and hardened-container tiers, an honest L7 egress allowlist, no VM tier, and git-native provenance welded on, because for local, reviewable agent work the missing piece was rarely a stronger boundary; it was an auditable one.
FAQ
What is the strongest sandbox for AI coding agents? By escape resistance, full VMs and microVMs (Firecracker, Kata's VM-backed containers) sit at the top: the workload runs behind a separate guest kernel and a hardware-virtualization boundary, not just host namespaces. But strongest is not always right: it adds boot latency, memory cost, and operational weight. Match the boundary to the adversary, not to a leaderboard.
Is a container a secure sandbox for running AI agents? A default runc container shares the host kernel, so the claim is medium and configuration-dependent. Rootless mode, dropping all capabilities, no-new-privileges, a read-only rootfs, and user namespaces all help. It collapses under a mounted Docker socket, privileged mode, retained capabilities, broad bind mounts, or a host-kernel vulnerability. For hostile code, put gVisor or a VM-backed runtime under it.
What does seccomp plus Landlock actually protect against? seccomp-bpf filters which syscalls a process may issue, Landlock restricts which filesystem paths it may touch, and namespaces isolate its view of PIDs, mounts, users, and the network. Together they raise escape cost sharply at low overhead, but the workload still runs on the host kernel, so a kernel vulnerability or a gap in the policy can defeat them.
Where does h5i sit in the sandbox landscape? h5i env spans kernel confinement (its process and supervised tiers use Landlock, seccomp-bpf, namespaces, and rlimits) and a hardened rootless-Podman container tier with an L7 egress allowlist. It ships no microVM or full-VM tier, so it is not the strongest raw boundary. Its distinguishing trait is that the sandbox is tied to a git branch, a reasoning trace, a policy digest, and command captures, so the work is auditable and reviewable, not just executable.
Is an HTTP proxy egress allowlist enough to control an agent's network? A proxy-based allowlist is L7 enforcement: it gates the dominant HTTP/HTTPS path and is useful for cooperative tooling, but it does not stop a process that ignores the proxy environment variables and opens a raw socket to an IP the NAT permits. Airtight egress needs L3/L4 packet filtering or a VM network boundary. Be honest about which one a tool provides.
The right sandbox depends on the claim
Try h5i on your next AI-assisted branch: create a sandboxed workspace, capture the run, and post a review-ready PR brief.
Star on GitHub Read part 2