AI agents are no longer confined to chat windows. They read files, call APIs, write to databases, and execute code autonomously. That changes the security model entirely. A misconfigured agent is not just a buggy service; it is a privileged process that handles untrusted input and has broad tool access by design.
This guide covers three layers that actually matter: why standard Docker containers are not enough, how gVisor and Kata Containers raise the isolation floor, and how Docker's MCP Toolkit lets you enforce least-privilege at the tool layer.
1. Why Standard Docker Containers Are Not Enough
Docker containers isolate through Linux namespaces, cgroups, and seccomp, but they share the host kernel. Every container on a host calls into the same kernel. That is a fine trade-off for a trusted web server. It is a significant one for a process that dynamically generates and executes code based on external input.
The threat model for an AI agent looks like this:
- Container escape (MITRE ATT&CK T1611): a kernel vulnerability or misconfiguration gives an attacker host-level access, reaching every other container on the machine.
- Prompt injection leading to RCE: an agent receives a malicious instruction and executes it through a shell tool.
- Tool poisoning: hidden directives embedded in MCP tool metadata are visible to the model but not to the user.
- Credential exfiltration: an agent with filesystem access can read
.envfiles,~/.aws/credentials, or service account tokens.
Real-world baseline: A 2025 academic survey of over 1,800 deployed MCP server implementations found that more than 30% had at least one exploitable vulnerability. Endor Labs analysis of 2,614 MCP implementations found that 82% use file operations prone to path traversal and 34% use APIs susceptible to command injection.
CVE-2024-21626 ("Leaky Vessels") showed the concrete risk of shared-kernel runtimes: a process inside a container could set its working directory to /proc/self/fd/7, a leaked file descriptor pointing at the host filesystem, and achieve a full container escape. Affected all runc versions up to 1.1.11, patched in 1.1.12.
2. Stronger Runtimes: gVisor and Kata Containers
gVisor: a kernel in user-space
gVisor is a Google open-source project that implements the Linux kernel in user-space. A component called Sentry intercepts all syscalls before they reach the host kernel and handles them in an isolated process. From the container's perspective everything looks normal. From the host's perspective, no direct kernel calls ever happen.
Installation requires a single binary (runsc) registered in daemon.json. Any existing image runs without changes since it is OCI-compatible. The overhead is roughly 10 to 30% on I/O-heavy workloads and minimal on compute-heavy ones.
// JSON | /etc/docker/daemon.json
{
"runtimes": {
"runsc": { "path": "/usr/local/bin/runsc" }
}
}json
# YAML | docker-compose.yml (gVisor runtime)
services:
ai-agent:
image: my-agent:latest
runtime: runscyaml
Kata Containers: a micro-VM per container
Kata Containers wraps each container in a lightweight VM with its own Linux kernel via KVM. The hardware boundary eliminates an entire class of kernel-based attacks since there is no shared kernel to escape to. It is OCI-compatible and works with Docker Compose with a single runtime field change.
The trade-offs are cold starts of roughly 100 to 300ms, around 100 MB of extra RAM per container, and no support on macOS or WSL2 (you need bare metal or a cloud instance with nested virtualization). GPU passthrough works with Kata 3.x via VFIO.
# YAML | docker-compose.yml (Kata Containers runtime)
services:
ai-agent:
image: my-agent:latest
runtime: kata-qemu # or kata-fc (Firecracker, faster cold start)
cap_drop: [ALL]
read_only: true
security_opt:
- no-new-privileges:trueyaml
How to choose: use gVisor for high-I/O agents where simpler setup matters and a user-space kernel boundary is sufficient. Use Kata Containers when agents execute untrusted, LLM-generated code in production, since the dedicated kernel eliminates the kernel escape vector entirely. Standard runc is appropriate only for agents running fully trusted, reviewed code.
3. Docker MCP Toolkit: Least Privilege at the Tool Layer
Model Context Protocol (MCP) is Anthropic's open standard for connecting LLMs to external tools and data sources. Docker's MCP Toolkit, announced in April 2025 and released in beta in June 2025, solves three problems at once: tool discovery through a catalog of 300+ verified servers on Docker Hub, isolation where each MCP server runs as its own container, and credential management through a Gateway proxy rather than environment variables.
The three components
MCP Catalog is a curated registry on Docker Hub with automated testing and scanning. Currently over 300 verified servers including Stripe, Elastic, Neo4j, New Relic, Grafana, and many others.
MCP Toolkit is a Docker Desktop extension for managing server profiles and launching containers. Credentials are stored in Docker Desktop's secure store rather than in environment variables, reducing the risk of accidental exposure through logs or environment dumps.
MCP Gateway is an open-source proxy between MCP clients and servers that enforces policy on every tool call. It handles server lifecycle management, request routing, authentication, logging, and call tracing.
Key principle: By treating each tool as a separate MCP server container, you re-introduce least privilege. Instead of giving an agent broad access, you allow only the smallest set of capabilities it needs. The Gateway enforces this per-call and provides full audit visibility over every tool invocation.
Hardened Compose config
# YAML | docker-compose.yml (hardened MCP stack)
version: "3.9" services:
mcp-server:
image: mcp/wikipedia:latest@sha256:<digest> # pin by digest, not tag
runtime: runsc # gVisor runtime
read_only: true
tmpfs:
- /tmp:size=64m,noexec
cap_drop: [ALL]
security_opt:
- no-new-privileges:true
user: "1000:1000"
networks: [mcp-net]
mcp-gateway:
image: docker/mcp-gateway:latest
ports: ["127.0.0.1:8811:8811"]
volumes:
- ./policy.yaml:/config/policy.yaml:ro
networks: [mcp-net]
networks:
mcp-net:
internal: true # no outbound internet by defaultyaml
4. MCP Attack Patterns You Need to Know
Tool poisoning
Tool poisoning is a demonstrated attack class first documented publicly by Invariant Labs in April 2025. An attacker who controls an MCP server writes directives directly into tool descriptions or JSON Schema metadata. The model reads this as trusted configuration and executes hidden commands while the user sees nothing unusual. Because these fields arrive at boot as what looks like system configuration, they bypass the mental model most developers have of injection attacks.
The rug pull variant is subtler: a tool's description looks benign on day one, then quietly changes on day seven to redirect API keys to an attacker. MCP clients should alert on any change to tool descriptions after installation.
MCPoison: CVE-2025-54136
MCPoison (CVE-2025-54136, CVSS 7.2) is a related but distinct vulnerability discovered by Check Point Research in Cursor IDE. Once a user approved an MCP configuration file, Cursor never re-validated it on subsequent opens. An attacker with write access to a shared repository could commit a benign config, wait for approval, then silently swap in a malicious payload. Every subsequent Cursor launch would execute the attacker's commands with no warning. Fixed in Cursor 1.3, released July 29, 2025.
Supply chain: CVE-2025-6514
mcp-remote is a popular OAuth proxy for connecting local MCP clients to remote servers. JFrog Security Research discovered a critical OS command injection flaw (CVSS 9.6/10) in all versions from 0.0.5 up to 0.1.16. A malicious MCP server could send a crafted authorization_endpoint URL that mcp-remote passed directly to the system shell, achieving RCE on the client machine. The package had been downloaded over 437,000 times at the time of disclosure. Fixed in version 0.1.16.
Mitigation: Pin all images by sha256 digest, not by tag. Use only servers from the Docker MCP Catalog with passed verification. Enable signature verification in MCP Gateway. Alert on any change to tool descriptions. Keep mcp-remote at 0.1.16 or later.
Cross-server hijacking
When multiple MCP servers connect to the same agent, a malicious server can attempt to override or intercept calls to a trusted one through the model's context window. Network isolation between servers through an internal Docker network with gateway routing limits this attack surface structurally, since servers cannot reach each other without going through the Gateway policy layer.
5. Kubernetes: RuntimeClass for Per-Workload Isolation
For teams running agents on Kubernetes, RuntimeClass lets you assign an isolation level per Pod without changing container images.
# YAML | kata-runtime-class.yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: kata-containers
handler: kata-qemuyaml
# YAML | agent-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: ai-agent
spec:
runtimeClassName: kata-containers
containers:
- name: agent
image: my-agent:latest
securityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]yaml
Google's Agent Sandbox, a project contributed to CNCF under Kubernetes SIG, is building a standard for agentic workload isolation with gVisor and Kata Containers as pluggable backends. Not yet GA, but worth tracking if you already operate Kubernetes at scale.
6. Production Security Checklist
- Use gVisor or Kata Containers. Never use standard runc for code-executing agents.
- Never run containers with
--privileged. Drop ALL capabilities and add back only what is needed. - Set
read_only: trueon the container filesystem. Mount tmpfs for/tmpwithnoexec. - Bind MCP services to
127.0.0.1only. Use an internal Docker network with no default egress. - Pin every image by sha256 digest. Never deploy from a mutable tag in production.
- Store credentials in Docker Secrets or an external vault, not in environment variables.
- Log all tool calls through MCP Gateway. Redact secrets before they reach the model.
- Alert on changes to tool descriptions. This is your rug pull detector.
- Keep
mcp-remoteat version 0.1.16 or later. Audit all MCP-related npm packages regularly.
FAQ
What is Docker MCP and why does it matter for AI agents?
Docker MCP Toolkit is Docker's solution for running MCP servers as isolated containers with managed credentials and policy enforcement. Without it, MCP servers typically run directly on the host with access to the full filesystem. The Toolkit adds a catalog of 300+ verified servers, per-server container isolation, and an open-source Gateway proxy that enforces policy on every tool call and provides full call tracing.
What is the difference between gVisor and Kata Containers?
gVisor implements a Linux kernel in user-space so syscalls are intercepted by an isolated process instead of reaching the host kernel directly. Kata Containers goes further: each container gets its own micro-VM with a dedicated Linux kernel via KVM. gVisor is simpler to set up and works on most environments including cloud VMs; Kata gives stronger, hardware-enforced isolation and is the right choice when agents run untrusted, LLM-generated code in production.
Do I need a different container image for gVisor or Kata?
No. Both runtimes are OCI-compatible. Your existing images run without any changes. You only add a single runtime field to your Compose file or daemon.json.
What is MCP tool poisoning?
Tool poisoning embeds malicious instructions in an MCP tool's descriptions or JSON Schema metadata rather than in user input. The model reads this as trusted system configuration and executes the hidden directives. Invariant Labs first documented this attack class in April 2025. Defense includes using only catalog-verified servers pinned by digest, enabling Gateway policy enforcement, and monitoring for any changes to tool descriptions after initial installation.
What was CVE-2025-6514?
CVE-2025-6514 was a critical (CVSS 9.6) OS command injection vulnerability in mcp-remote, a widely used npm package for connecting MCP clients to remote servers via OAuth. A malicious MCP server could craft an authorization_endpoint URL that mcp-remote passed directly to the system shell. Discovered by JFrog Security Research, disclosed July 9, 2025, and fixed in mcp-remote version 0.1.16.
Conclusion
AI agents are privileged processes that handle untrusted input. Standard Docker container isolation was not designed for this threat model.
The practical floor for production in 2026 is gVisor for I/O-heavy agents, Kata Containers for anything executing untrusted code, Docker MCP Gateway as the policy enforcement point for every tool call, and digest-pinned images throughout. The MCP ecosystem is maturing fast and so is its CVE list. The tools to defend it exist today. The gap is architectural decisions, not missing technology.