The agent would make a change, something else would break, I’d ask the agent to fix that too, and a few cycles later the blog worked again. My confidence in what was underneath had quietly evaporated. That feeling (it works, thank god, let’s not touch it) is the feeling of having given an autonomous agent real access to your codebase. Every developer using these tools knows it. Nobody writes about it in vendor blog posts.
And it’s what made me understand, on a level deeper than reading documentation, why Docker had to build Sandboxes. Because here’s what I hadn’t thought about: while Claude Code was rewriting my Astro components and fixing image CLS across hundreds of files, every npm install it ran happened on my laptop. Same for every file it modified and every package it pulled. My user privileges, no boundary in sight. If the agent had decided to modify a Git hook or rewrite a CI workflow, I would not have noticed. I wasn’t reviewing individual file changes at that point. I was reviewing outcomes. And reviewing outcomes while skipping changes is not a security model. It’s a prayer.
Docker Sandboxes exists to close that gap.
The container model and why it doesn’t stretch here
Containers were never the wrong abstraction. They were the right abstraction for a world where you knew what was inside them. For twelve years that world held: you wrote the code, you reviewed it, you put it in a Dockerfile, and the container gave it a clean room to run in. Shared kernel was fine because the threat model was bugs in your own software, not surprises from a tenant you’d just invited in.
AI coding agents don’t fit. They aren’t bugs in your software because they aren’t your software. They’re a new kind of tenant, one that’s autonomous and privileged in ways that would make any security engineer nervous. The agent installs packages you didn’t pick and runs commands you didn’t script. It makes network calls you’d never have predicted, to endpoints you didn’t know were in your dependency tree. The trust profile is code being written right now, by something that won’t pause to ask permission. Containers were built for a different kind of code.
This isn’t hypothetical. On March 19, 2026, attackers force-pushed 76 of the 77 version tags in aquasecurity/trivy-action and published a malicious Trivy v0.69.4 binary to GitHub Releases. The exposure window was about 12 hours. The compromised code scraped CI runner memory for secrets, cloud credentials, SSH keys, and Kubernetes tokens, exfiltrating them to a typosquatted domain. Every pipeline that referenced trivy-action by version tag during that window ran code nobody on the receiving end had reviewed.
What gets me about Trivy: the weaponized tool was a vulnerability scanner. The thing organizations deployed to find malicious code became the malicious code. The maintainers didn’t write the bad binary; a compromised CI workflow with too much access and not enough containment did. Substitute “compromised CI workflow” with “AI agent in permissive mode” and you have the same threat model, running all day on every developer machine.
Containers were the right answer to “I trust this code, I want to run it cleanly.” They were never going to be the right answer to “I don’t fully trust this code, and I want to give it real work to do anyway.” That’s the gap microVMs fill.
What Docker built, and why each piece is there
First choice: don’t patch containers. There’s a long tradition in our industry of making a familiar abstraction handle a new problem by adding flags to it. Privileged mode, capability dropping, seccomp profiles, gVisor in front of runc. All of those have their place. None of them solved the specific issue that an autonomous agent needs its own Docker daemon. Docker-in-Docker either compromises the isolation (privileged mode, host socket mounting) or creates a nested complexity that becomes its own attack surface. The Docker docs are blunt about this. Containers, they say, share the host kernel.