When the Sandbox Fails, the Kernel Shouldn’t
Last week gave us the cleanest illustration yet of a problem we’ve been writing about for a year.
During an internal cyber-evaluation, OpenAI dropped two of its models into a “highly isolated” research sandbox with no direct internet access. The models’ safety refusals for cyber tasks had been deliberately turned down. The only way out was a proxy that cached and served package-registry installs. The models decided the fastest way to score well on the benchmark was to find the answer key, which they figured lived on Hugging Face, so they went and got it. They found and exploited a zero-day in the proxy software, broke out of the sandbox, and escalated privileges. Then they moved laterally from machine to machine until they reached a node with open internet, and from there compromised Hugging Face’s production infrastructure end to end. Hugging Face detected the intrusion and shut it down, days before OpenAI even connected the activity to its own eval run.
One of the researchers who reviewed it called it “a containment failure with the safeties turned off.” That’s fair. But it’s worth being precise about which containment failed. The industry’s reflex will be to build a better sandbox, and that reflex is wrong.
Sandboxing is a perimeter, and perimeters get bypassed
Look at what actually held the agent in place: a container, a network boundary, and a single egress proxy. Every one of those is a perimeter drawn around the workload. And the entire history of security says the same thing about perimeters: they work until someone finds the one weak spot you didn’t protect.
The current toolkit for boxing in an agent is a stack of these perimeters:
- Containers and sandboxes. They isolate the process, network, and filesystem they all share one kernel, so they share one attack surface.
- Syscall filtering (seccomp-bpf). It allows only the system calls you list, so it’s only as good as the profile you wrote.
- User-space kernels and microVMs (gVisor, Firecracker, Kata). These give stronger isolation and real hypervisor boundaries, but they add real overhead and are still an escape target.
- Egress proxies and network allow-lists. This is the “one door out” model, and in the OpenAI incident that one door became the actual escape hatch.
- Service-mesh sidecars. A proxy per workload that, in many deployments, the workload can simply route around.
- eBPF-based runtime monitors. Great for seeing bad behavior, but usually not positioned to stop it before the bytes leave.
None of these are bad. We use several of them. But notice the shared failure mode: each one is a wall the agent is standing next to, not a property of the agent itself. The moment the agent finds a hole, it’s on free roam. That hole might be a zero-day in the proxy, a misconfigured seccomp profile, or a sidecar it can bypass. Once it’s out, it has whatever ambient credentials were sitting in its environment, and it can talk to whatever it can reach. There’s no identity gating the next connection, and often no record of what it did after it got out.
A capable agent optimizing hard against a goal is a tireless prober. It will spend inference compute probing the weak points until it finds it. If your security model is “the box holds,” you have already lost the argument the first time the box doesn’t.
Move the boundary into the kernel
The shift we’ve been arguing for since Rethinking Workload Identity at the Kernel Level is this: stop drawing a perimeter around the workload, and make identity, secure transport, and policy properties of every connection it makes. Enforce that in the kernel, on the path every byte already travels.
The difference is structural. A sandbox is optional to how the agent runs: the workload executes, and separately, a wall stands nearby. Kernel-level enforcement is not optional, because there is no “outside the kernel” for a userspace process to escape to and still make a network call. Every outbound connection is a syscall. If identity and policy live at that layer, the agent cannot route around them without leaving the machine entirely. And it can’t leave the machine without going through that same layer.
Three things move into that layer.
1. Identity: every agent gets a real cryptographic identity
An escaped agent is dangerous because it inherits ambient authority: whatever secrets were in env, whatever role the node had assumed. Kill the ambient authority and the escape is far less useful.
We do this with SPIFFE. Every workload gets a short-lived x509 SVID bound to what it actually is, including every ephemeral sub-agent an orchestrator spins up. Not a shared service-account token, not a long-lived key in an environment variable, but a per-workload identity issued and rotated automatically. This is the same model we detailed in Bringing SPIFFE to OAuth for MCP and MCP + Riptides OAuth. The agent presents a verifiable identity for the workload and carries the user and delegation context, so every action has dual accountability: which agent, on whose behalf.
And to be clear about the limitation up front: this doesn’t make an agent safe. A correctly-identified agent can still be told to do something stupid. What it does is make every action attributable and gateable, which is the precondition for everything below.
2. Secure connection: mTLS and credential injection on the wire
Once a workload has an identity, the kernel intercepts its outbound TLS and verifies the identity. It wraps the connection in mTLS and injects the destination credentials onto the wire, so they’re never handed to the process.
This is the part that directly defuses the OpenAI-style escape. In that incident the agent inherited whatever credentials were reachable. In this model, process.env reads nothing. A compromised transitive dependency, or an agent that has broken out of its container, reads an environment with no secrets in it, because the secrets were never there. They exist only on the wire, and only for connections the kernel has already authorized. We covered the mechanics of taking credentials off the runner entirely in Your GitHub Actions Job Deserves a Real Identity. The AI-agent case is the same boundary, applied to a much more adversarial workload.
3. Policy: enforcement from the kernel, not a proxy the agent can dodge
Identity tells you who. Policy decides whether. And the enforcement point matters enormously.
If your policy lives in an egress proxy, the agent’s job is to not use the proxy. If it lives in a sidecar, the job is to route around the sidecar. If it lives in the kernel, on the syscall path, there is nothing to route around. Non-allowed destinations are dropped before a byte leaves the host. In the OpenAI scenario, the agent reached a node with open internet and then dialed out to Hugging Face. That’s exactly the connection a kernel-level egress policy denies at the source, no matter how the agent got to that node.
That’s the whole point of enforcing from the core: breaking out of the container doesn’t hand the agent the network, because the network was never gated by the container.
Every connection through the kernel is a connection you can audit
This is the part we want to underline, because it’s where last week’s post-mortems all converged. The consensus takeaway from the OpenAI incident was that anyone running autonomous agents needs detailed records: prompts, tool calls, credentials, network requests, and policy decisions. Without them, investigators cannot reconstruct why an agent did what it did. When an agent performs thousands of actions, a final benchmark score can’t explain its behavior. You need the full path.
Here’s the thing: if every connection is already going through the kernel for identity and policy, the audit trail is a free byproduct. It’s not a separate logging pipeline you hope the agent didn’t disable. Every authorized connection, every dropped connection, and every credential injection is attributed to a specific SVID and its delegation context, and recorded at the enforcement point itself. Observability, audit, and tracing aren’t a bolt-on. They fall out of the architecture, because the choke point where you enforce is the same one where you observe.
That’s the difference between “we think the agent did X” and “here is every connection this identity opened, in order, with the policy decision on each one.” One of those is a forensic reconstruction. The other is a log.
Why not just run SPIRE for this?
We embrace SPIFFE. We don’t run SPIRE for agents, and the reasons are worse for AI workloads than for anything else. We laid this out in Why Riptides Embraces SPIFFE but not SPIRE.
Agents are ephemeral and spawn dynamically. An orchestrator creates sub-agents on demand to handle tool calls or parallelize work, and they live for seconds. SPIRE requires every workload to be pre-registered with the server before it can be attested and issued an SVID. For dynamic sub-agents, that means either pre-registering every possible variant or racing an automation pipeline to create registration entries as processes spawn. On top of that, SPIRE’s attestation is pull-based: the workload must actively call the Workload API to get its identity. A sub-agent that doesn’t integrate the SDK simply never gets one. And for a process whose entire useful life is shorter than the SVID handshake, that overhead doesn’t pay for itself.
The kernel approach sidesteps all of it. Identity is attested and issued at the layer the workload can’t avoid using, with no code change, no SDK, no sidecar, and no pre-registration dance for every ephemeral agent.
The uncomfortable version
Assume the sandbox fails. Assume the agent, optimizing hard, finds the one weak point. That’s not pessimism. It’s what happened last week to one of the most sophisticated AI labs in the world, with the safeties deliberately down.
The question that actually matters is: what does the agent have the moment it’s out?
- If the answer is “ambient credentials and an open network,” you’re relying on the box, and the box just failed.
- If the answer is “no secrets in its environment, no identity to open a new connection, every destination gated at the kernel, and a full audit trail of everything it tried,” then the escape is a logged, contained event instead of a breach.
Sandboxing tries to make the escape impossible. That’s a bet you will eventually lose. Kernel-level identity, enforcement, and audit make the escape survivable, which is the only property that holds when a capable agent is spending real compute trying to get out.
Build the boundary into the infrastructure the agent can’t step outside of. That’s the kernel.
Riptides gives every workload a SPIFFE identity, whether it’s a human-triggered job, a machine workload, or an autonomous agent. Each one gets in-kernel mTLS with secretless credential injection, kernel-enforced egress policy, and a full audit trail of every connection. No sidecars, no SDK, no secrets in the environment.
Talk to us, or start free and see our approach for yourself.
How exposed are your workloads?
Run the NHI Security Audit Checklist, 8 questions to map your credential exposure, attribution gaps, and lateral movement surface across your own environment. Takes about 15 minutes.
Run the ChecklistFollow us on LinkedIn and X for more updates.