VM Isolation for High-Security Code Agents
gVisor, Firecracker microVMs, and hardware-level isolation for agents.
VM Isolation for High-Security Code Agents is a free AI Agents lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the AI Agents learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Beyond Docker: Stronger Isolation
Standard Docker containers share the host kernel. A kernel exploit inside the container can escape to the host. For high-security code execution, stronger isolation layers are required.
Two major approaches: gVisor (user-space kernel proxy) and Firecracker (lightweight microVMs).
How gVisor Works
gVisor inserts a user-space component called Sentry between the container and the host kernel. The container's system calls go to Sentry, which re-implements a safe subset in Go, not the real kernel.
The runtime is called runsc (run sandboxed container).
# Configure Docker to use gVisor runtime (runsc)
# /etc/docker/daemon.json:
# {
# "runtimes": {
# "runsc": { "path": "/usr/local/bin/runsc" }
# }
# }
import docker
client = docker.from_env()
output = client.containers.run(
'python:3.12-slim',
'python -c "print(\"hello from gVisor\")"',
runtime='runsc', # use gVisor
network_disabled=True,
auto_remove=True
)
print(output.decode())gVisor Syscall Interception
When code inside the container calls open(), read(), or socket(), gVisor intercepts the syscall and decides whether to allow, emulate, or deny it.
Sensitive syscalls like ptrace or raw socket creation are blocked by default, closing common exploit vectors.
# gVisor blocks dangerous syscalls like ptrace.
# This code would fail inside a gVisor container:
#
# import ctypes
# libc = ctypes.CDLL(None)
# libc.ptrace(...) # EPERM: Operation not permitted
#
# Normal Python I/O and computation works fine:
# open(), read(), write(), socket() (if network enabled)
# are all emulated safely by Sentry.
print('gVisor intercepts syscalls before they reach the host kernel')gVisor Performance Tradeoff
Every syscall goes through Sentry instead of directly to the kernel. This adds ~10-30% overhead on I/O-heavy workloads. For CPU-bound computation, the overhead is much smaller.
Startup time is similar to regular Docker — milliseconds.
import time
import docker
client = docker.from_env()
start = time.time()
client.containers.run('python:3.12-slim', 'python -c "pass"',
runtime='runsc', auto_remove=True)
print(f'gVisor startup: {time.time()-start:.2f}s') # ~0.3-0.8s
start = time.time()
client.containers.run('python:3.12-slim', 'python -c "pass"',
auto_remove=True)
print(f'Docker startup: {time.time()-start:.2f}s') # ~0.1-0.3sFirecracker MicroVMs
Firecracker takes a completely different approach: it runs each workload in a full virtual machine with its own kernel. The VM boots in ~50ms and uses only ~5MB of overhead memory.
Because VMs have a completely separate kernel, there is no shared kernel attack surface.
# Firecracker is controlled via a REST API on a Unix socket.
# Python SDK example (firecracker-python-sdk or direct HTTP):
import requests_unixsocket
session = requests_unixsocket.Session()
base = 'http+unix://%2Ftmp%2Ffirecracker.socket'
# Boot the microVM
session.put(f'{base}/boot-source', json={
'kernel_image_path': '/opt/kernel/vmlinux',
'boot_args': 'console=ttyS0 reboot=k panic=1 pci=off'
})
session.put(f'{base}/actions', json={'action_type': 'InstanceStart'})
print('MicroVM booted in ~50ms')Firecracker Security Model
Firecracker VMs have a minimal attack surface by design. The VMM exposes only 5 device types (virtio-net, virtio-block, serial, RTC, keyboard). No USB, no PCI bus, no BIOS.
Each VM is isolated at the hypervisor level — a kernel exploit inside the VM cannot reach the host.
# Firecracker security properties:
# 1. Each microVM has its own Linux kernel instance
# 2. Guest-to-host attack surface is tiny (5 device types)
# 3. The VMM (Virtual Machine Monitor) runs unprivileged
# 4. No shared memory between VMs
# 5. Snapshot/restore: freeze a running VM, clone it for next request
# Used in production by:
# - AWS Lambda (each function invocation = Firecracker microVM)
# - Fly.io (each app container)
# - Replit (code execution)
print('Firecracker: full VM isolation at container startup speed')Kata Containers: Combining Both
Kata Containers use a lightweight VM (can use Firecracker or QEMU) but expose the standard OCI container interface. You run normal Docker commands; Kata handles the VM layer transparently.
import docker
client = docker.from_env()
# Kata Containers registered as 'kata-runtime' in daemon.json
output = client.containers.run(
'python:3.12-slim',
'python -c "import platform; print(platform.node())"',
runtime='kata-runtime', # each container = a VM
mem_limit='256m',
network_disabled=True,
auto_remove=True
)
print(output.decode()) # unique VM hostnameChoosing the Right Isolation Level
The right sandbox depends on your threat model and latency budget:
- Docker (runc): fast, low overhead, shared kernel — OK for trusted or lightly-filtered code
- gVisor (runsc): syscall filtering, same image format, mild overhead — good balance
- Firecracker/Kata: full VM isolation, 50ms boot — for untrusted user code at scale
Security vs Startup Latency Table
Isolation depth and startup speed are inversely related. Choose based on acceptable latency for your agent's use case.
# Isolation vs Latency summary:
#
# Runtime | Isolation | Startup | Overhead
# -----------------|---------------|----------|----------
# runc (Docker) | Namespace | ~100ms | ~0%
# gVisor (runsc) | Syscall filter | ~300ms | ~15-30%
# Kata Containers | Full VM | ~500ms | ~10%
# Firecracker | Full VM | ~50ms | ~5%
# QEMU KVM | Full VM | ~1-2s | ~5%
#
# For interactive agent tools: gVisor is usually the sweet spot.
# For high-throughput batch jobs: Firecracker snapshots.
ISOLATION_OPTIONS = {
'runc (Docker)': {'isolation': 'Namespace', 'startup': '~100ms', 'overhead': '~0%'},
'gVisor (runsc)': {'isolation': 'Syscall filter', 'startup': '~300ms', 'overhead': '~15-30%'},
'Kata Containers': {'isolation': 'Full VM', 'startup': '~500ms', 'overhead': '~10%'},
'Firecracker': {'isolation': 'Full VM', 'startup': '~50ms', 'overhead': '~5%'},
'QEMU KVM': {'isolation': 'Full VM', 'startup': '~1-2s', 'overhead': '~5%'},
}
for runtime, info in ISOLATION_OPTIONS.items():
print(f"{runtime:<17} | {info['isolation']:<14} | startup {info['startup']:<7} | overhead {info['overhead']}")
Pre-warming Sandboxes
Cold-starting a VM for every agent request adds latency. Production systems pre-warm a pool of idle sandboxes. When a request arrives, a warm sandbox is claimed, used, and then destroyed (never reused).
import queue, threading
SANDBOX_POOL_SIZE = 5
pool = queue.Queue()
def pre_warm():
'Start a sandbox and put it in the pool.'
container = client.containers.create(
'python:3.12-slim',
'tail -f /dev/null',
runtime='runsc',
mem_limit='256m',
network_disabled=True
)
container.start()
pool.put(container)
# Pre-warm the pool at startup
for _ in range(SANDBOX_POOL_SIZE):
threading.Thread(target=pre_warm, daemon=True).start()
def claim_sandbox():
return pool.get(timeout=5) # blocks until one is readySnapshot and Restore for Scale
Firecracker supports snapshotting a running VM to disk. The snapshot captures memory state, device state, and CPU registers. Restoring from snapshot takes ~10ms — much faster than a cold boot.
This pattern lets you pre-initialize a Python interpreter once, snapshot it, and restore for each request.
# Firecracker snapshot workflow:
# 1. Boot microVM, run Python interpreter, wait for REPL ready
# 2. Pause VM
# 3. Create snapshot
# PUT /snapshot/create { snapshot_path, mem_file_path }
# 4. For each request:
# PUT /snapshot/load { snapshot_path, mem_file_path }
# # VM resumes from paused state with Python already loaded
# # Send code via stdin/virtio-serial, read output
# 5. Discard VM after request (never reuse)
print('Snapshot restore: ~10ms vs 50ms cold boot for Firecracker')Which component does gVisor insert between the container and the host kernel?
gVisor's isolation model depends on a specific component that intercepts system calls. Understanding this architecture is key to evaluating its security guarantees.
VM Isolation Recap
For high-security agent code execution, move beyond standard Docker to gVisor (syscall interception, low overhead) or Firecracker (full VM, 50ms boot, ~5MB overhead).
The tradeoff is always isolation depth vs startup latency. Pre-warming pools and VM snapshots can recover most of the latency cost in production.
Frequently asked questions
Is the “VM Isolation for High-Security Code Agents” lesson free?
Yes — the full text of “VM Isolation for High-Security Code Agents” is free to read here on the web, and the AI Agents course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the AI Agents course, upgrade to CoddyKit PRO.
What will I learn in “VM Isolation for High-Security Code Agents”?
gVisor, Firecracker microVMs, and hardware-level isolation for agents. You practise AI Agents with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start AI Agents?
No prior experience is required. AI Agents on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “VM Isolation for High-Security Code Agents” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this AI Agents lesson?
Yes. Every AI Agents lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Docker-Based Agent Sandboxes
- VM Isolation for High-Security Code Agents
- E2B and Cloud Sandbox Services
- Security Policies for Code Execution