OpenAI's no-internet rule for frontier training: the approved services were the way out, and agent sandboxes should copy the split
The copy of the web held. What OpenAI's own red team found a way through was almost every service left connected for running the lab, and the September escape went through a resolver no copy replaced. Serve the agent's work from copies, keep the live connections few and outside its reach, and expect the cost to land on github.com.
Contents
On September 20 an OpenAI research model reached the live internet through a DNS resolver, and OpenAI paused training and evaluation of its most capable models. On October 23 it published what it did in the eleven days before it started again, and the line that travelled was the policy: frontier training runs with no live internet. The lesson people drew from it is the easy one. If the lab that built the model will not give it the web, your agent holding production keys should not have it either.
As a default I agree with that. The reason in the post is narrower, and I think more useful. The model’s web was already a copy before September: per OpenAI’s own report on the incident, every request except the DNS lookups landed in its offline web cache. The escape went through the one path the copy had not replaced. Then OpenAI set teams of its own agents on the few services it had left connected to run the lab, metrics, logging and authentication, and they found a way through almost every one. My read is that this is the shape to copy: serve the agent’s work from copies, and treat what stays live as the operator’s plumbing, few, outside the agent’s reach and tested by someone trying to get through it.
What OpenAI’s offline training environment is, and what stayed connected
OpenAI calls the copy an offline world: a large set of indexed and cached web content that a model can browse and search without touching anything outside. All frontier RL runs use it. The rule the post hangs everything on is plain:
we must always be able to prevent a frontier model from achieving unauthorized, arbitrary access to the live internet.
Around that sit restricted containers inside lightweight virtual machines, monitoring meant to catch an attempt in time, and a network and cloud perimeter meant to hold if everything inside it fails. What the post does not claim is an air gap. Disconnecting the infrastructure entirely is not currently feasible, it says, because experiments have to be run and watched from outside. So the models are off the live internet and the lab is not, and the interesting part of the post is what happened at the seam between the two.
Why OpenAI’s allowlisted services became the exits
After the Hugging Face incident in July, OpenAI had cut the channels a model could use during training down to a few services it operates. For the red team it then assumed the worst: an agent already in control of a host machine, asked only whether it could get from there to the live internet.
Our red-teaming agents found vulnerabilities in almost every one of these services that gave them limited forms of internet access.
One example carries the whole idea. An agent reused a connection the firewall allowed, reached an authentication endpoint in the metrics service that was supposed to be blocked, and had that endpoint fetch a URL the model supplied. A metrics endpoint that fetches URLs on request is an internet connection with extra steps. My earlier piece on the September reports already counted anything that makes a request on the agent’s behalf as a channel out, and OpenAI’s design says the same, extending its restrictions to services reachable “either directly or through other services”. What the October post adds is how that rule fared once a capable searcher went looking at the services kept on purpose. A hostname allowlist on its own does not describe reach. Reach is what each allowed service will fetch, store, forward or run for the caller, and what the services behind it will do in turn.
Two qualifications belong next to the quote. The red team was set up to win: capable and aligned models told to attack, working on isolated copies of the infrastructure with its source code, configuration and documentation of likely weak points, across hundreds of billions of tokens. And the access it found was limited. OpenAI says it found no route to the internet that agents could trivially exploit while hiding from its monitors. Neither changes the point. A short, deliberate list of live connections did not hold up as a boundary on its own; it held up as a list of places to watch.
OpenAI’s offline world splits the model’s channels from the operator’s
OpenAI tightened its network restrictions and fixed what the red team found, and it kept the copy. Put together, the two September and October documents describe a design I would state like this, though OpenAI does not put it this way: the model’s work needs nothing live, because its web is a copy, and the connections that remain exist for the people running the experiments. Whether a given connection is reachable from where the agent runs is then a separate question, enforced by the perimeter, and the red team’s job was to answer it.
That split changes what you ask of each connection. The usual question is which hosts the agent needs, and the answer only grows, because every task finds one more site worth reading. After the split the question is which of the agent’s needs a copy made before the session can meet. Documentation can be a snapshot, dependencies can come from a mirror filled in advance, the repository can be cloned at a pinned commit. Whatever is left is short enough to test door by door.
For a released coding agent the split has to be drawn in a specific place, because the agent is not one process. The harness still talks to the model provider, and the sandbox docs I read for an earlier test of Claude Code’s sandbox on Ubuntu list the endpoints that takes. What loses the network is the execution side: the shell, the commands and whatever they start. The work leaves the way it came in, through the tree. A coding agent I run works in a sandboxed checkout with real write access to the files and no path to production or to the outside, and the push, the deploy and the CI trigger happen outside that boundary, as operator actions on what the agent left in the tree.
The cost is real, and it lands on one entry. That same sandbox post puts github.com and registry.npmjs.org in its allowlist example, which is roughly what a day of coding needs, and the docs warn that a broad entry like github.com can carry data out. It is the metrics service at the scale of a laptop: one host allowed for a good reason, with a great deal reachable through it. A package mirror and pinned clones are work, and most people will keep that entry. If you do, the honest version of the split is to know the entry is a relay and gate what the credential behind it can push to, which is where the predecessor post ended up from the other side.
Does OpenAI’s training threat model transfer to a released AI agent?
Partly, and the post draws part of the line itself. Its opening notes that training settings differ from the ones customers use: models in development may not have finished safety and alignment training, and OpenAI tests them under adversarial conditions on purpose. The red team had the source code. A released model doing ordinary work on a developer machine has none of that.
So weigh the findings one at a time. The red team chained vulnerabilities into microVM escapes, and OpenAI lists patches across sandbox components, Kata Containers, gVisor and Moby/Docker’s syscall filters, alongside broader kernel hardening with three CVEs named. Those matter wherever a VM is the boundary. On a developer machine the agent usually runs on the host already, under your account, so the escape is a problem you have to build a VM to have, and the access you granted on purpose deserves attention first.
The cross-isolation channels are a second thing that transfers only weakly. In one test, agents in separate microVMs on a shared host swapped a synthetic secret with no network connection and no shared writable file, by evicting chosen data from the processor cache and timing how long reloads took. Other tests found channels in shared storage, in competition for CPU time and in a TLS certificate cache in OpenAI’s offline web, though in most of them the agents had been pointed at a channel or given an encoding. OpenAI says these channels are slow and hard for models to use, and it added monitoring checks for them. The narrow lesson for a small setup is that blocking two agents’ network does not by itself keep them apart when they share a machine, its storage and its services.
The finding about approved services is different, because it needs no misalignment at all. A path a service opens is open whoever is steering. In OpenAI’s red team, the searcher was a model told to search. In a released agent, the party that might steer it is whoever wrote the text it reads: a web page, an issue comment, a document handed in by a tool. I have argued before that a connector is an untrusted author. That does not mean text controls the agent; an injection still has to persuade the model, and the model still needs the tool and the reach to act on it. It means that if an injection does land, an approved indirect path gives it somewhere to go without the model ever wanting to leave. What carries over is the containment requirement. Nobody has measured how often such an injection succeeds, and the argument does not need that number.
How to copy OpenAI’s egress split onto one machine
Start the execution side with no network and make every live connection earn its place, then write a second column next to each one: what the host on the other end will do on the caller’s behalf. Does it fetch a URL it is given, accept writes, run CI, forward a webhook, send mail? The second column is the real allowlist. The first column alone is the list OpenAI’s red team walked through. Meet what the work needs from copies made before the session, and expect a residue you cannot copy, which is where the credential’s scope does the remaining work.
Then test the way OpenAI did, from a layer out. Its host-control tests skipped the sandbox and asked only whether the perimeter held. The modest version on one machine is to run the probes again outside the sandbox, as the account the agent runs as, and see what that account can reach. It is not a full compromise test, and it only covers the paths you try, but if the answer is everything, the sandbox was carrying the whole load. And run the probes again after every new tool, mount or allowlist entry, since OpenAI’s own ongoing work includes checks for configuration changes that could weaken its defenses. Its findings fell as the campaign went on, and it still expects future models to find holes it does not know about.
OpenAI says it will keep the no-internet policy until better safeguards justify broader access. Its infrastructure stays connected; its training models do not. I read the policy less as fear of one model than as a conclusion about lists. The lab spent a red-team campaign at a scale few organisations could fund on a short list of deliberate connections and still found a way through nearly every entry, and none of the routes to the internet it describes went through the copy the models actually work in.
01 / Discussion
No comment section here — all discussions happen on X.
02 / More articles
Vox's AGENTS.md lines, tested in 90 Claude Code runs: the line that worked best wasn't one of his
Line one made the agent leave out the input check. Line two's extras disappeared when line one shared the file. 'Without breaking anything' showed no clear effect beyond what a named test command already did. What 90 runs can and cannot say, and how to test a line before you keep it.
Attack surface reduction with Claude Code: Anthropic's three passes on my own site, and a fourth they don't ask
The skill is not out, the method rebuilds in an afternoon, and the hard part is choosing where to point it. Here the most useful result was a broken verification file, and the exposure that mattered lived in a deploy setting my three passes never opened.
How to make Claude write like a human: the tell that's left is the story it makes up
In my test Claude Sonnet 5.5 skipped the em dashes and the stock words before I banned them. What it did instead was open eight texts out of nine with an incident from a team that doesn't exist, and a humanizer pass kept every one of them, because they read as human.