Skip to main content
Promotional banner ad for the Penetration Testing Report Kit
Sandbox Failure Teardown: Agent Code Meets a Shared KernelIncident
5 min readFor Security Engineers

Sandbox Failure Teardown: Agent Code Meets a Shared Kernel

A note on what this is. This analysis explores sandboxing layers for AI agents on Kubernetes. It doesn't document a specific breach or victim. Instead, it examines a failure pattern: design choices that allow untrusted agent-generated code to access shared infrastructure. Hypothetical scenarios are clearly labeled.

What Happened

AI agents generate and execute code without prior review. This is the core risk. The default Kubernetes container runtime, runc, shares the host kernel with every pod on the node. Containers use kernel features like namespaces and cgroups, but they're not a security boundary against determined attackers.

The failure pattern is clear. A team deploys an agent capable of running code, relying on the container for isolation. The agent's untrusted output runs alongside other workloads on a shared kernel. If that code exploits a kernel flaw or misconfiguration, the node and potentially the cluster are at risk.

Two alternatives frame the discussion. gVisor offers a middle path between runc and full virtualization. Kata Containers place each pod in a lightweight VM, requiring bare-metal nodes or VMs that support nested virtualization. Teams often skip the stronger option due to infrastructure limitations.

Timeline

Here's a generic sequence this failure pattern follows:

  1. Design. The agent needs to run code (a data transform, a script, a tool call). The team runs it in a standard pod.
  2. Deployment. Pods land on general-purpose nodes alongside other services. No runtime class is set, so runc is used.
  3. Exposure. The agent consumes input it doesn't control: user prompts, retrieved documents, third-party tool output. Any of these can steer the code it writes.
  4. Execution. Generated code runs with whatever the pod can reach: the service account token, the network, the node's kernel.
  5. Escape or lateral movement. A permissive pod spec or a reachable internal service is often enough before a kernel exploit is even required.

Isolation decisions are made at step 2, long before anyone considers step 5.

Which Controls Failed or Were Missing

Map the pattern to five layers:

  • Runtime isolation. Missing. runc alone provides process-level separation on a shared kernel. For untrusted code, it's the weakest option.
  • Pod hardening. Typically absent. Running as root, writable root filesystems, and retained Linux capabilities widen what escaped code can do.
  • Network segmentation. Often default-allow. Without NetworkPolicy, an agent pod can reach cluster-internal services and the metadata endpoint.
  • Identity and credentials. The default service account token is mounted into pods unless you turn that off. Agent code inherits it.
  • Resource limits. Unset limits let one agent starve neighbors. This is an availability failure, and it's the one teams notice first.

What the Relevant Standards Require

None of these frameworks mention AI agent sandboxing by name, but they do require the underlying controls. Here's where the failures land.

ISO/IEC 27001:2022, Annex A. Control 8.22 (segregation of networks) covers the missing NetworkPolicy. Control 8.31 (separation of development, test, and production environments) applies if agent experimentation shares production nodes. Control 8.9 (configuration management) covers pod specs and runtime class settings.

SOC 2 Type II. CC6.1 requires logical access controls over protected assets, which includes limiting what an untrusted workload can touch. CC6.6 addresses boundary protection against external threats. CC7.1 covers detection of configuration changes that introduce vulnerabilities. Type II means you need evidence these operated over the audit period, not just at a point in time.

NIST 800-53 Rev 5. SC-39 (process isolation) is the closest match to the runtime layer. SC-7 (boundary protection) covers network segmentation. AC-6 (least privilege) covers service account and capability scoping. SC-6 (resource availability) covers limits.

PCI DSS v4.0.1. If agents run near the cardholder data environment, Requirement 1 (network security controls) and Requirement 2 (secure configurations) apply directly. Requirement 7 covers least-privilege access. Treat any agent that can execute code in or adjacent to that scope as in scope until you've proven otherwise.

NIST Cybersecurity Framework (CSF) v2.0. The Protect function, specifically platform security and identity management outcomes, maps to runtime and credential decisions. The Govern function is where the "who approved running unreviewed code" question belongs.

Lessons and Action Items for Your Team

  1. Match isolation strength to code trust. Treat the three runtimes as a ladder. runc is fine for code your team wrote and reviewed. gVisor adds a user-space kernel layer and is a reasonable default for untrusted code when you can accept some performance cost. Kata Containers gives you VM-level isolation per pod, which is the right call for the highest-risk workloads, but it needs bare-metal nodes or nested virtualization support. Confirm that before you commit to it.

  2. Use RuntimeClass to enforce the choice. Don't rely on developers remembering to set it. Define a RuntimeClass per trust tier and use admission control to require it on any namespace that hosts agents.

  3. Isolate agent nodes. Use taints, tolerations, and dedicated node pools so untrusted agent pods never share a kernel with your payment, identity, or data services.

  4. Strip the pod down. Run as non-root, drop all capabilities, set a read-only root filesystem, and apply the restricted Pod Security Standard to agent namespaces.

  5. Default-deny the network. Start with a deny-all NetworkPolicy, then allow only the specific egress the agent needs. Block access to the cloud metadata endpoint explicitly.

  6. Kill the default credentials. Set automountServiceAccountToken: false on agent pods. If the agent needs cluster access, give it a purpose-built service account with the narrowest role you can write.

  7. Measure overhead before you argue about it. Benchmark your own workloads. Run representative agent tasks under each runtime, record latency, CPU, and memory, and set requests and limits from those results. Don't carry numbers from someone else's benchmark into your capacity plan. Syscall-heavy workloads tend to feel gVisor's interception cost more than compute-heavy ones, which is a reason to test your actual workload mix rather than assume.

  8. Collect audit evidence now. For SOC 2 Type II, screenshots of a config don't prove operating effectiveness. Export admission policy logs, RuntimeClass assignments, and NetworkPolicy state on a schedule so you can show the control ran across the whole period.

The takeaway is simple. An agent that runs unreviewed code is an untrusted tenant. Give it the isolation you'd give any untrusted tenant, and pick the runtime tier by what the code can do, not by what's easiest to deploy.

Topics:Incident
a promotional banner asking how ready are you for PCI DSS 4.0? With a call-to-action to get the checklist now.

You Might Also Like