
Agent Sandboxing: Running Untrusted Tool Code Safely
Explore techniques for safely executing untrusted code in AI agents using microVMs, gVisor, and WebAssembly to ensure secure isolation.
When an AI agent executes a tool—such as a Python script provided by a third-party API or a user-generated function—it is effectively running untrusted code. For security engineers, this is not merely a code review problem; it is an execution environment problem. If the agent’s runtime is compromised, the attacker gains control over the underlying infrastructure. Standard process isolation (like subprocess in Python) is insufficient because it relies on the host kernel’s security model, which can be bypassed via race conditions, symlink attacks, or kernel vulnerabilities. To secure AI agents, we must implement a defense-in-depth strategy that layers isolation techniques: WebAssembly (WASM) for memory-safe sandboxing, gVisor for system call interception, and microVMs for hardware-enforced boundaries.
The Threat Model: Why Process Isolation Fails
The primary risk in agent sandboxing is tool injection. An attacker does not need to break into the agent’s core logic; they only need to trick the agent into executing a malicious payload. For example, an LLM might be prompted to "write a script that fetches data from X." If the tool code is not strictly sandboxed, the script can read environment variables, access local files, or make network requests to exfiltrate data.
Traditional containers (Docker) share the host kernel. If a vulnerability exists in the kernel or in the container runtime, an attacker can escape the container and gain root access to the host. This is known as a container escape. In the context of AI agents, where tools are often dynamic and generated at runtime, static analysis is impossible. Therefore, the execution environment itself must be untrusted.
Layer 1: WebAssembly (WASM) for Memory Safety
The first layer of defense is WebAssembly (WASM). WASM is a binary instruction format designed for safe execution in web browsers and now widely used in backend services. It operates as a stack-based virtual machine that restricts direct hardware access.
Mechanism: The Linear Memory Model
WASM enforces a strict separation between the code and the host environment. It uses a linear memory model, meaning all memory is accessed through explicit load and store instructions. The WASM virtual machine (VM) does not have direct access to the host’s file system, network, or CPU registers unless explicitly granted via the WebAssembly System Interface (WASI) or similar bindings (like Wasmtime or Wasmer).
This design prevents common vulnerabilities:
- Buffer Overflows: WASM memory is bounded. You cannot write past the end of the allocated memory segment.
- Code Injection: WASM code is validated before execution. It cannot execute arbitrary machine code or jump to arbitrary memory addresses.
For short-lived tool execution, WASM is ideal. A Python script can be transpiled to WASM using tools like Pyodide or compiled via Emscripten. The agent runs the tool inside the WASM VM, which provides a sandbox with minimal overhead. However, WASM alone is not enough for complex tools that require system calls (e.g., opening a file). This is where gVisor comes in.
Layer 2: gVisor for System Call Interception
When a tool needs to interact with the operating system (e.g., creating a temporary file, making an HTTP request), it must make system calls (syscalls). Traditional containers pass these syscalls directly to the host kernel. gVisor changes this by acting as a user-space kernel.
Mechanism: The Intercept Layer
gVisor consists of two main components:
- Sentry: The user-space kernel that receives syscalls from the application.
- Gofer: A process that proxies filesystem access for the Sentry.
When an application inside a gVisor sandbox makes a syscall, the Sentry intercepts it. Instead of passing it to the host kernel, the Sentry emulates the behavior of the syscall in user space. For example, if a tool tries to open() a file, gVisor checks its own internal file table and permissions before allowing the operation. If the tool tries to read /etc/shadow, gVisor denies it because it does not have visibility into the host’s file system.
This layer protects against kernel exploits. Since the Sentry is a separate, smaller attack surface than the full Linux kernel, it reduces the risk of kernel-level vulnerabilities being exploited. Additionally, gVisor implements its own syscall filtering mechanism in user space, which is analogous to seccomp but does not rely on the host kernel's seccomp-bpf for enforcement. For AI agents, this means you can allow read, write, and socket calls while blocking execve, ptrace, and other dangerous syscalls.
Layer 3: MicroVMs (Firecracker) for Hardware Isolation
For long-running or highly privileged tools, user-space interception (gVisor) may introduce too much latency or complexity. In these cases, microVMs like AWS Firecracker provide hardware-enforced isolation.
Mechanism: Kernel-Based Virtual Machine (KVM)
MicroVMs are lightweight virtual machines that use KVM to leverage hardware virtualization extensions (Intel VT-x or AMD-V). Unlike full VMs, microVMs do not include a full guest kernel or BIOS. Instead, they boot a minimal Linux kernel that is specifically designed for fast startup and low overhead.
The key advantage is hardware isolation. Each microVM runs in its own memory space, isolated by the CPU’s memory management unit (MMU). Even if an attacker compromises the guest kernel, they cannot access the host’s memory or other VMs without exploiting a hypervisor vulnerability, which is significantly harder than escaping a container or user-space kernel.
Firecracker, for example, starts a microVM in milliseconds and uses minimal memory overhead (as little as 5MB per microVM). This makes it cost-effective to spawn a new microVM for each high-risk tool execution. The agent can send the tool code to the microVM via a remote procedure call (RPC), and the microVM executes it in complete isolation.
Integration Strategy: Composing the Layers
The most robust architecture combines these layers based on the trust level of the tool:
- Ephemeral Scripts: For simple, stateless tools (e.g., a math calculation or a short Python snippet), use WASM. It offers near-native performance and strong memory safety.
- Containerized Services: For tools that need a full OS environment but should not interact with the host, use gVisor. It provides a balance of security and compatibility with existing container ecosystems.
- High-Risk Tools: For tools that require network access, file I/O, or are from untrusted sources, use microVMs. The hardware isolation ensures that even if the guest is fully compromised, the host remains secure.
Trade-offs
- Latency: WASM is fastest (<1ms startup), gVisor is moderate (~10-50ms), and microVMs are slower (~100-200ms) due to VM boot time.
- Overhead: WASM has minimal overhead, gVisor adds some CPU cycles for syscall emulation, and microVMs require memory for the guest kernel.
- Complexity: WASM is easiest to integrate, gVisor requires container runtime support, and microVMs require orchestration (e.g., via Kubernetes or a custom scheduler).
Conclusion
Securing AI agents is not about finding a single silver bullet. It is about building a layered defense that assumes compromise at each level. By using WASM for memory-safe sandboxing, gVisor for syscall interception, and microVMs for hardware isolation, platform engineers can create a strong execution environment that protects the host infrastructure from untrusted tool code. As AI agents become more autonomous, this multi-layered approach will be essential for maintaining security and trust.
Related posts
Input and Output Guardrails in Practice
Practical implementation of input and output guardrails for AI systems, covering content moderation, classifier tuning, and reducing false positives in streaming data.
Prompt Injection: Direct, Indirect, and Why It's Unsolved
An examination of direct and indirect prompt injection attacks, jailbreak techniques, and current mitigation strategies for AI security.
The Threat Model for AI Agent Identity
A technical examination of threat models for AI agent identity, focusing on confused deputy problems and non-human identity security for engineers.