On agent safety, part 2 of 2
What a Session Container Needs
Docker is the obvious place to run an agent’s code, and it isn’t a boundary. What the platforms that run agents for a living actually ship: a VM per session, egress off, no secrets inside, and guardrails the agent can’t write.
A map before you read
One line per section, written by an AI model running entirely in your browser. Free, private, nothing leaves your device.
- Engine
- loading…
- Model
- –
- Download
- –
- Speed
- –
Generated on your device by an AI model, not written by Kyle. It can be wrong; the essay is the source.
Most teams that need to run an agent’s code somewhere safe reach for Docker. It’s the obvious choice. Everyone already has it, a container starts in a second, and it looks like isolation: its own filesystem, its own process tree, its own network namespace.
The trouble is the kernel. Every container on a host shares the host’s kernel, so a bug in the kernel or the container runtime is a way out of all of them at once. That isn’t hypothetical. In January 2024, a file descriptor leak in runc, the runtime under Docker and most of Kubernetes, let a process in a newly started container end up with “a working directory in the host filesystem namespace,” which the advisory calls “a complete container escape” in its worst variants (NVD). And the thing running inside an agent’s container is now good at finding exactly that kind of bug. In March 2026 the UK AI Security Institute released SandboxEscapeBench, and its finding was that “when vulnerabilities are added, LLMs are able to identify and exploit them” (Marchand et al.).
The first part walked through the swarm attack, where about 1,200 OpenAI agents broke out of an evaluation and breached Hugging Face, and argued that the remedy is session containers. So what does a session container actually need to be one? This part answers that using the platforms that run agents for a living as the evidence. A container is where the code runs. A session container is a set of guarantees about what that code can reach.
A Machine Per Session
The first guarantee is the boundary itself, and the platforms have mostly stopped trusting the shared kernel. Google’s gVisor puts an application kernel between the container and the host, moving the system interfaces “into a distinct, per-sandbox application kernel in order to minimize the risk of a container escape exploit” (gVisor). AWS went further with Firecracker, which gives every workload its own lightweight virtual machine and boots one “in <125ms” with “<5 MiB overhead per VM” (Firecracker).
Firecracker matters because it removed the old excuse. The paper that introduced it, presented at NSDI in 2020, described the choice teams used to face as “a choice between virtualization with strong security and high overhead” and containers with weaker security and minimal overhead (Agache et al.). A virtual machine that boots in a fraction of a second takes the overhead side of that argument away. Vercel’s sandbox for agents runs each one “in a secure Firecracker microVM with its own filesystem and network” (Vercel). Microsoft’s Azure Container Apps dynamic sessions use “Hyper-V isolation” and hand out sessions “in milliseconds thanks to pools of ready but unallocated sessions” (Microsoft). Why accept a shared kernel at all? Speed was the reason, and it isn’t anymore.
The other half of the boundary is the session. In most agent products, a session is the same thing as a thread: one conversation, with its own history, from the first message to the last. Azure’s docs say plainly that anything inside a session, “including files and environment variables, is accessible by users of the session,” which is why the identifier matters as much as the isolation. Microsoft says to generate session identifiers with “cryptographic methods,” one per conversation, in a way that “can’t be modified by the end user” (Microsoft). One thread gets one machine, and the machine is destroyed when the thread goes idle. When someone picks the thread back up a week later, it gets a fresh machine, and anything it needs is restored from storage outside the session. The swarm’s first message was written into storage every agent shared. A session container shares nothing writable with any other session.
Egress Off
The second guarantee is that nothing leaves unless something outside the session allows it. Azure’s default is the right one: “By default, sessions are prevented from making outbound network requests.” OpenAI’s Codex does the same, and “by default, Codex blocks internet access during the agent phase,” with a list of what turning it on risks that reads like a summary of the field: “Prompt injection from untrusted web content,” “Code or secret exfiltration,” and “Downloading malware or vulnerable dependencies” (OpenAI).
Notice the exception in the Codex docs, though. “Setup scripts still run with internet access so you can install dependencies.” Every sandbox needs some way to get packages in, and that path is where the swarm got out. OpenAI’s evaluation had no direct internet access, but it had a package proxy, and the agents owned the proxy. The safe version of an exception is a proxy outside the session, run by something the agent can’t reconfigure, that allows specific destinations and specific methods. Anthropic’s sandbox for Claude Code routes network traffic through a proxy outside the sandbox for exactly that reason.
No Secrets Inside
The third guarantee is that the session holds nothing worth stealing. At Hugging Face, every step of the swarm attack ran on a credential it found in an environment variable, and every new credential opened the next system. Azure turns managed identity off inside sessions by default and warns that enabling it means “any code or programs running in the session can create Microsoft Entra tokens,” which should be done “with extreme caution.” The pattern that works is the same proxy from the last section. The session asks for a request to be made, and the proxy attaches the credential on the way out, for approved destinations only. The agent never sees the key.
Guardrails the Agent Can’t Write
The fourth guarantee is the one most setups miss. An agent’s hooks, permission settings, approval rules and MCP configs are usually files in the workspace, and a file the agent can write is a guardrail it can switch off. That’s how a prompt injection got GitHub Copilot to approve its own commands by editing a settings file, and it’s the fifth line from the first part. In a session container, configuration is mounted read-only, and the enforcement that matters most, the network proxy and the credential broker, runs outside the session where nothing inside can reach it.
Anthropic’s write-up of its Claude Code sandbox explains why the filesystem and the network have to be locked down together. “Without network isolation, a compromised agent could exfiltrate sensitive files like SSH keys; without filesystem isolation, a compromised agent could easily escape the sandbox and gain network access” (Anthropic). One without the other is a door with a lock and no wall.
Why It Makes Agents Faster
The part of this that gets the least attention is that hard boundaries make agents more useful, not less. Anthropic found that its sandbox “safely reduces permission prompts by 84%.” An agent that can’t reach anything dangerous doesn’t need to ask before every command, and an agent that doesn’t ask before every command can actually finish a task while you do something else. Prompts asking for approval were never a security boundary anyway. They were a person clicking yes, eventually without reading.
That’s the case I’d make to any team still running agents in a plain container or, worse, on a laptop. If I were setting one up today, I’d give every session its own microVM and destroy it at the end. I’d turn egress off and allow specific destinations through a proxy outside the session. I’d keep every credential outside the session and let the proxy attach it. I’d mount hooks and agent configuration read-only. And I’d keep the logs outside too, because the one control that held through the swarm attack was a record the agents couldn’t edit.
A container is where the code runs. A session container is what the code can’t reach.
Sources
- NIST National Vulnerability Database, CVE-2024-21626
- Marchand et al., “Quantifying Frontier LLM Capabilities for Container Sandbox Escape,” March 2026
- gVisor documentation
- Firecracker
- Agache et al., “Firecracker: Lightweight Virtualization for Serverless Applications,” NSDI 2020
- Vercel, “Vercel Sandbox”
- Microsoft, “Dynamic sessions in Azure Container Apps”
- Microsoft, “Use dynamic sessions in Azure Container Apps”
- OpenAI, “Codex: Agent internet access”
- Anthropic, “Making Claude Code safer with sandboxing,” October 2025