Kernel & Runtime Sandboxing Benchmark for Code-Executing AI Agents
Whenever an LLM synthesizes and executes Python, Bash, SQL, or Node.js, you are running untrusted remote code inside your infrastructure. Compare Firecracker MicroVMs, the open-source gVisor (`runsc`) project, Wasmtime, and Kata Containers, and copy hardened `nftables` rules blocking `169.254.169.254` metadata theft.

Isolation Boundary, Cold-Start & Syscall Surface Comparison
Cold-start latency and memory figures reflect typical warm-pool or snapshot-free baseline Linux x86_64 measurements; always benchmark your own rootfs image size and network CNI attachment overhead.
| Sandbox Runtime | Kernel / Memory Boundary | Cold Start | RAM Overhead | Host Syscall Surface | Target Agent Workload |
|---|---|---|---|---|---|
| Firecracker MicroVM (KVM) | Hardware KVM virtualization + dedicated minimal Linux guest kernel per worker | ~125 ms | < 5 MiB | Isolated guest kernel; minimal VirtIO net/block device model (no QEMU) | Arbitrary Python/Bash/Node code interpreters, repo-cloning agents, and untrusted package installs |
| the open-source gVisor (runsc) project | Memory-safe user-space Sentry kernel intercepting guest syscalls without full hardware VM | ~50 to 100 ms | ~15 to 30 MiB | Host Linux kernel shielded; only ~70 allowlisted host syscalls invoked by Sentry/Gofer | Multi-tenant Kubernetes OCI agent pods needing container density without bare-metal KVM |
| Wasmtime (WebAssembly + WASI) | Capability-zero linear memory sandbox; bounds-checked AOT/JIT execution | < 5 ms | < 2 MiB | Zero ambient host filesystem, clock, env, or socket syscalls unless explicitly pre-opened | Single-function MCP tools, deterministic parsers, data transforms, and policy evaluators |
| Kata Containers (QEMU / Cloud Hypervisor) | Hardware VM per Kubernetes Pod with OCI CRI integration and optional VFIO passthrough | ~180 to 350 ms | ~30 to 80 MiB | Dedicated guest kernel per pod; supports multi-container sidecars and PCI/GPU passthrough | Heavy multi-container agent pipelines requiring hardware accelerators or standard Kubernetes CRDs |
| Unconfined Shared-Kernel Docker (Anti-Pattern) | Linux namespaces + cgroups sharing the host Linux kernel syscall table directly | ~150 to 250 ms | ~5 MiB | 300+ host kernel syscalls exposed (io_uring, bpf, netfilter); high kernel CVE blast radius | Unsafe for untrusted LLM-generated code execution; restrict strictly to trusted static services |
Why Unconfined Shared-Kernel Docker Fails for LLM-Generated Code
1. Shared Host Linux Syscall Table
Standard Linux containers isolate process visibility via `namespaces` and resource quotas via `cgroups`, yet every process inside the container invokes the exact same host kernel ring-0 syscall interface. Local privilege escalation bugs in `io_uring`, `netfilter`, or filesystem drivers allow prompt-injected payloads to escape to the Kubernetes node.
2. Ambient IMDS & Kubernetes Token Leakage
Default container bridge networks permit outbound HTTP requests to `169.254.169.254` (cloud Instance Metadata Service) and mount `/var/run/secrets/kubernetes.io/serviceaccount/token` automatically. A 3-line Python snippet inside an injected prompt can harvest node IAM credentials in milliseconds.
3. Persistent Filesystem & Fork-Bomb Contention
Reusing long-lived warm containers across user sessions leaks `/tmp` files, environment variables, and background child processes between tenants. Ephemeral MicroVMs destroy block devices and zero guest RAM after a single 60-to-300 second task run.
Copyable Egress Firewall Rules: Blocking 169.254.169.254 IMDS & RFC 1918
Kernel isolation without network containment still leaves your internal VPC and cloud metadata endpoints exposed. Apply this `nftables` baseline on the MicroVM tap interface or sandbox network namespace so outbound connections default-drop and only allowlisted Layer-7 TLS inspection proxies receive traffic.
#!/usr/sbin/nft -f
# Deterministic Egress-Deny Firewall for AI Agent Code-Execution Sandboxes
# Blocks Cloud IMDS (169.254.169.254), Loopback, and RFC 1918 Private Networks.
flush ruleset
table inet agent_sandbox_egress {
set approved_tls_egress_proxies {
type ipv4_addr
elements = { 198.51.100.10, 198.51.100.11 }
}
chain output {
type filter hook output priority 0; policy drop;
# Allow established return frames for approved proxy connections
ct state established,related accept
# Explicitly drop AWS/GCP/Azure/Cloud IMDS link-local credential endpoint (169.254.169.254)
ip daddr 169.254.169.254 counter drop
ip daddr 169.254.0.0/16 counter drop
ip6 daddr fe80::/10 counter drop
ip6 daddr fd00:ec2::254 counter drop
# Explicitly drop host loopback and RFC 1918 internal East-West subnets
ip daddr {
127.0.0.0/8,
10.0.0.0/8,
172.16.0.0/12,
192.168.0.0/16,
100.64.0.0/10
} counter drop
# Permit outbound HTTPS (TCP/443) strictly to allowlisted L7 inspection proxy IPs
tcp dport 443 ip daddr @approved_tls_egress_proxies accept
# Drop all raw DNS, UDP, ICMP, and direct internet exfiltration attempts
counter drop
}
}Kubernetes RuntimeClass Pod Spec & Upstream Failover Coupling
When running on managed Kubernetes clusters where bare-metal `/dev/kvm` nested virtualization is unavailable, bind agent pods to the open-source gVisor (`runsc`) project via `RuntimeClass`, disable `automountServiceAccountToken`, and enforce a read-only root filesystem. Remember that sandbox timeout budgets must also coordinate with upstream LLM API latency spikes and HTTP 429/529 retries: explore live 5-minute polled AI provider status feeds and compound multi-agent SLA availability calculators at our sister SRE publication, agentoutages.com.
# Kubernetes RuntimeClass binding untrusted agent pods to gVisor (runsc) or Kata
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: agent-sandbox-runsc
handler: runsc
---
apiVersion: v1
kind: Pod
metadata:
name: code-interpreter-worker
spec:
runtimeClassName: agent-sandbox-runsc
automountServiceAccountToken: false
enableServiceLinks: false
securityContext:
runAsNonRoot: true
runAsUser: 65532
seccompProfile:
type: RuntimeDefault
containers:
- name: runner
image: registry.internal.example/agent-python-runner:2026.11
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]Reviewed by Dr. Henrik Solberg, Principal AI Security & Runtime Containment Editor
Reviews OWASP GenAI Agentic security controls, Firecracker/gVisor/Wasm isolation architectures, and NIST AI RMF governance gates.
Last reviewed:
Reviewed every 3 months
AI-assistance & editorial check: Research outlining and formatting are assisted by AI tools in an offline draft workflow. Nothing on this site publishes automatically without verification. A named human editor opens and verifies every primary source link, command snippet, and factual statement prior to publication. See our Editorial Policy and Corrections Policy.
Verified Primary Sources
- Firecracker: Lightweight Virtualization for Serverless Applications (USENIX NSDI / Firecracker Open Source Project, MicroVM Architecture)
- gVisor Container Runtime Sandbox Architecture & Syscall Security Guide (Open-Source gVisor Project Documentation, User-Space Kernel Docs)
- Wasmtime Security & WASI Capability-Based Isolation Model (Bytecode Alliance, WebAssembly Security Spec)
- Kata Containers Architecture: OCI Lightweight Virtual Machines (OpenInfra Foundation / Kata Containers, VM-Isolated Containers)
Receive Sandbox Benchmark & Kernel Hardening Updates
Runtime Guardrails & Sandbox EngineeringStore your email for technical notes on Firecracker snapshot security, WASI 0.2 component isolation, and container escape advisories. No emails are sent yet.