The key had too many homes
Wiz counts at least nine AI developer platforms that disclosed breaches in October, most of them traced to credential access, with attackers going after stored environment variables that hold AI keys. The latest, Northflank, told customers on October 30 to assume every environment variable had been decrypted, and users reported their AI keys being used within hours. In Bromure Agentic Coding, the key your agent codes with lives in one place on your Mac, the agent can't copy it onto a platform, and rotating it takes one paste.
Every platform you paste an AI key into keeps a copy of it. In October, attackers went after those copies at nine platforms, and Wiz saw stolen keys tested within 30 minutes.
On October 30 at 11:43 UTC, Wiz alerted Northflank, a cloud platform for deploying apps, databases and AI workloads, to a breach. About two hours later, Northflank's status page told every customer: "Assume all environment variables have been decrypted. Disable/rotate all keys." At 15:12 it added: "Multiple users are confirming that their AI keys have been used." The last update of the day, at 23:38, said: "Users have reported unauthorised use of AI API keys supplied to the Northflank platform." BleepingComputer reports that Northflank hasn't said how the attackers got in or how many customers were affected.
Northflank wasn't the first. The same day, Wiz researchers Benjamin Read and Rami McCarthy published Black October for AI Developer Platforms, which counts at least nine AI developer platforms that disclosed security incidents during the month. "Any other month, and this would be the top security story," they write.
Nine platforms in one month
Wiz's list, in order:
| Date | Platform | What the disclosure says |
|---|---|---|
| Oct 6 | Fireworks AI | Credential access; signs of an "agent swarm" attack |
| Oct 9 | Andromeda | Part of an "industry-wide attack" |
| Oct 14 | Zeabur | Credential access; the company is shutting down |
| Oct 15 | Lightning AI | Credential access |
| Oct 16–17 | OpenCode | A "legacy system"; stored provider keys exposed |
| Oct 20 | Railway | "Privilege escalation in our build infrastructure" |
| Oct 23 | Warp | A third-party vendor; agent traces taken |
| Oct 28 | CommandCode | Attributed to distillation |
| Oct 30 | Northflank | Environment variables assumed decrypted |
Wiz found no single vulnerability or dependency behind all nine. They share a target. Most of the incidents trace back to credential access, and the attackers went looking for stored environment variables, "especially those granting AI access." OpenCode and CommandCode blamed distillation, where stolen access to frontier models trains cheaper ones. Wiz ties the rest of the demand to the resale market it calls LLMJacking: stolen keys sold as discounted model access.
Tested in thirty minutes, resold by the million
Wiz also traced what happened to two sets of stolen enterprise credentials used for Amazon Bedrock. Wiz couldn't tie either case to a specific platform breach, but the pattern explains why AI keys are worth hunting:
- Within 30 minutes of the reported credential access, one
InvokeModelcall from a residential IP tested the keys. It asked for Claude Fable 5.1, failed, and fell back to Opus 5.5, which worked. - A small Go client then checked the keys 14 to 120 times a day to make sure they still worked.
- A
boto3script enumerated Bedrock and EC2 quotas. The same script, down to its version string, showed up in both cases. - After that came the bulk traffic. Case A made about 800,000 Bedrock calls in roughly 30 hours, about 90% of them successful. Case B made about 1.7 million calls in roughly 13 hours, over a million successful.
Wiz estimates the two cases "likely ran up over $100k in usage" at list price. The token patterns looked like resold coding-agent traffic: prompt caching and many end users behind one reseller. Wiz links infrastructure that touched the keys to LLM resale sites, including one that takes payment in USDT.
That's the market stolen AI keys feed: people running coding agents on someone else's bill.
How one key ends up in nine places
A developer gets one Anthropic key and starts using it. It goes into the coding agent, then into the preview deployment so the app's AI feature works, then into the CI job that runs the evals, then into a notebook service to try a fine-tune. Each paste takes thirty seconds and makes something work. You never go back to any of them.
Coding agents speed this up. Ask one to "deploy this to Northflank" or
"set up the Railway service" and it does what a developer would do: reads
ANTHROPIC_API_KEY from its environment and passes it to the platform's
CLI as a service variable. The deploy works. The key now lives on one
more platform, next to the database password, and no human typed it
there.
Then someone breaches a platform, and the advice is the same every time. Northflank's was "Revoke existing credentials with their issuing providers, generate replacements." To do that, you first have to remember every place that key went.
The same month in Bromure Agentic Coding
Bromure Agentic Coding runs Claude Code, Codex, Grok, Kimi and omp in Ubuntu VMs on your Mac, one VM per machine. The agent, its repositories and every command it runs live in the VM. The real credentials, and the proxy that all of the VM's traffic passes through, stay on the Mac.
The key lives in one place
Model keys go into Preferences › Models, once. Bromure stores them in
models.enc, encrypted with AES-GCM under a master key in the Mac's Data
Protection Keychain, with iCloud sync turned off. No credential, token
store or key material is uploaded, synced or backed up anywhere by the
app. Bromure runs no console that stores provider keys, so an attacker
finds nothing on our side to breach.
Inside each VM, ANTHROPIC_API_KEY holds a stand-in that starts with
sk-ant-api03-brm-. Claude Code accepts it, because it has the right
shape. When the agent calls api.anthropic.com, the request leaves the VM
through the proxy on your Mac, which swaps in the real key and sends the
request on. The proxy adds the key for the provider's own hosts and no
others:
anthropic.com for an Anthropic key, openai.com for an OpenAI key, and
so on.
If you sign in with a Claude, ChatGPT, Grok or Kimi subscription instead, the OAuth tokens stay on the Mac and the Mac refreshes them. The VM never holds a refresh token.
The agent can't spread it
Now replay the deploy. The agent runs the platform's CLI and sets
ANTHROPIC_API_KEY on the service, using the value from its environment.
That value is the stand-in, and the request carrying it goes to the
platform's API.
Bromure's proxy scans every outbound request, headers and body, for stand-ins headed to a host they weren't minted for. A stand-in Anthropic key in a request to a deploy platform's API is one of them. The proxy blocks the request with HTTP 451 before a byte reaches the platform, pauses the VM, and shows This environment may have been compromised, naming the credential, the host it belongs to and the host it was sent to.
We built that alert for malware that steals keys, and it fires the same way for an agent trying to help. Your coding key doesn't get copied onto a deploy platform without you seeing it. If the copy is what you want, Allow sends it to that host for the rest of the session. The better fix is to mint the production service a key of its own, scoped to production, and leave the key your agent codes with on your Mac.
Agents also pull secrets the other way. railway variables or a platform's
env pull can drop a production .env into the repository, real values
and all. Turn on Only allow credentials Bromure injects in the
machine's Guardrails and any request carrying a credential Bromure didn't
put there is blocked and raises the same alert. A real key the agent
downloaded from a platform stays unused in the VM.
Bedrock without a key to steal
Both of Wiz's downstream cases ran on Amazon Bedrock with long-lived enterprise credentials. In Bromure, any agent can run on Bedrock, Claude Code natively and the others through Bedrock's OpenAI-compatible API, and none of them needs a Bedrock key at all. Leave the Bedrock API key field empty and the Mac signs each request with the machine's AWS credentials.
Those credentials can be temporary. Choose SSO / Identity Center in the machine's AWS credentials and the Mac resolves short-lived role credentials from your SSO cache, refreshing them about five minutes before they expire. The VM gets a fake secret key that produces signatures AWS rejects; the Mac strips them and re-signs. No environment variable anywhere holds a long-lived Bedrock credential for someone to decrypt.
Rotation takes one paste
When a platform tells you to rotate, the key your agents use is a single field. Paste the new key into Preferences › Models and Bromure applies it about a second and a half after you stop typing, on every running machine that uses it. Each agent whose credential changed is relaunched with its resume flags, so the conversation carries on. The VMs don't restart, and nothing inside them needs editing, because nothing inside them held the old key.
If your keys live in 1Password, a machine's other API keys can be
op:// references instead of values. Bromure resolves them on the Mac and
re-resolves every two minutes, so rotating the item in 1Password reaches
running machines within a couple of minutes without a reboot.
Your own record of every use
Northflank's other advice was to check your provider's usage and billing
logs for activity you didn't run. In Bromure, every swap is a row in the
Security Timeline on your Mac, under Credential brokering, with a
masked key preview and the host, such as sk-a…f9q3 → api.anthropic.com.
AWS signings, Bedrock included, appear as Credential used rows with a
masked access key. When the provider's dashboard shows a spike, you can
see which calls came from your own machines.
On a Mac enrolled with Bromure Enterprise Manager, the same swaps stream
to your organization as credential.token_swap events, carrying previews
only, never the key itself. An admin answering "did any of our keys get
used from somewhere else?" has the legitimate side of the ledger for the
whole fleet.
One copy, on the Mac
Model keys live in models.enc, encrypted under a Keychain key, never synced or uploaded. There's no vendor console holding them.
Stand-ins in the VM
The agent's ANTHROPIC_API_KEY is a stand-in. The real key is added on the Mac, only for the provider's own hosts.
No accidental copies
A stand-in sent to a deploy platform is blocked with a 451, the VM pauses, and the alert names the destination.
Strict credentials
With strict mode on, a real key the agent pulled from a platform's env file is blocked the moment it's used.
Bedrock on SSO
The Mac signs Bedrock calls with short-lived Identity Center credentials. No long-lived key to store or steal.
Rotate in one paste
A new key in Preferences › Models reaches every running agent in seconds. The VMs don't restart.
Count the copies
Wiz doesn't know yet whether one group was behind all nine incidents, and most of the platforms haven't published a root cause. Every platform that stores your AI key can lose it, and October showed that thieves now have buyers waiting.
The key your agent codes with is the one you'd least want on that list. It works with your best models and your highest limits, and your agent uses it all day. In Bromure Agentic Coding it stays on your Mac. The agent gets a stand-in, which no other platform can use.
For the OpenCode Console breach, one of October's nine, read The keys were in their console. For Warp's stolen agent traces, read The agent log was in their cloud.