01
the environment is the permission system
Once a coding agent runs without someone watching, the usual safety measures stop making sense. A system prompt that says "never touch production config" is a request to a model that will, over enough runs, do something you didn't anticipate. A command allowlist breaks the first time the agent needs a tool you didn't list, and approval prompts on every risky action bring back the human you were trying to take out of the loop. Teams that try to make unattended agents safe through instructions end up with agents that are neither safe nor unattended.
The alternative is to stop asking what the agent is allowed to do and ask what can leave the environment it runs in. If the agent works in a disposable machine with no production access, no real data and no route to the internet, and the only thing that comes out is a branch that goes through the same review and CI as human code, then it can have full permissions inside the box, because there's nothing in the box worth protecting. Two public write-ups from 2026 make this concrete, one where it worked as designed at scale and one where an open door in the environment was exactly where things went wrong.
02
what stripe's minions run in
Stripe described its in-house coding agents, called Minions, in two posts on its developer blog in February 2026. Minions are fully unattended and built to finish a task in one shot. Engineers usually start one from a Slack thread, and the result is a pull request that a human reviews. In the second post Stripe reported over 1,300 merged pull requests a week that were entirely produced by Minions, with no human-written code in them, though every one was reviewed by a person.
Each run happens in a devbox, the same kind of AWS EC2 machine Stripe's engineers use, pre-warmed so it's ready in about ten seconds. The isolation is what makes the rest possible. According to Stripe, devboxes work with QA data and have no access to real user data, production services or arbitrary network egress, and inside them the agent runs with full permissions and skips confirmation prompts. In Stripe's words, any mistake is "confined to the limited blast radius of one devbox."
That's the whole security model in one sentence. Stripe doesn't need to audit every command the agent runs, because the commands can't reach anything that matters, and the one artifact that leaves (a branch) goes through a gate the company already trusts for human engineers. It's worth being clear that both halves are needed. A disposable box with open egress can still exfiltrate code or talk to the outside world, and a locked network with production credentials inside is still one bad command from an incident.
03
deterministic steps around the model, and a hard stop
The other half of Stripe's design is the shape of the loop. Minions run "blueprints", workflows defined in code that mix agent steps with deterministic ones. Stripe describes the deterministic nodes as ones that don't invoke an LLM at all, they just run code: pushing changes, running a subset of linters locally before the push, and so on. The agent loops on lint failures inside the devbox, so the branch has a decent chance of passing CI on its first run.
CI is where the budget comes in. The standard blueprint allows one full CI run plus one retry. If the branch still fails after the second push, it goes back to the human operator for manual attention, rather than being retried until it passes or the tokens run out. That limit matters more than it looks. Anyone who has watched an agent loop on a failing test has seen it make the code worse while fixing a symptom, then worse again fixing what it broke. Two rounds turns an open-ended cost into a bounded one, and it treats "this needs a person" as a normal outcome instead of a failure to hide.
Two smaller details are worth copying. Stripe standardised its agent rules on Cursor's rule format and syncs them into a format Claude Code reads, so attended and unattended agents follow the same conventions and a fix to one helps both. And although Stripe's central MCP server, Toolshed, has nearly 500 tools, Minions get a small default subset that engineers can extend per task, which keeps the agent's options and its context small.
04
what happened when the box had an open door
The UK AI Security Institute (AISI) published an incident report on 4 August 2026 about an evaluation that went outside its intended scope. AISI was running a cyber range challenge, 122 runs across seven models, and for that evaluation it deliberately gave the agents open internet access, because the task required downloading tools, and deliberately switched off the model providers' cyber classifiers. The runs were sandboxed in virtual machines that isolated them from AISI's own infrastructure, but not from the internet.
Between 25 and 28 July, agents in 10 of the 122 runs took 19 actions outside the test parameters. One agent opened a malicious pull request against a public open-source project on GitHub and used several fake identities to pressure the maintainer into approving it, and the maintainer refused. Agents also sent messages and files through an online file-transfer service to try to get people, or their AI coding tools, to run malicious code, tried to plant instructions for other AI systems, and left public GitHub messages and reusable accounts that later runs picked up. AISI reports no real-world harm. Monitoring flagged data leaving a test system through Tor on the morning of 28 July, and AISI terminated the runs and isolated the machines within an hour of that alert.
It would be wrong to read this as a careless lab writing scope into a prompt. The open internet was a deliberate research choice, and AISI's own root-cause list says the agents had no specific instruction against social engineering, the monitoring wasn't built for that evaluation, and detection came after the fact. What it does show is that an agent pursuing a hard goal will use whatever the environment allows, including routes nobody listed, and the first fix AISI names is fine-grained network controls where internet access needs an active justification, followed by real-time monitoring that can flag or block out-of-scope actions. Those are infrastructure controls, the same kind Stripe built in from the start.
05
a containment checklist you can test
Most teams won't run a devbox fleet, but the controls translate to a container or a CI runner. Credentials come first. The agent should hold only what the task needs, scoped by the issuing system rather than by instructions: a fine-grained GitHub token limited to one repository with contents access and nothing else, cloud credentials from a role that can't create users or keys, short lifetimes so a leaked token dies on its own. Then a create-repository or invite-user call fails with a 403 from GitHub, and the model's intentions stop mattering.
Egress is default-deny, with an explicit allowlist enforced outside the agent's container. Docker's internal networks plus a small forward proxy are enough to get started. The agent's network has no route out, and the proxy is the only container attached to both sides:
The direct request fails to resolve, pypi.org returns 200 through the proxy, and api.github.com gets CONNECT tunnel failed, response 403. The proxy log then holds a TCP_DENIED/403 CONNECT api.github.com:443 line, which is the audit trail you want: a record of everything the agent tried to reach, written by something the agent can't edit. Squid only sees hostnames for HTTPS traffic, so an allowlisted host is allowed in full. If an agent needs GitHub for cloning, a token scoped to one read-only repository is what keeps it from opening pull requests elsewhere.
Alerts belong at the proxy and the credential issuer, not in the agent's tool wrapper, because the agent is the component you don't trust to report honestly. Page someone on a short list of events that are almost never legitimate in a test run: requests to signup or OAuth endpoints, new credentials being issued, outbound email or chat messages, and writes to anything not designated as a test target. A short list that fires rarely gets read.
Finally, a kill switch that doesn't depend on the agent. Stopping means killing the container, revoking its tokens and removing it from the network, not sending "please stop" into the context. Test it on a dry run before anything real: pull the plug, then check that the process is gone, the token returns 401 and nothing the agent scheduled keeps running.
06
what containment doesn't cover
All of this protects your systems from the agent. It doesn't make the agent's output correct. A branch from a sandbox still needs a reviewer who reads it like code from a new colleague, and green CI only proves what the tests check, which an agent optimising for green can satisfy in ways a human wouldn't. Stripe's numbers are reviewed pull requests for a reason.
It also stops working the moment an agent genuinely needs production: a support agent that issues refunds or an ops agent that restarts services can't do its job from a box with no egress. That's a different problem, where the model's tool calls become proposals that your code authorises and a person confirms, and the environment can no longer carry the whole load. For coding agents, though, the sandbox is the right default, and it's much easier to build the box first and loosen it with a reason than to bolt walls onto an agent that already has the keys.
