By Sagar Shankaran, Founder of CallSphere
Explore isolation strategies for AI agents including Docker container security, gVisor sandboxing, Firecracker microVMs, and WebAssembly sandboxes, with practical guidance on choosing the right isolation level for your threat model.
Key takeaways
AI agents that execute code, run tools, or interact with external systems can cause damage if they behave unexpectedly. A code execution agent with access to the host filesystem can read sensitive configuration files. An agent that spawns shell commands can escalate privileges. Isolation ensures that even a fully compromised agent cannot affect the host system or other agents.
The isolation question is fundamentally about blast radius: if this agent goes rogue, what is the worst possible outcome? Your isolation strategy should make the answer to that question acceptable.
Isolation exists on a spectrum from weakest to strongest. Process-level isolation uses OS processes with restricted permissions. Container isolation adds filesystem and network namespaces. Sandbox isolation intercepts system calls. MicroVM isolation provides a full virtual machine boundary. Each level adds security but also adds overhead.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
flowchart LR
AGENT(["Agent wants<br/>to run code"])
POLICY{"Policy check<br/>allow list"}
SANDBOX[("Ephemeral sandbox<br/>Firecracker or gVisor")]
NETPOL["Egress firewall<br/>deny by default"]
LIMIT["Resource limits<br/>CPU, mem, time"]
EXEC["Run untrusted code"]
LOG[("Audit log")]
OUT(["Captured stdout<br/>or error"])
DENY(["Refuse"])
AGENT --> POLICY
POLICY -->|Allow| SANDBOX
POLICY -->|Block| DENY
SANDBOX --> NETPOL --> LIMIT --> EXEC --> LOG --> OUT
style POLICY fill:#f59e0b,stroke:#d97706,color:#1f2937
style SANDBOX fill:#ede9fe,stroke:#7c3aed,color:#1e1b4b
style EXEC fill:#4f46e5,stroke:#4338ca,color:#fff
style OUT fill:#059669,stroke:#047857,color:#fff
style DENY fill:#dc2626,stroke:#b91c1c,color:#fff
Containers are the most common isolation layer for production agents. However, a default Docker container shares the host kernel and has more privileges than necessary. Lock down agent containers with security options:
import docker
from dataclasses import dataclass
@dataclass
class AgentContainerConfig:
"""Security configuration for an agent container."""
image: str
memory_limit: str = "512m"
cpu_limit: float = 1.0
read_only_rootfs: bool = True
no_new_privileges: bool = True
drop_capabilities: list[str] | None = None
network_mode: str = "none" # No network by default
timeout_seconds: int = 60
def __post_init__(self):
if self.drop_capabilities is None:
self.drop_capabilities = ["ALL"]
class SecureAgentRunner:
"""Runs agent code inside hardened Docker containers."""
def __init__(self):
self.client = docker.from_env()
def run_agent_task(
self, config: AgentContainerConfig, command: str
) -> dict:
"""Execute an agent task in an isolated container."""
security_opt = []
if config.no_new_privileges:
security_opt.append("no-new-privileges:true")
container = self.client.containers.run(
image=config.image,
command=command,
detach=True,
mem_limit=config.memory_limit,
nano_cpus=int(config.cpu_limit * 1e9),
read_only=config.read_only_rootfs,
network_mode=config.network_mode,
cap_drop=config.drop_capabilities,
security_opt=security_opt,
# Prevent container from gaining host access
privileged=False,
# Temporary writable directory for agent scratch space
tmpfs={"/tmp": "size=100m,noexec"},
)
try:
result = container.wait(timeout=config.timeout_seconds)
logs = container.logs().decode("utf-8")
return {
"exit_code": result["StatusCode"],
"output": logs,
"error": result.get("Error"),
}
finally:
container.remove(force=True)
# Usage
runner = SecureAgentRunner()
config = AgentContainerConfig(
image="agent-sandbox:latest",
memory_limit="256m",
cpu_limit=0.5,
network_mode="none",
timeout_seconds=30,
)
result = runner.run_agent_task(config, "python /task/analyze.py")
gVisor (runsc) provides a user-space kernel that intercepts and reimplements system calls. The agent's code never directly touches the host kernel. This protects against kernel exploits that can escape standard containers:
class GVisorAgentRunner(SecureAgentRunner):
"""Runs agent containers using gVisor runtime for syscall isolation."""
def run_agent_task(
self, config: AgentContainerConfig, command: str
) -> dict:
container = self.client.containers.run(
image=config.image,
command=command,
detach=True,
runtime="runsc", # Use gVisor runtime
mem_limit=config.memory_limit,
nano_cpus=int(config.cpu_limit * 1e9),
read_only=config.read_only_rootfs,
network_mode=config.network_mode,
cap_drop=config.drop_capabilities,
privileged=False,
)
try:
result = container.wait(timeout=config.timeout_seconds)
logs = container.logs().decode("utf-8")
return {
"exit_code": result["StatusCode"],
"output": logs,
"error": result.get("Error"),
}
finally:
container.remove(force=True)
For the strongest isolation without full VM overhead, Firecracker provides lightweight microVMs that boot in under 125 milliseconds. Each agent runs in its own virtual machine with a dedicated kernel:
import subprocess
import json
import tempfile
class FirecrackerAgentRunner:
"""Manages agent execution inside Firecracker microVMs."""
def __init__(self, kernel_path: str, rootfs_path: str):
self.kernel_path = kernel_path
self.rootfs_path = rootfs_path
def create_vm_config(
self, vcpu_count: int = 1, mem_size_mib: int = 256
) -> dict:
return {
"boot-source": {
"kernel_image_path": self.kernel_path,
"boot_args": "console=ttyS0 reboot=k panic=1 pci=off",
},
"drives": [
{
"drive_id": "rootfs",
"path_on_host": self.rootfs_path,
"is_root_device": True,
"is_read_only": True,
}
],
"machine-config": {
"vcpu_count": vcpu_count,
"mem_size_mib": mem_size_mib,
"smt": False, # Disable SMT to prevent side-channel attacks
},
"network-interfaces": [], # No network by default
}
def launch_agent(self, task_payload: str) -> dict:
"""Launch a Firecracker microVM for agent task execution."""
config = self.create_vm_config(vcpu_count=1, mem_size_mib=128)
with tempfile.NamedTemporaryFile(
mode="w", suffix=".json", delete=False
) as f:
json.dump(config, f)
config_path = f.name
# In production, use the Firecracker API socket
# This is a simplified illustration
result = subprocess.run(
["firecracker", "--config-file", config_path],
capture_output=True,
text=True,
timeout=60,
)
return {
"stdout": result.stdout,
"stderr": result.stderr,
"returncode": result.returncode,
}
Match your isolation level to your threat model. For agents that only process text without executing code, container isolation is typically sufficient. For code execution agents, use gVisor or Firecracker. For agents handling regulated data like healthcare or finance, consider Firecracker microVMs with no network access.
Still reading? Stop comparing — try CallSphere live.
CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.
from enum import Enum
class ThreatLevel(Enum):
LOW = "low" # Text-only agent, no tool execution
MEDIUM = "medium" # Tool execution, trusted tools only
HIGH = "high" # Code execution, untrusted input
CRITICAL = "critical" # Regulated data, adversarial users
ISOLATION_MAP = {
ThreatLevel.LOW: "process",
ThreatLevel.MEDIUM: "docker",
ThreatLevel.HIGH: "gvisor",
ThreatLevel.CRITICAL: "firecracker",
}
def select_isolation(threat_level: ThreatLevel) -> str:
return ISOLATION_MAP[threat_level]
gVisor reimplements Linux system calls in user space, and its compatibility has improved significantly. Most Python workloads — including NumPy, requests, and common ML libraries — run without issues. However, some low-level operations like raw socket access or specific ioctl calls may not be supported. Test your agent's full dependency stack under gVisor before deploying to production.
Firecracker microVMs boot in approximately 125 milliseconds and add roughly 5-10 milliseconds of overhead per system call compared to bare containers. For AI agents where LLM inference takes seconds, this overhead is negligible. The primary cost is memory: each microVM requires a minimum of 128 MiB, so running many concurrent agent VMs needs capacity planning.
Yes, layered isolation is a best practice. Run your agent container with gVisor as the OCI runtime and further restrict it with seccomp profiles and AppArmor. For multi-agent systems, run each agent in its own container with network policies that allow communication only with authorized peers.
#ContainerSecurity #Sandboxing #AgentIsolation #Firecracker #GVisor #AgenticAI #LearnAI #AIEngineering

Written by
Sagar Shankaran· Founder, CallSphere
LinkedInSagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
Inside NVIDIA OpenShell — the open-source secure runtime for autonomous desktop agents. Sandboxing, policy enforcement, and why it matters in 2026.
Agents that write and run code need real isolation. A 2026 comparison of E2B, Daytona, Modal, and Firecracker-based sandboxes for production agentic workloads.
By April 2026 agent runtime sandboxing has three credible options — gVisor, Firecracker microVMs, and WASM — with different latency, capability, and tool-call tradeoffs.
Current state of AI agent safety research covering alignment techniques, sandbox environments, constitutional AI applied to agents, and red-teaming methodologies.
Design secure Claude Computer Use deployments with VM isolation, network restrictions, action allowlists, credential handling, and comprehensive audit logging to prevent unintended actions and data exposure.
Discover how to build AI agents that can write new Python tools at runtime, validate them in a sandbox, register them dynamically, and use them in subsequent reasoning — creating truly self-extending agent systems.
© 2026 CallSphere Inc. All rights reserved.
Made within San Francisco
Watch how CallSphere handles real customer calls, schedules appointments, and processes payments — live.