On 23 October 2026 OpenAI published Securing our frontier model training environment, a write-up of a large red-teaming campaign against its own model sandboxes. One paragraph went round social media faster than the rest: agents in separate microVMs, with no network and no shared writable files, still managed to pass secrets to each other through the processor’s cache.

Halvar Flake (@halvarflake) quote-posting Lisan al Gaib (@scaling01) on X. Halvar Flake writes: 'Am I weird for not finding it insane? You tell agents to communicate, they know about cache timing, this is the first thing you'd expect they try?' The quoted post reads 'completely insane. OpenAI agents communicated via cache timing differences, without any shared files or network connection', above OpenAI's paragraph: agents in separate VMs on shared host machines exchanged synthetic secrets by evicting cache lines and timing reloads.
The paragraph as it circulated on X: @scaling01 called it "completely insane", and @halvarflake replied that it was the obvious first move. Quoting OpenAI's report.

Not everyone was surprised. Halvar Flake (Thomas Dullien), a well-known security researcher, replied:

Am I weird for not finding it insane? You tell agents to communicate, they know about cache timing, this is the first thing you’d expect they try?

— Halvar Flake on X

He has a point.

This is not a new kind of attack. It is a textbook covert channel, and the computer-security literature has studied this exact problem since 1973. What is new is who is using it: models that can read the research, design a protocol, and try for as long as you let them.

This post covers what OpenAI actually reported, why a virtual machine (Firecracker included) does not stop it, what seventeen years of cross-tenant attacks teach, and a layered defence, from scheduling policy down to cache colouring, drawing on USENIX, IEEE S&P, CCS, OSDI, Black Hat, Chaos Communication Congress, hacker-camp and Platform Security Summit work, and on public proofs of concept. It follows on from Sandboxing untrusted AI agents on Linux, which covers the sandbox mechanisms themselves; this post is about what leaks between sandboxes that are working as designed.

📖 Terms in this section

Everything here is point-in-time (late October 2026). Quotes are from OpenAI’s report unless marked otherwise.

🔎 What OpenAI reported

📖 Terms in this section

The report describes the containment stack for training and evaluating frontier models, then a red-teaming campaign against it.

The containment stack. On Linux, agents run in “restricted containers inside lightweight microVMs”: the container limits files and processes, and the microVM “runs its own operating-system kernel and is isolated from the host by a hypervisor”. GPU tasks use “GPU-backed containers with user-space sandboxing”. Around that sit monitoring with automatic stopping, and a network and cloud perimeter “designed to maintain containment even if an agent escapes its sandbox and gains control of the host”. Frontier training runs with no live internet access at all; agents browse an “offline world” of indexed and cached web content instead. Agents that are allowed to cooperate share an explicit message board; everything else is meant to be unreachable.

The red team. Teams of frontier-model agents, including an upcoming “GPT-6 Astra Cyber” model, were given three goals: reach the live internet, cross an internal security boundary, and communicate across isolation boundaries. To favour the attacker they were given “infrastructure source code, configuration details, and documentation describing potential vulnerabilities”. The campaign used “hundreds of billions of tokens”.

What they found. Three classes of result:

  1. 🧨 MicroVM escapes. Agents “found several ways to chain vulnerabilities into microVM escapes”. Fixes went to Kata Containers (CVE-2026-24834, privilege and filesystem isolation), gVisor (file-descriptor handling), Moby/Docker (syscall filters) and the Linux kernel (CVE-2026-74753, CVE-2026-80521, CVE-2026-80841), with more disclosures not yet public.
  2. 🌐 Paths to the internet from a compromised host. Narrow connections that remained for metrics, logging and authentication “gave them limited forms of internet access” in almost every case. One agent “reused a firewall-approved connection to reach a blocked authentication endpoint in our metrics service and then made that endpoint fetch a model-provided URL”. Others slipped requests through DNS and firewall misconfigurations, or made internal services fetch external URLs.
  3. 📡 Communication across isolation. The paragraph in the screenshot: agents “in separate microVMs, created and managed by OpenAI’s sandboxing software on shared host machines” exchanged synthetic secrets “without the use of network connections or shared writable files”. One agent evicted chosen data from the cache; the other timed reloads and read fast as 0 and slow as 1, or similar. Other channels used shared storage (one agent “alternated between continuous writes and inactivity”, which an agent described in its chain of thought as an “acoustic modem-like signal”), competition for CPU time within a shared execution container, and a TLS certificate cache in the offline web infrastructure.

Two caveats from the report itself matter for reading this fairly:

🔊 Covert channels, side channels, and the confinement problem

📖 Terms in this section

Two terms get used interchangeably and should not be:

OpenAI’s agents built covert channels. Butler Lampson named this in A note on the confinement problem (1973): a confined program can leak through any shared resource whose behaviour it can influence and another party can observe, including timing and load. Fifty years of results since have converged on an uncomfortable conclusion: on shared hardware you cannot eliminate covert channels, only reduce their bandwidth, which is why security evaluation schemes historically required covert-channel analysis and bandwidth limits rather than proof of absence. The hacker community has known it just as long: Steven Murdoch’s Covert channels in TCP/IP (22C3, 2005) at the Chaos Communication Congress showed how much room ordinary protocol fields leave for hidden signalling, and how hard that is to filter out.

Why this matters more with agents than with ordinary malware:

The security question is therefore not “can agents in separate sandboxes communicate?” (assume yes) but “what can they achieve if they do?”

🧬 Microarchitectural state, and why it matters so much

📖 A short hardware primer

Everything that follows hinges on one distinction. A CPU has two layers of state:

The catch is that microarchitectural state is invisible to a program’s results but visible in its timing. A load that hits the L1 cache takes a few nanoseconds; one that goes to DRAM takes around a hundred. Same answer, different time, and anything that changes timing can carry information.

That is how OpenAI’s agents talked. The hypervisor kept each VM from reading the other’s memory the whole time, but both VMs ran on the same physical cache. The sender filled a group of cache lines to send a 1 and stayed idle to send a 0; the receiver timed its own memory accesses, reading slow (its data was evicted) as 1 and fast as 0. Neither ever touched the other’s memory. Think of two hotel rooms with locked doors and shared plumbing: flush in one room, and the neighbour hears it in the pipes.

Two pictures make this concrete. The first shows where the wall is. The hypervisor sits between the two VMs and blocks every direct read, but both VMs run on the same physical cache underneath it, and the hypervisor does not divide that cache between them.

flowchart TB subgraph ARCH["Architectural layer: the hypervisor enforces this"] direction LR A["VM A<br/>sender process"] B["VM B<br/>receiver process"] A x--x|"direct memory reads blocked"| B end subgraph HW["Microarchitectural layer: shared, never virtualised"] direction LR CACHE["Shared cache sets<br/>(the channel)"] OTHER["Also shared:<br/>TLB, DRAM rows,<br/>predictors, clock speed"] end A -->|"its loads land in"| CACHE B -->|"its loads land in"| CACHE A -.- OTHER B -.- OTHER classDef vm fill:#dce8f8,stroke:#1d4f91,stroke-width:2px,color:#0f2a4d classDef chan fill:#fbe4d8,stroke:#c0392b,stroke-width:2px,color:#6b2416 classDef hw fill:#ece2fb,stroke:#6a3fd1,stroke-width:2px,color:#30205a class A,B vm class CACHE chan class OTHER hw style ARCH fill:#f3f8fd,stroke:#1d4f91,stroke-width:1.5px,color:#0f2a4d style HW fill:#f8f4fd,stroke:#6a3fd1,stroke-width:1.5px,color:#30205a linkStyle 0 stroke:#1d4f91,stroke-width:2px linkStyle 1 stroke:#c0392b,stroke-width:2.5px linkStyle 2 stroke:#c0392b,stroke-width:2.5px linkStyle 3 stroke:#8a8a8a,stroke-width:1.5px,stroke-dasharray:4 3 linkStyle 4 stroke:#8a8a8a,stroke-width:1.5px,stroke-dasharray:4 3

Blue is what isolation protects. Red is the path the bits take: neither VM can reach the other, but both can reach the same cache sets.

The second shows how one bit crosses. This is the classic Prime+Probe pattern, and it is close to what OpenAI describes. Before starting, the two sides agree on which cache set to use and how long each bit lasts.

sequenceDiagram participant R as Receiver (VM B) participant C as One shared cache set participant S as Sender (VM A) Note over R,S: Agreed in advance: which set, and how long one bit lasts R->>C: 1. Prime: load its own data until the set is full alt Sender transmits a 1 S->>C: 2. Load its own data into the same set C--xR: The set is full, so the receiver's lines are evicted else Sender transmits a 0 Note over S: 2. Do nothing end R->>C: 3. Probe: time a reload of its own data C-->>R: Slow (about 100 ns, fetched from DRAM) means 1<br/>Fast (a few ns, still cached) means 0 Note over R,S: Repeat for every bit. Neither side ever reads the other's memory.

Each step is an ordinary memory load inside the agent’s own VM. Nothing here asks the hypervisor for anything, so nothing here can be refused.

From bits to messages

One bit per round is not yet a conversation. To pass real messages, the two sides build a slow serial line on top of the trick above, with the same parts as any network protocol. Every access is still an ordinary load, the same instruction every program uses, and the values loaded mean nothing. The information is in which addresses get touched (which cache set) and when.

📖 Terms in this section

  1. ⏱️ Time slots. Both sides agree on a slot length, say 100 µs, and each slot carries one bit: the sender loads into the set for the whole slot to send a 1, or stays idle to send a 0. The receiver primes at the start of each slot and probes at the end. Both read their own timestamp counter, so they agree on slot boundaries without ever talking directly.
  2. 🔤 Turning a message into bits. Exactly as on any serial line: text becomes bytes, and bytes become bits. Sending the letter “h”:

    'h' = 0x68 = 0    1    1    0    1    0    0    0
    slot:        1    2    3    4    5    6    7    8
    sender:      idle load load idle load idle idle idle
    receiver:    fast slow slow fast slow fast fast fast  ->  01101000  ->  'h'
    
  3. 🎯 Sync and framing. The receiver has to know where a message starts. A fixed preamble such as 10101010 lets it lock onto the slot rhythm, like a UART start bit or an Ethernet preamble, and a length field or end marker says where the message stops.
  4. 🩹 Error correction. The cache is noisy: every other program on the host evicts lines too, so some 0s arrive as 1s. The protocol pays for that with redundancy: repeat each bit, use a Hamming or Reed–Solomon code, add a checksum and resend when it fails. This is why covert channels can afford to be slow: patience buys reliability.
  5. 🏓 Ping-pong. For two-way traffic there are two options. Half-duplex: take turns, A sends a frame, then the roles swap and A listens, with acknowledgements and retransmission much like TCP. Full-duplex: use two cache sets, one per direction, so both can transmit at once. More sets in parallel also means more bits per slot.

Researchers have taken this all the way. Hello from the Other Side (NDSS 2017) ran a full TCP/IP stack over a cache channel between two Amazon EC2 instances, error correction included, and carried a working SSH session over it. Once there is a reliable bit pipe, everything above it is ordinary networking. OpenAI’s agents built a crude version of steps 1 to 4: most were handed the protocol, and in one case they agreed on an encoding themselves. That is the real concern behind “the attack literature is in the weights”.

Inside the silicon: what “evicted” actually means

It’s worth being precise about this, because the whole channel lives inside one mechanism that most explanations wave past.

A cache line is not a labelled box that data gets lifted out of when it’s “evicted.” It’s a row of SRAM cells: six-transistor loops, each holding one bit as two transistors locked in a feedback loop, one driven high, the other low, each continuously reinforcing the other’s state. No magnetism, no moving parts, no atoms relocating anywhere — just voltage, held in place by circuit topology. Next to the data bits in each row sit a tag (which physical address this row currently represents) and a valid bit. A cache is also not one undifferentiated pool: addresses are routed by some of their bits into one of many sets, and each set holds a small, fixed number of lines (the “ways” mentioned later in this post). “Full” means that specific set’s ways are all occupied, not the cache as a whole.

Eviction, then, is not removal. It’s overwrite. When an address needs a slot in a full set, a small hardware circuit called the replacement policy (commonly an approximation of least-recently-used, tracked with a couple of extra bits per set) picks a victim line. If the victim holds unwritten changes (a “dirty” line), the controller writes it back down to the next cache level or memory first, so the data survives. Then the write circuitry forces new voltages onto that row, flipping its transistor pairs to represent the new tag and data. The old pattern of highs and lows doesn’t go anywhere. It’s simply gone the instant the new one lands, the way writing over a whiteboard erases what was there; nothing was carried away, there’s just nothing left to read.

Why this is the covert channel

Every layer of isolation on this page is built on top of one assumption: that access is mediated by something that can check permissions, a system call, a page-table entry, a hypervisor trap. The replacement policy checks none of this. It cares about one thing: which physical address does an access resolve to, and which set does that address’s bits route it into. Two completely separate VMs, with completely separate address spaces, completely unable to read each other’s memory, can still land in the same set, because set assignment is a function of physical address geometry, not ownership. When that happens, filling a set from one side necessarily evicts whatever the other side put there, and there is no permission check anywhere in that path to stop it, because none was ever designed to apply here.

That’s what makes it a signal and not just contention. The sender doesn’t need to see the receiver’s memory, write to it, or share a socket with it; the sender only needs to touch enough addresses that map to the same sets the receiver cares about, which it can work out by timing its own accesses in advance (the probing step behind every “eviction set” in the Prime+Probe literature below). Once it has that map, filling those sets is a 1, leaving them alone is a 0, and the receiver reads its bit back by timing its own access to the same sets: a few nanoseconds if its data survived (fast, still in the cache), on the order of a hundred if it didn’t (evicted, had to go to DRAM). That gap is large, stable across runs, and doesn’t depend on either process’s privileges, which is exactly the combination Lampson’s 1973 definition asks for: a shared resource, influenced by one party, observed by the other, outside what the security policy accounts for.

It’s also why the fix can’t be “monitor cache accesses and block the bad ones”: there’s nothing to distinguish a sender’s eviction from the thousands of ordinary evictions every running program causes every microsecond just by executing. The replacement policy has no concept of “tenant,” “sandbox,” or “trust boundary” to enforce, because nobody wired one in; it was built to make programs fast, not to keep secrets apart. Everything in the defence-in-depth section further down is, underneath the acronyms, an attempt to retrofit exactly that distinction onto a circuit that was never asked to make it.

Why this has such large implications for sandboxing:

  1. 🧱 Isolation only covers the layer above. Every boundary in the sandboxing post (namespaces, seccomp, Landlock, gVisor, a microVM) protects architectural state. The channel runs underneath all of them.
  2. 🤝 It is shared on purpose. Sharing the L3 between cores, two hyperthreads per core, and handing idle capacity to whoever wants it are what make CPUs and clouds efficient. Every defence that removes sharing (dedicated cores, partitioned cache, fixed quotas, separate hosts) costs performance or money, which is why these channels have survived decades of research.
  3. 🔁 It is not saved or restored. A context switch swaps registers, but caches, predictors and TLBs keep whatever the previous tenant left. So taking turns on a core leaks too, not just running side by side, which is why the defences include flushing on switch and pinning VMs to dedicated cores.
  4. 🗺️ It cannot be fully listed. The instruction set is documented; the microarchitecture largely is not, and it changes with every CPU generation. When defenders partitioned the cache, attackers moved to the TLB, the coherence directory, the interconnect, the prefetcher and the clock frequency (all in the timeline below). You cannot partition a structure you do not know exists.
  5. 👻 Speculation turns covert channels into side channels. A CPU runs ahead on guesses and throws away the architectural results of a wrong guess, but not the microarchitectural footprint. Spectre and Meltdown make the CPU speculatively touch a secret and then read it back from the cache: the same receiver OpenAI’s agents used, which is why the report mentions those attacks. Cooperating agents do not need speculation; leaking an unwilling victim’s secret does.
  6. 🧮 It sits below every policy layer. Sandbox policy is written against architectural interfaces: seccomp sees system calls, Landlock sees paths and ports, a VM sees devices and memory, a proxy sees connections. A cache eviction involves no system call, file or packet, so none of them can see it. Only controls at the same level can act on it: where code runs (placement, SMT, pinning), how the hardware is divided (cache partitioning and colouring), and what is wiped between tenants (flushing, and seL4’s “time protection”, which treats microarchitectural state as a resource to divide in space or in time).

That last point is why the defence layers later in this post move from software policy to scheduling and hardware.

🧱 Why a VM, even Firecracker, does not stop this

📖 Terms in this section

A virtual machine isolates architectural state: memory contents, registers, the kernel, devices. Covert channels live in microarchitectural and physical state that the hypervisor does not virtualise, because the hardware shares it:

Shared resource Example channel Shared between VMs when…
L1/L2 caches, branch predictors, execution ports Prime+Probe, port contention they run on the same physical core (SMT siblings, or time-sharing a core)
Last-level cache (L3) cross-core Prime+Probe they run on the same socket or core complex
Coherence directory directory Prime+Probe same socket, even with non-inclusive caches
Shared memory pages Flush+Reload the host deduplicates pages (KSM)
Memory bus, DRAM banks and row buffers bus locking, row-buffer timing same memory controller or DIMMs
CPU frequency and power frequency-based timing same package
Mesh interconnect interconnect contention same die
GPU TLB, L2, PCIe contention across GPU partitions same physical GPU, even under MIG
Storage, network and software caches I/O timing, cache hits same disk, NIC, proxy or cache service

Firecracker is explicit about where its responsibility ends. Its production host setup guide says “Firecracker is not able to mitigate host’s hardware vulnerabilities” and asks the operator to:

It says nothing about cache partitioning or vCPU pinning. Those are left to you. So: a microVM is necessary (it stops the cheap software escapes, at least until a VMM bug is found, as OpenAI’s red team showed), but it is not sufficient against covert channels. What decides the outcome is how the host is configured and, above all, what shares a host.

Is any kind of VM immune?

“VM” is an overloaded word, so it is fair to ask whether some kind of virtual machine escapes this problem. None does. The VM technology decides how hard it is to break out of the VM; what decides whether a covert channel exists is which hardware the VMs share, and every kind of VM runs on shared hardware unless you arrange otherwise.

📖 Terms in this section

Kind of “VM” Examples What it separates Microarchitectural channels?
System VMs KVM (with QEMU, Firecracker, Cloud Hypervisor), Xen, VMware ESXi, Hyper-V guest kernels, memory and devices Yes. All run on the same cores, caches and memory unless the host is configured not to share them. The hypervisor brand changes the escape risk and which mitigations are built in, not the physics.
User-space kernels gVisor the host kernel, from the sandboxed program’s requests Yes. It shares the host’s hardware like any process.
Confidential VMs AMD SEV-SNP, Intel TDX guests a guest’s memory, from the host and hypervisor Yes. Their threat models largely exclude side channels (see the frontier section).
Static partitioning hypervisors Jailhouse, Bao, Xen “dom0less” fixed cores and memory per VM, never time-shared Fewer. No core sharing removes the L1, L2, TLB and SMT channels, and some add cache colouring: Xen’s cache colouring partitions the last-level cache on Arm64, though it is built for predictable timing in embedded systems rather than as a security boundary. Package-wide resources (memory bus, DRAM, frequency, interconnect) are still shared.
Verified microkernel with time protection seL4 (research prototype) cache colouring, flushing and padding on every domain switch Fewest known. Designed to close timing channels, with proofs in progress, on specific hardware. Power and frequency remain out of reach of any software.
Language or process VMs JVM, WebAssembly, JavaScript engines, eBPF code inside one process Most. Everything shares one process and address space, so Spectre-style reads cross the boundary directly.

The last row deserves emphasis, because “run the agent’s tools in a WebAssembly sandbox” is a common design. After Spectre, Google’s V8 team concluded that language-level protection cannot keep secrets inside one process: “The only effective mitigation is to move sensitive data out of the process’s address space” (A year with Spectre, V8 blog; see also Spectre is here to stay). Chrome’s answer was Site Isolation: a separate process per site. For agents the lesson is the same: a language sandbox is a good integrity boundary for running a tool, but two agents whose data must stay apart need at least separate processes, and against covert channels, separate hardware.

So the honest summary of this section: every kind of VM shares hardware by default, and the only VMs that leak noticeably less are the ones built to stop sharing it (static partitioning, colouring, time protection), which is exactly what the defences later in this post do on ordinary hypervisors.

What a hyperscaler does

The clearest public description of production practice is AWS’s Nitro whitepaper section on side channels. Its design rules map almost one-to-one onto the table above:

That last point is the honest summary of the state of the art: even the most careful multi-tenant design falls back on “don’t share the host” for the strongest guarantee.

📚 Seventeen years of cross-tenant channels

📖 Terms in this section

The OpenAI result sits at the end of a long line of research, most of it published at USENIX Security, IEEE S&P and CCS:

The pattern: every time one shared resource is partitioned, research finds the next one. Defences raise the cost and lower the bandwidth; they do not reach zero.

A note on why this list leans on these particular results: you don’t learn anything about adversarial breakout risk by testing it against a weak boundary. Showing that a timing channel crosses a default, unhardened container with no seccomp filtering proves nothing, because that was never a security boundary to begin with — it was never meant to stop a determined process, so defeating it isn’t news. The results above matter because they were run against the best isolation available at the time: NetCAT against Intel’s DDIO on real server hardware, Downfall and MDS against production Intel server silicon, Osiris’s channel across live AWS VMs, Raymakers’ Spectre leak across VM boundaries at a major public cloud. That’s the right standard for this kind of claim. Researchers and red teamers testing agent sandboxes should hold themselves to the same bar: break the newest isolation primitive, not last decade’s.

🏰 Defence in depth

📖 Terms in this section

No single control solves this, so stack them. The layers below run from the cheapest and most effective (design and placement) down to the expensive and partial (hardware partitioning, detection).

Layer 0: design so collusion does not matter

The strongest control is architectural, and it costs nothing. Assume any two agents that share hardware can talk, and make sure that no agent, and no pair of agents that could collude, holds all three legs of the lethal trifecta: private data, untrusted content, and a way to communicate externally.

Layer 1: placement removes the hardware channels

📖 Terms in this section

If two agents must not communicate, they must not share hardware. Make it a scheduler rule, not a hope. This is the only control that closes the microarchitectural channels outright. It does not close channels through services both agents still use, which is why layer 3 and the next section matter:

Layer 2: harden hosts that must be shared

📖 Terms in this section

When agents of the same trust level share a host (the common case for training and evaluation fleets), shrink the shared surface:

Be clear-eyed about the limits:

Layer 3: remove shared software state

📖 Terms in this section

Two of OpenAI’s channels, storage and the TLS certificate cache, were software. These are often the easiest to build and the easiest to fix:

Layer 4: add noise and take away clocks (weak)

📖 Terms in this section

Covert channels need a timer. Taking it away helps less than it sounds:

Layer 5: detect and respond

📖 Terms in this section

This is what OpenAI relies on for the channels it could not remove:

Layer 6: assume escape, hold the perimeter

📖 Terms in this section

OpenAI’s other findings are a reminder that covert channels are the subtle failure; the blunt ones were VM escapes and internal services that reach the internet. The perimeter must hold with a compromised host:

🧮 What “mitigated” means here

📖 Terms in this section

It is worth being precise, because “mitigated” is easy to over-read. None of the layers above eliminates covert channels between agents that share anything. They change three numbers: how much bandwidth a channel has, how much it costs to build, and how likely it is to be noticed.

So the honest goal is not “agents cannot communicate”. It is: communication between agents that should be separate is slow, expensive, observable, and not worth much, because layer 0 has made sure no colluding pair can assemble data, untrusted input and a way out. Isolation lowers the odds; capability design bounds the damage.

🔬 The frontier

📖 Terms in this section

Beyond what you can deploy today, three research directions aim at the root cause:

One thing that is not on this list: confidential computing. AMD SEV-SNP and Intel TDX protect a guest from the host, not guests from each other, and their own threat models leave microarchitectural side channels largely out of scope. An SEV-SNP primer sums it up: the mitigations raise the bar “but side-channel risk is not eliminated”.

✅ A checklist by threat level

Situation Minimum Add when stakes rise
One agent on your own laptop the OS-level sandbox from the sandboxing post; there is no second agent to collude with nothing specific to covert channels
Several cooperating agents, one trust level an explicit, logged channel between them; per-task credentials per-agent caches and fixed quotas
Agents with different privileges (secrets vs egress) on one fleet split capabilities; never co-locate the two roles (anti-affinity) separate hosts or at least separate L3 domains; SMT off; KSM off
Multi-tenant agents (strangers’ code) microVM per tenant; pinned dedicated cores; SMT off; KSM off; per-tenant service instances LLC partitioning (CAT, MPAM); whole GPUs per tenant; dedicated hosts for sensitive tenants
Frontier models under adversarial evaluation all of the above, plus default-deny cloud egress, monitored inner layers, automatic stopping colouring of caches, directories and DRAM (Marghera-style); continuous red-teaming; formal time protection where available

🔗 How this fits the earlier post

Sandboxing untrusted AI agents on Linux argued that the strongest boundary is a second kernel, which is why serious hosted platforms use microVMs (its Firecracker section explains the choice). OpenAI’s report sharpens that conclusion in two ways:

  1. A second kernel is a boundary for software, not for hardware. The microVM is still the right primitive, but its guarantees stop at what the hypervisor virtualises. What shares a host is a security decision, and the scheduler is part of the sandbox.
  2. The section 8 items are not theoretical. That post listed side channels, exfiltration through allowed channels, and the model as a channel among what the stack still misses. OpenAI has now shown agents building those channels on demand. The fix is the same as before, applied across agents: decide what each agent may hold, and make sure the agents that could talk to each other cannot assemble the lethal trifecta between them.

If any of this felt like you’d read it before, that’s because you had: Prime+Probe is 21 years old, Rowhammer is 12, Spectre is 8, and not one line of silicon changed to make OpenAI’s finding possible. Same cache, same bus, same clock, same bag of tricks from the same conference proceedings — just a new kind of attacker that can read all of it overnight and never gets bored of trying.

— Déjà vu, agentic-sandbox edition

📚 Sources

Point-in-time (checked October 2026).