Skip to main content

Command Palette

Search for a command to run...

Choosing an Isolation Model for Untrusted Code: Userspace Kernel versus MicroVM

When exposing code execution to autonomous agents, choose between gVisor's userspace kernel sandbox and Firecracker's microVM. Compare attack surface

Updated
8 min readView as Markdown
Choosing an Isolation Model for Untrusted Code: Userspace Kernel versus MicroVM
D
PhD in Computational Linguistics. I build the operating systems for responsible AI. Founder of First AI Movers, helping companies move from "experimentation" to "governance and scale." Writing about the intersection of code, policy (EU AI Act), and automation.

TL;DR: When exposing code execution to autonomous agents, choose between gVisor's userspace kernel sandbox and Firecracker's microVM. Compare attack surface

When teams expose a code-execution service to autonomous agents running model-directed, untrusted code, the isolation model becomes the load-bearing decision. Two dominant approaches have emerged: intercepting system calls in a userspace kernel, as gVisor does, or running workloads inside a lightweight microVM with a minimal device model, like Firecracker. This choice shapes both the host's attack surface and the compatibility cost your team must absorb. Before you commit, you need a clear-eyed comparison of how each model contains threats and what trade-offs follow for your operational environment, especially if you are an engineering leader at a small or mid-sized European company where resource efficiency and security assurance are equally critical.

The Threat Model: What Isolation Must Withstand

Untrusted code, whether it arrives as a third-party container or as an autonomous agent’s generated script, can attempt to exploit kernel bugs to escalate privileges or access sensitive data. The gVisor security model categorizes attack vectors into several classes: the System API (standard interfaces like file and socket operations), side channels, and implicit actions triggered by hardware or privileged code, such as traps or interrupts. A typical exploit might involve crafting a specific sequence of system calls and racing multiple threads to hit a vulnerable kernel code path. If successful, the attacker gains control over kernel memory and can compromise the entire host.

Both gVisor and Firecracker aim to minimize this exposure, but they do so with fundamentally different architectures. gVisor runs in userspace and implements its own kernel that intercepts system calls from sandboxed processes. Firecracker leverages hardware virtualization via KVM to run a minimal virtual machine monitor (VMM), giving each workload its own guest kernel. Understanding their internal defenses is essential to weigh them against your risk profile.

Userspace Kernel: gVisor’s Defense-in-Depth

gVisor was created specifically to provide additional defense against kernel bug exploitation by untrusted userspace code. Its architecture replaces the host kernel with two layers running in userspace: the Sentry, which implements most syscall logic, and the Gofer, which handles file system access. This means the host kernel’s attack surface is never directly exposed to the untrusted code; all interactions are mediated and reduced to a smaller set of well-defined operations.

The resource model further isolates processes. Inside a gVisor sandbox, processes do not appear as host processes; they are modeled as goroutines within the Sentry, which are lightweight green threads. Similarly, the network stack runs entirely in userspace within the sandbox, and file systems like tmpfs at /tmp or /dev/shm allocate memory from the sandbox’s own memory file, not directly from the host. This design keeps untrusted workloads contained, and resources can be limited per container. Because the sandbox appears as a single opaque host process, it can scale dynamically-spanning many cores when busy and yielding them back when idle-which suits variable workloads common in serverless and agent-driven environments.

However, there are compatibility considerations. The Sentry must faithfully emulate Linux system calls. While gVisor has broad coverage, some infrequently used syscalls or specific kernel features may not be supported, potentially requiring application adjustments. The documentation at gVisor’s architecture intro explains that the Sentry runs in a restricted environment and delegates to the Gofer for file access, which can introduce performance overhead for I/O-heavy workloads. Still, for many teams running containers, gVisor offers a drop-in isolation layer with minimal operational changes.

MicroVM: Firecracker’s Hardware-Backed Isolation

Firecracker takes a different path: it uses Linux’s Kernel Virtual Machine (KVM) to create microVMs-lightweight virtual machines that provide hardware-enforced isolation. The Firecracker VMM is purpose-built for serverless and multi-tenant services, and it excludes unnecessary devices and guest functionality to minimize both memory footprint and attack surface. Each microVM runs its own kernel, and the host is protected by the virtualization boundary; a bug in the guest kernel cannot directly compromise the host unless the VMM itself is exploited.

Firecracker was developed at Amazon Web Services to accelerate services like AWS Lambda and AWS Fargate, where fast startup and high density are paramount. The project, open sourced under Apache 2.0, is integrated with container runtimes such as Kata Containers and Flintlock, and it supports OCI image formats through tools like firecracker-containerd. This compatibility layer lets you run standard Linux containers inside a microVM, combining the security of virtualization with the familiar container workflow. The firecracker-containerd project includes a control plugin for containerd, an agent running inside the microVM to invoke runC, and a root filesystem builder.

Operationally, microVMs start quickly and consume few resources, making them suitable for packing diverse workloads on the same host without sacrificing isolation. Unlike traditional VMs, Firecracker’s minimal device model-no emulated BIOS, only a few virtio devices-keeps the trusted computing base small. The attack surface is further reduced by the VMM’s design: it handles only essential tasks like CPU and memory management, network via a configured TAP interface (e.g., “tc-redirect-tap”), and local storage. However, this minimalism can mean that some Linux features expected by applications (e.g., certain device nodes or kernel modules) are absent, so teams must validate their workload’s kernel requirements. Additionally, the overhead of running a separate guest kernel per microVM, while small, can add up when orchestrating hundreds of workloads, and memory deduplication is not as straightforward as in process-sharing sandboxes like gVisor.

Attack Surface and Compatibility: Making the Trade-off

The core trade-off between gVisor and Firecracker lies in how they narrow the attack surface and what that costs in compatibility and resource efficiency. gVisor reduces exposure by filtering and reimplementing syscalls; if the Sentry is bug-free, the untrusted code never touches the host kernel’s system call interface. The attack surface becomes the Sentry itself, which is written in Go and thus less prone to memory-safety issues than traditional C kernels. Firecracker, on the other hand, relies on the battle-tested KVM subsystem and hardware virtualization. The attack surface is the VMM and the KVM API; even if the guest kernel is compromised, the attacker must break out of the VM, which is a far higher bar than escaping a userspace sandbox. For this reason, Firecracker is often preferred for highly hostile multi-tenant environments.

Compatibility tells a different story. gVisor aims to be a transparent container runtime, so most Linux applications can run unmodified, albeit with some performance penalty for I/O and unsupported system calls. Firecracker requires that you boot a full guest kernel (albeit a minimal one) and manage a VM lifecycle, which adds complexity. But with firecracker-containerd and OCI images, the container ecosystem has made this path more accessible. For teams already using Kubernetes, tools like Kata Containers can slot Firecracker in as a runtime class, letting you selectively isolate particularly sensitive pods.

Operationally, both models can be integrated into CI/CD and orchestration pipelines at small to mid-sized companies. gVisor’s memory sharing across sandboxes (via SCM_RIGHTS for host files) can lead to higher density on a single host, which keeps infrastructure costs down. Firecracker’s per-microVM guest kernel requires more memory overhead, but that cost is often justified by the stronger isolation guarantee. Early profiling and load testing with representative agent workloads will reveal which penalty your team can absorb.

Frequently Asked Questions

Q: Is gVisor’s userspace kernel as secure as a hypervisor-based microVM?

gVisor reduces the host kernel attack surface by mediating all system calls, but it does not provide hardware-enforced isolation. Firecracker uses KVM to create a hardware boundary, which is generally considered stronger because escaping a VM is harder than breaking out of a userspace process. The choice depends on your threat model: if you must defend against kernel exploits from untrusted code, Firecracker offers a higher assurance; if you need compatibility and density, gVisor is sufficient for many cases.

Q: Can I run unmodified Docker containers with Firecracker?

Yes, via firecracker-containerd. This project integrates with containerd to run OCI images inside microVMs. The container’s root filesystem is built into a microVM disk image, and an agent inside the microVM manages the container lifecycle with runC. Some minimal adjustments (e.g., kernel features) may be needed, but the workflow remains container-like.

Q: Which solution has better performance for network-heavy workloads?

gVisor runs its own network stack in userspace, which can add latency compared to native networking. Firecracker uses a virtualized network device (virtio-net) with a TAP interface on the host, which can be more efficient but still introduces virtualization overhead. Both will have overhead; testing with your actual workload is essential. For high-throughput services, a microVM with hardware offload might outperform gVisor’s software stack.

Q: How do resource limits work in gVisor versus Firecracker?

gVisor models resources per sandbox: processes as goroutines, memory from a sandbox-internal file, and network resources within the sandbox’s stack. Limits can be applied, and the sandbox can release resources back to the host. Firecracker microVMs have traditional VM resource limits (vCPU count, memory size) and do not share host processes; each microVM is an isolated process on the host with its own guest resources. Both allow restricting what untrusted code can consume, but gVisor’s approach is more granular for process-like workloads.

Further Reading