Your API Key Was Someone Else's Credit Card: The OpenCode Console Breach

OpenCode's one-line explanation for its October breach was that it was "related to a large scale distillation attack." It's a catchy phrase, the kind that makes a breach sound like it happened to the frontier labs rather than to the people who got the bill. But the people who woke up to hundreds of dollars of Anthropic and OpenAI charges did not have a distillation problem. They had a key custody problem, and so does anyone who has ever pasted an API key into somebody else's web console. So we set ourselves two goals for this piece, and they pull against each other a little. We wanted to be fair to a small open-source team in the middle of an incident it says is still ongoing, and we wanted to be blunt about the architecture that made this incident cheap for the attacker and expensive for everyone else.
What actually happened
The public record is still thin, so here is what we could verify, as far as we could tell, and from whom. OpenCode is the open-source AI coding agent built by the former SST team, now Anomaly Innovations, and it comes in two very different shapes. The local CLI and desktop app run on your machine. The hosted OpenCode Console lets a workspace owner link provider accounts once, store the credential, and route the team's requests through OpenCode's gateway so members can use models without ever seeing the key (OpenCode Console docs).
On October 17, affected users received an email titled "Action Required, Potential provider key breach," which reportedly described "unauthorized access to a legacy system" that OpenCode was in the process of decommissioning and said provider keys saved in the workspace "may have been exposed" (The Hacker News). Security researcher Matt Johansen posted a screenshot of it that afternoon (X). A few hours later OpenCode's own account appears to have confirmed the breach, tied it to "a large scale distillation attack," put the affected population at 1.4 percent of Console users (all of them with external providers linked), said the incident was ongoing, and said it was working with Anthropic, OpenAI, and Google (OpenCode on X). Co-founder Dax Raad drew the line that matters most for readers, which is that this was the Console and not OpenCode itself, because keys you add locally "never come to us" (Dax Raad on X).
The providers probably moved faster than the post-mortem will. Lydia Hallie, who works on Claude Code at Anthropic, said Anthropic had revoked Claude API keys it believed were affected (X). Tibo Sottiaux at OpenAI said OpenAI worked with OpenCode to get affected users back in business and to refund credits drawn in the attack (X). That is an employee's post rather than a formal notice, and we found nothing from Google at all. Meanwhile Raad said attackers had been hitting OpenCode's systems non-stop for 48 hours, and that his own accounts were being targeted too (X). There is no root cause, no entry point, no dwell time, and no statement on whether the stored keys were encrypted. As far as we could tell on October 19, those are all still open.
Two products, two very different trust models
Strip away the brand name and this incident is a lesson about where a secret lives. In the local CLI, OpenCode's documentation says keys you add with /connect land in a SQLite database on your own machine, by default under ~/.local/share/opencode/ (OpenCode CLI docs). An attacker who wants those keys has to compromise your laptop, and then the next laptop, and then the one after that. That is most likely slow, noisy, retail work. In the Console, the same keys sit in one service run by one company, so the attacker's unit of work is the whole customer base at once. That is wholesale.
None of this makes a hosted console a bad idea. Teams want one place to manage access, they want members to use models without holding raw keys, and they want a budget per person. Those are probably good security goals. But a console that stores customers' long-lived bearer credentials for frontier models has to be built like a vault, and the email's own wording suggests these keys likely lived in a "legacy system" that was being retired. In my experience, systems on their way out are exactly where nobody is watching anymore. The decommissioning ticket is open, the owner has moved on, and the data is still there.
There is a second, quieter detail that I think deserves more attention than it got. Several users on GitHub reported that first-party Console and OpenCode Go keys set to never expire suddenly showed as expired on October 17, including users who had linked no third-party keys and received no breach email (GitHub #56833; GitHub #56703). The most likely explanation is a precautionary mass revocation, which is the right call during an active incident. But OpenCode has not said so, and when a vendor says "if you did not get an email you were not impacted" while also expiring your keys, users are probably going to fill the gap with their own theories.
What "distillation attack" can and cannot mean
Words matter in incident response, so it's worth being precise about this one. Anthropic uses "distillation" for training a weaker model on a stronger model's outputs, and "distillation attacks" for covert, large-scale campaigns that pull those outputs out through fraudulent accounts, proxies, and reseller networks (Anthropic; Anthropic). Anthropic has also described proxy networks controlling hundreds of thousands of fraudulent accounts, and The Hacker News reported in September that those proxy pools are partly built from illegally harvested API keys (The Hacker News). I have not independently validated that last report against Anthropic's own document, so treat it as reported.
Read that way, there are three live explanations for OpenCode's phrase. One is that attackers breached OpenCode specifically to harvest keys for a distillation operation, which would make the stolen keys raw material for someone else's training run. Another is that OpenCode was already fighting distillation traffic through its own gateway, and the breach of the legacy system happened in the middle of that fight. The third, perhaps, is that "distillation" was simply the most dignified word available on a bad afternoon. It could have been any of them. My gut tells me it's the first, because the observed abuse was mass querying of frontier models billed to strangers, and that is exactly what a distillation operator wants. But we should not conclude it from the wording alone, and neither should anyone writing a headline.
Here is the part that doesn't depend on which explanation wins. Whatever the attacker wanted the tokens for, the method was the oldest one in cloud security. They found long-lived credentials stored by a third party and spent them. Sysdig named this pattern LLMjacking in 2024, when stolen cloud credentials were used to resell model access and run up victim costs that Sysdig estimated could exceed $46,000 a day (Sysdig). Two years later the target appears to have moved from cloud accounts to the services that aggregate model keys. That is not a new attack. It's an old attack that found a better wallet.
The bill was the detection
The victims did not learn about this from an alert. Most of them, it seems, learned from their invoice. The user reports are self-reported and none of them are confirmed by OpenCode, but they seem to paint a consistent picture, with roughly $281 on OpenAI and $168 on Anthropic for one developer, $1,700 for another, a Reddit user describing about $400 of Anthropic usage overnight, and another reporting about 200 euros of Google usage before the project was suspended (The Hacker News). The numbers are not huge by enterprise standards. But they are exactly the numbers a developer on a personal card notices at breakfast.
That is a design smell, and it probably isn't OpenCode's alone. For a decade we have told people to set billing alerts on cloud accounts, and most of us learned that lesson the hard way. AI API keys reintroduced the same failure with a faster burn rate, because a stolen key pointed at a reasoning-heavy frontier model might spend in an hour what a stolen compute key spent in a week. If your only detection control is the monthly statement, your detection time is likely a month.
One more uncomfortable point is worth making plainly. Console-side budgets and per-member limits probably do nothing once the raw key has left the building, because the attacker no longer routes through OpenCode's gateway (The Hacker News). The only limits that still apply are the ones on the provider side. So the place to put your hard stop is the provider, not the tool that holds the key.
Lock it down in twenty minutes
If you ever pasted a provider key into OpenCode Console, treat it as compromised whether or not you got the email, because the available evidence does not yet tell you otherwise. Deleting it from Console does not revoke it. Go to each provider directly, rather than following links in any breach email (phishers read the news too), and do the following.
For Anthropic, delete the key from the API keys page in the Console (Anthropic support). Every usage tier carries a monthly spend cap, and you can set your own lower organization limit on the Billing page. Workspaces other than the default one can have their own spend and rate limits, which is how you keep one tool's blast radius away from another (Anthropic rate limits). We could not find a documented spend-alert email, so check the Usage page yourself until you're sure.
For OpenAI, revoke the key from the project's API keys page. Spend alerts only notify. Hard limits are the control that actually stops spend, and they can be enforced per organization or per project; OpenAI notes that enforcement is not instant, so spend can overshoot a little (OpenAI spend limits). Give each tool its own project with its own hard limit, and a stolen key becomes a bounded loss instead of an open tab.
For the Gemini API, create a replacement key, switch your applications to it, then disable the leaked key (Google). Restrict keys to the Gemini API and, where you can, to IPs or apps. Since March, AI Studio has offered per-project monthly spend caps, which Google says take roughly ten minutes to enforce (Google). Vertex AI budgets are standard Cloud Billing budgets, which alert but do not stop spending.
Then review usage back to at least October 16. The things to look for are boring and useful, such as spikes at hours you don't work, models you never call (especially the expensive reasoning tiers), a high ratio of output tokens to input, batch jobs you didn't create, and source IPs where the provider exposes them.
While you're there, look at your own machine. The keys that leak next may not come from a vendor. They'll come from shell history, a forgotten .env, or a config directory that got synced to a backup you don't think about. The local CLI's model is safer than a hosted vault only as long as your laptop is safer than their legacy system.
What I'd change if I were building a BYOK console
If you run a product that stores customers' model keys (and a lot of AI tooling now does, from coding agents to the automation platforms I wrote about earlier this year), this incident is most likely your cheapest tabletop exercise this year. Encrypt every stored key with envelope encryption and a per-tenant key in a real KMS, so a database dump is not a key dump. Never let a decommissioning system keep live secrets; migrate them, rotate them, and then shut it down. Alert on per-key usage that departs from the customer's normal shape, because you see the traffic first and your customer sees the bill last. And give customers a one-click way to revoke at the provider, rather than only deleting your copy.
The providers have homework too. Long-lived static bearer keys are the root of this whole class of incident. The better pattern is short-lived, scoped credentials issued to a workload identity, with spend limits on by default instead of opt-in. Some of that appears to exist in pieces today. None of it is the default developers actually get when they click "create key."
Who holds the keys
OpenCode will publish a post-mortem eventually, and I hope it's a candid one, because the open-source community will learn more from a detailed failure than from a polished one. But the lesson does not have to wait for it. Every AI tool that offers to "manage your keys for you" is, in most cases, asking to become the most valuable target in your stack, because it holds credentials that turn directly into money and compute for whoever steals them. Convenience moved the keys into someone else's database. The bill stayed with you.
So the question to ask about any AI tool is not how smart its model is. Ask who holds the key, where the hard spending limit lives, and who finds out first when someone else starts using it. If the answer to that last one is "your credit card company," you already know which control to fix this week.
Further reading
- OpenCode, breach confirmation on X (Oct 17, 2026)
- The Hacker News, OpenCode Console breach may have exposed users' AI provider keys
- OfficeChai, OpenCode discloses security breach
- Startup Fortune, OpenCode breach exposes stored OpenAI and Anthropic keys
- Anthropic, Detecting and preventing distillation attacks
- Sysdig, LLMjacking: stolen cloud credentials used in new AI attack (2024)
- OpenAI, Spend limits; Anthropic, Rate and spend limits; Google, More control over Gemini API costs
- Earlier on this site, The State of AI Automation: Zapier vs Make vs n8n, Through a Red Team Lens

Founder · Dr. Chaos
Aamir Lakhani is a leading senior security strategist responsible for providing IT security solutions to major enterprises and government organizations. He creates technical security strategies and leads security implementation projects for…


