Drift ·
The .gitignore protects your commits. The deploy took the folder.
An $89,000 bill, and the three moments where it could have been stopped.
Earlier this month a developer woke up to a Google Cloud bill for about $89,000. By their own account, a coding agent had deployed their project to Cloudflare Pages, the .env file went with it, and someone found the API key at the public URL and spent it on model calls overnight.
The first instinct is .gitignore. It does not apply. .gitignore decides what goes into a commit. A deploy command such as wrangler pages deploy . uploads a folder, and the folder still has your .env in it. The agent never committed anything. It ran a command people run every day, from the wrong directory.
It helps to split the incident into the three moments where it could have been stopped. They need different tools, and one of them is out of reach for anything that runs on your machine.
1. The key is spent somewhere else
The $89,000 was spent from someone else’s machines, against Google’s API. Nothing on the developer’s laptop, ours included, sees that traffic. The only controls at this point sit with the provider: a budget alert and a hard quota on the project, an API key restricted to the one API and the callers that should use it, and a separate project with a small budget for anything an agent touches. If you do one thing after reading this, do that.
2. The agent asks to publish
The upload itself goes straight from the deploy tool to Cloudflare, not through anything that watches models. But before the upload, the model asked for it. Its next tool call was a shell command, and the shell command named the deploy. That request travels the path between the agent and its model, which is where a monitor can see it without keeping it: recognizing “this is a deploy to a public host” needs the command’s shape, not a copy of it.
The useful alert is not “something happened”. It is “your coding agent just published this folder to Cloudflare Pages; check what was in it and rotate anything that was,” delivered in the minute after the deploy, while the key may still be unspent.
3. The agent reads the key
Coding agents read .env files all the time, often for good reasons, so alerting on every read mostly teaches people to ignore alerts. A tripwire works better: a fake key, shaped exactly like a real one, sitting in the .env next to the real ones. No legitimate task uses it. If it shows up in a prompt, you know the file was read into a model’s context. What a tripwire on your own machine cannot tell you is that a stranger now holds it. That goes back to the provider controls in the first moment.
What we changed
This one was close to home. Writing it up showed us a blind spot of our own: Codex speaks OpenAI’s newer Responses format, and until this week our proxy read tool calls only in the Chat Completions and Anthropic formats, so a Codex agent’s tool calls were invisible to us. That is fixed. The next release also alerts when an agent asks its shell to publish to a public host (Cloudflare Pages, Vercel, Netlify, Firebase, GitHub Pages and a few others), recorded as a fixed label and never as the command, and adds a Google API key tripwire alongside the OpenAI, Anthropic, AWS and GitHub ones.
None of that would have stopped the spend. It would have told the developer, at the moment of the deploy, that the folder had gone public.
The boring fixes matter most
Deploy the build output (dist/, public/), never the project root. Keep production keys out of any directory an agent works in. Put a spending cap on every key an agent can reach. The agent did nothing a tired person has not done. The difference is that it does it at three in the morning, without hesitating, and nobody notices unless something is watching.
Source: the developer’s own posts on X, October 2026. What AariaSec covers, and what it leaves to others: the coverage map.