· 20 min read
The OpenCode breach is bigger than you think, and here's the proof
OpenCode says 1.4% of Console users were hit. That's the share who had provider keys to spend. I spent the weekend counting everyone else, and reading OpenCode's own code to see what was sitting next to those keys.
Stolen API keys get spent at the end of the playbook, when the doors are shutting or the data has already been extracted. If you see this signal, it's already too late.
On October 17, OpenCode said a breach "impacted 1.4% of OpenCode Console users," and that if you didn't get an email, you weren't affected. I spent the weekend counting the people that sentence leaves out, and reading OpenCode's own public code to see what was sitting next to those keys.
Here's what I found.

Those numbers are self-reported, from 96 posts and issues I cataloged by hand. They're a floor, not a total. If you lost money or access, tell me: what you lost, which provider, and whether you got the email.
What OpenCode said
OpenCode sent two emails and posted twice.
The first email said it found "unauthorized access to a legacy system" it was decommissioning, and that third-party provider keys saved in your workspace "may have been exposed."
so you leaked the API keys? please say that and not call this a distillation attack pic.twitter.com/besxhNknsq
— Dawnshard (@WispyWinter) October 17, 2026
The first public post, at 17:56 UTC, gave the 1.4% figure. Twelve minutes later a second post added the line everyone quoted: no email means you weren't impacted, because it was "a subset of users who had external providers linked."
We had a security breach last night related to a large scale distillation attack that impacted 1.4% of OpenCode Console users
— OpenCode (@opencode) October 17, 2026
We have notified them all this morning via email
The incident is ongoing so we cannot share more details at this point but we are working with…
We had a security breach last night related to a large scale distillation attack that impacted 1.4% of OpenCode Console users
— OpenCode (@opencode) October 17, 2026
We have notified them all this morning via email. If you did not get an email you were not impacted, it was a subset of users who had external providers…
Then a follow-up email listed each affected key, put the earliest possible exposure at 00:30 UTC on October 17, and said this:
At this time no other data appears to have been exposed.
Can confirm
— Max Weinbach (@mweinbach) October 17, 2026
My OpenAI and Anthropic balances got drained, Google account got limited and drained a bit and OpenCode did email me https://t.co/HxPrmXJe2U pic.twitter.com/sdR8D1OAq2
That's the official answer to everything below. I want to be fair to it. "Appears" is doing honest work there: they're mid-incident, and it's their best read at the time. But the evidence doesn't fit it.
Why exposure hits more than 1.4% of Console users
The 1.4% counts people who had provider keys saved: OpenAI, Anthropic, Google. It doesn't count anyone else. Here's who else turned up.
People with OpenCode's own keys. Starting around 17:00 UTC on October 17, OpenCode's older sk- API keys started dying across accounts, with no notice. One user noticed every key under their "Legacy Service Account" expired at once, while newer oc_sk_ keys kept working. A paying Go subscriber with no external providers linked at all filed a GitHub issue: their key, set never to expire, was revoked and removed from their account. Another found every workspace they own locked, with no provider keys stored and no email. I count 38 people in this group.
People who were drained without an email. At least 14 people say they never got OpenCode's notice. Some were drained anyway, including OpenRouter balances, a provider OpenCode never named.
I didn't get an email, but my external openrouter API key was still drained
— Adam (@npm_startup) October 18, 2026
disappointed icl
People whose OpenCode credit was spent. One user, writing in Chinese, says their prepaid Zen balance was drained to zero overnight, and the usage history shows no trace of the calls. That's not a provider key. That's OpenCode's own money, in OpenCode's own system.
People whose provider accounts were punished for it. Google suspended Cloud projects. OpenAI disabled at least one account entirely, ChatGPT included, for "abusive behavior" the owner didn't commit.
OpenAI first flagged "suspicious activity" on the key I had stored in OpenCode Console (~06:17 UTC Oct 17). ~8h later they disabled both my API org and my whole account (ChatGPT included) for "abusive behavior". No specifics beyond that. Appeal in progress.
— Alejandro García Iglesias (@aiglesias_) October 18, 2026
None of that is in the 1.4%.
The timeline
All times UTC. Pieced together from OpenCode's emails, posts, status page, code and deploy logs, plus the earliest posts from the people affected.
- The Console is already under attack PR #45007 rate-limits checkout to stop "active card-testing abuse."
- The Console login is locked down PR #45027 and #45374 restrict where sign-in can redirect and reject forged requests.
- A fix to protect the legacy Console login is written PR #45919 adds a bot check (Cloudflare Turnstile) before sign-in.
- Fraud at scale PR #48491 adds bulk blocking, because "fraud response regularly needs to block hundreds of workspaces at once."
- A trusted header goes in The request proxy starts sending a client ID the model service trusts. Per PR #55120, it could be used to fake an IP or pick a model until Oct 13.
- The old Console narrows to paying customers PR #50716 limits it to Black subscribers: 1,887 active workspaces. Everyone else is redirected.
- A cleanup bot closes the bot check, unmerged It had fewer than two reactions. The same day, Black renewals stop.
- OpenCode fixes guessable addresses PR #53962: hostnames "are published in certificate transparency logs, so the remote address was guessable." That's the remote-access feature, not the Console, but it's the same public list.
- Dev can't delete its old database Three test deploys fail in a row: "This branch is protected from deletion."
- The old Console is cut off from its database The production deploy removes the old sign-in service and one database password. Deleting the database itself is left as a manual step.
- The trusted header is closed PR #55120 stops honoring the old client ID.
- Earliest possible exposure OpenCode's own estimate, from its follow-up email.
- First public "my key leaked" post A user says their OpenAI key leaked right after using OpenCode.
- First balance drained to zero Anthropic credits, per one victim. OpenAI flags the same person's key at about 06:17.
- First full victim write-up Two keys added to OpenCode Zen, both drained.
- OpenCode's own keys start expiring Legacy keys die across accounts, with no notice. The earliest exact report is 17:14.
- OpenCode's "logs" service goes down Twice, until 18:11, per its status page.
- OpenCode posts about the breach Twelve hours after the first drained balance.
- Anthropic revokes affected Claude keys Announced here. Google blocks exposed Gemini keys at 22:53.
- A forgotten page comes down PR #56566 removes an old homepage draft, "still live and indexable," that linked to the retired sign-in.
- Free models start blocking whole networks Users without a VPN get "abusive traffic" errors, a dozen GitHub issues so far.
- "Non stop" attacks for 48 hours Dax, from OpenCode.
- OpenCode rotates its own Cloudflare token PR #56841 swaps it for a narrower one.
- The old share API comes down PR #56939: "People still find these routes."
- OpenAI says it's refunding Drawn credits are refunded for affected OpenAI customers. Anthropic and Google haven't said the same publicly.
Two things jump out. Keys were being spent about twelve hours before OpenCode said a word. And OpenCode rotated more than customer keys: its own legacy keys, and its own infrastructure token.
Here are the posts behind those times, as people posted them:
Conviently my openai API key leaks right after using this
— Zach Huston (@HueyHuston) October 17, 2026
Same night my Anthropic credits were drained to zero (~05:40 UTC), before OpenCode's breach email even arrived. So the keys were being abused for hours before anyone was notified.
— Alejandro García Iglesias (@aiglesias_) October 18, 2026
Someone, somehow just drained ~$50 of Anthropic API tokens and ~$70 of OpenAI. Both keys were added to OpenCode Zen. I guess now these are called Providers in there.
— Martynas (@Martynas) October 17, 2026
And 14 hours ago I just got an email about opencode 2.0 being out. I hope it's not related, or then, I may not…
Why more than keys were probably leaked
A note before this section: this is an assumption, not a finding. Everything below is what the old database held. Whether the attacker read it is something only OpenCode can confirm, and it's the biggest open question in this whole story.
OpenCode's code is public, so you can read what the old Console stored. On October 12, a pull request cut the Console off from its "legacy PlanetScale DB." Right before that change, the database schema held:
- Account details: emails and names
- Logins: GitHub and Google account IDs
- Billing, per workspace: Stripe customer and payment method IDs, how it pays (card, Link or Alipay), the card's last four, balance, monthly usage and limit, subscription plan
- Usage: IP addresses and usage counters
- OpenCode API keys: stored as-is. The app showed the raw key back to its owner, so it wasn't hashed.
- Your provider keys: saved exactly as you typed them. No encryption in the app code.
The same pull request kept two storage buckets on purpose because, in its own words, they "hold the archived Zen request/response dumps." That's prompts and completions.
An independent investigation by YFarmX walked the same code and OpenCode's deploy records and reached the same conclusion: keys were stored readable, and there's no public record the old database was ever deleted.
Again, I can't prove the attacker read all of that. OpenCode hasn't said how they got in, and nobody outside knows which tables they touched. OpenCode's follow-up email says no other data appears to have been exposed, and that may turn out to be right.
Here's why I still think it's likely. The keys and everything listed above lived in the same database, and if you can read one table, you can usually read the rest. And OpenCode's response, expiring legacy keys across accounts and rotating its own infrastructure token, looks like treating the whole system as exposed. That's my reading of the evidence, not something OpenCode has said.
So: 1.4% got a bill. Every legacy Console user was in that database. Whether that data left with the keys needs clarification from OpenCode, and it's the first thing I'd want answered in their post-mortem (see the questions below).

How the keys were used
This wasn't somebody browsing your account. It was a machine.
- Volume: one victim's OpenAI key ran 8,966 requests and 35 million tokens in a day.
- Testing first: a request log shows a Chinese prompt meaning "please reply ok," answered "ok." That's a key check, done before the real work starts.
- Tooling: victims saw agent traffic, prompts in Chinese, Gemini runs through someone else's OpenRouter account, and balances emptied within minutes.
?
— Max Weinbach (@mweinbach) October 18, 2026
i am the only one literally paying for this pic.twitter.com/6Uee2wkQhv
OpenCode said the breach was "related to a large scale distillation attack." A lot of people, me included at first, read that as distillation being how the attacker got in. It doesn't work that way.
Distillation means feeding a strong model millions of prompts and training a cheaper model on its answers. It needs huge volumes of tokens, and the cheapest way to get them is on somebody else's card. So it fits as a motive. But be clear about the order: the distillation is what the stolen keys were for. It isn't how they were stolen. Something else let the attacker into a database full of keys, and that part is still unexplained.

Why the keys are the last thing they take
Think about how a break-in like this goes.
First you get in. Then you copy everything you can: the database, the backups, whatever's in storage. That part is silent. Nobody gets an alert when a table is read.
Spending the keys is different. Every provider meters them. Bills spike, fraud systems wake up, victims notice by morning. The moment you start spending stolen keys, the clock starts. So you do it after the copying is done.
That's why I don't read the drained balances as the size of the breach. I read them as the end of the first wave. The keys were the part that showed up on a bill.
This is the new frontier
I don't think OpenCode did anything unusual. That's what worries me.
Every developer tool is becoming a place where keys pile up. Coding agents, AI gateways, "bring your own key" dashboards, MCP configs, CI secrets. Each one holds credentials that spend real money, and each one is a blank check if it leaks. Attackers have noticed. Stolen AI keys now have a resale market and a business model.
And the attackers have agents too. Dax put it plainly: they've been attacking non-stop for 48 hours, and defending means running agents around the clock, "because that's what they have." His personal accounts were attacked the same day. When his team tried to investigate with frontier AI models, the models did quite a bit and then started refusing, until they got special access to a defense-only model.
they've been non stop trying to attack our systems for the past 48 hours
— dax (@thdxr) October 18, 2026
a side effect is everything is getting hardened but damn we basically need agents going 24/7
because that's what they have
my personal accounts are being attacked now too
— dax (@thdxr) October 17, 2026
whole new world with ai powered hacking
yes that was a bit frustrating mid incident when trying to investigate. they did quite a bit and then started refusing
— dax (@thdxr) October 18, 2026
we got access to daybreak blue now so it's better
Read that again. The attackers didn't need anyone's permission. The defenders needed a permission slip.

So expect more of this. More breaches at tools that hold keys. Longer gaps between the theft and the disclosure. And a second wave after this one. If emails and names left with the keys, the next thing OpenCode users will see is very convincing email about their "OpenCode billing" or "API key rotation." I haven't seen reports of that yet. I'd bet on it.
What to do right now
If you ever used the OpenCode Console:
- Revoke keys at the provider, not just in OpenCode. A copied key keeps working until OpenAI, Anthropic, Google or OpenRouter kills it.
- Rotate even without an email. 14 people who didn't get one still got hit.
- Check for old
sk-OpenCode keys and replace them with new ones. - Put a hard spend cap on every key, and use one key per tool, so one leak burns one budget.
- Treat any OpenCode-themed email as phishing until proven otherwise. Type the URL yourself.
- Read your usage logs back to October 16, not just yesterday.
Open Questions for OpenCode
These aren't gotchas. They're the gaps between what OpenCode has said and what its users are seeing. A post-mortem that answers them would settle most of this article, one way or the other.
How it happened
- What does "related to a large scale distillation attack" mean? Was distillation how the attacker got in, or what the stolen keys were used for? Many readers took it as the first.
- How did the attacker get in, and when were they first inside? The follow-up email puts the earliest possible exposure at 00:30 UTC on October 17. What is that time based on?
- When did OpenCode first know? OpenAI flagged a stolen key around 06:17 UTC. The public post came at 17:56. What happened in between?
- Was the legacy database still running on October 17? The October 12 change left deleting it as a manual step. Has it been deleted now, and when?
- Is the sign-in path that the August Turnstile fix was meant to protect involved?
What they could reach
- Which tables did the attacker read? Only the provider keys, or also users, logins, billing, IP addresses and OpenCode's own keys?
- Were the Zen request/response dumps accessed? Those are customers' prompts and completions.
- Were provider keys and OpenCode keys encrypted when they were taken? The legacy code didn't encrypt them. Did anything else?
Who was affected
- How many people is 1.4%? And how many keys, from which providers? OpenRouter users report drained balances, but OpenRouter isn't named anywhere.
- Why were legacy
sk-OpenCode keys expired across accounts if only provider keys were at risk? How many were revoked? - Were Zen balances spent by the attacker? At least one user says their balance hit zero overnight with no usage history to show for it.
- Why did some people who were drained never get an email? Will everyone whose details were in the legacy database be told, not only people who had provider keys?
What happens now
- Will refunds cover everyone? That means provider charges, spent Zen credit, subscription time lost to revoked keys, and the cost of provider accounts that were suspended or deleted.
- Why doesn't the status page show a security incident?
- When will the post-mortem be published, and what changes so a system being shut down can't hold live credentials again?
To be fair to Dax and the team: they're issuing refunds, answering people one by one, and hardening everything while under attack. That's hard, and it's heartbreaking to watch. It's also a reminder that the people we look up to aren't invincible. Nobody is. It's not a matter of if. It's a matter of when.
note this is the OpenCode Console, not OpenCode itself, those keys never come to us
— dax (@thdxr) October 17, 2026
If the breach is bigger, here's what comes next
This section only matters if my assumption above is right, and more than keys left that database. If it did, here's what I'd expect.
A profile for every affected user
The old Console didn't store users one row at a time. It stored them inside workspaces, with their teammates and roles. Joined together, the tables in that schema describe each person pretty well:
- your name and email, and the GitHub or Google account you sign in with
- your workspace name, often your company's name, and who else is on it, including who's the admin
- your workspace's plan, how it pays and the card's last four digits, plus its balance and monthly usage
- the IP addresses you work from, and which AI providers you use
That's not a list of leaked keys. That's a target list, sorted by who has the most access and the biggest budget.
Phishing that knows your name
The keys were the first wave. A target list is the second. If your details were in that database, expect phishing emails and text messages. The schema I read doesn't hold phone numbers, but matching an email address to a phone number is cheap, thanks to every older breach out there.
They'll look like they come from the people you'd expect right now:
- OpenCode: "Claim your refund," "Your workspace has been restricted," "Rotate your API key here."
- OpenAI, Anthropic or Google: "Suspicious activity on your API key," "Your account has been suspended, verify your billing."
- GitHub or Google: "Re-authorize OpenCode," a sign-in prompt asking you to approve access.
And they'll be targeted. A message that names your workspace, your teammate and the last four digits of your card doesn't look like spam. It looks like support. The goal is always the next step in: a fresh API key, a session token, a payment card, an OAuth grant to your GitHub and every repo behind it.
The tell is simple. Nobody legitimate will ask you to hand over a key, sign in through a link, or "verify" a card over email or text. Not OpenCode, not the AI providers, not GitHub.
What I'm doing about it
I watch attacks like this every day. Like I said in the beginning, I'm not immune to bad actors. I just got really good at watching them back. That comes down to two fronts: the messages that land in my inbox, and the traffic that lands on my apps.
Phishing: assume the next email knows my name
If this breach is as big as I think, the next attacks won't come through a server. They'll come through an inbox or a phone. These are the habits I lean on most right now:
- Never act on a link. If an email or text says a key, a bill or an account needs attention, I close it and go to the dashboard by typing the address myself.
- One email alias per service. When a phishing email arrives at the address I only gave to one vendor, I know exactly where it leaked from, and it goes straight to spam.
- Hardware keys and passkeys on anything that signs me in elsewhere. GitHub and Google first, because one approved prompt there opens everything downstream.
- Review what's connected. Every few weeks I check which apps have OAuth access to my GitHub and Google accounts, and revoke anything I don't recognize.
- Treat urgency as the signal. "Act within 24 hours or lose access" is the attacker's clock, not mine.
Application security: defend in front of the app
For my apps, I stopped trusting each one to defend itself, and moved the defense in front of them.
I run the Mr. Nice Try Edge, a front door that sits in front of websites and writes down every knock. On October 17, the same day those keys were being drained, it recorded its biggest AI key hunt ever:
.envI can't tell you those scanners were the same people. I can tell you the hunt for AI keys doubled overnight, and Anthropic keys were the most wanted. Here's how the edge handles it:
- Log everything, and fingerprint it. Every request, every TLS handshake. Bots dressed up as Chrome give themselves away before they say a word.
- Tag what looks wrong. Anyone asking for
.env,.git, an AI key file, or an admin panel that doesn't exist gets marked, along with everything else they do. - Move them aside quietly. Not always a hard block. Sometimes a detour, so they don't know they've been seen, and I get to watch what they try next.
- Assume patience. Their automations change a little every day until something gets through. So the rules have to keep learning too.
I'll share more about how it works soon. For now, the daily reports show what the edge sees every morning.
No one is coming to save you from being hacked, but there are ways to find out before your keys get revoked, and it requires reframing how we think about security.
How I put this together
I read every post I could find on X about the breach, plus replies and quote posts. I read OpenCode's public GitHub repo (pull requests, commits and issues) and its status page's public JSON. I cataloged 1,274 sources into a database and tagged 96 first-person reports from 78 people by hand. Dollar amounts are what people said publicly, not verified bills. Where I'm guessing, I've said so.
References
- OpenCode: first post, second post, first email (screenshot), follow-up email (screenshot), status page
- OpenCode's repo: PR #54585, legacy database removal, PR #56841, Cloudflare token rotation, PR #45919, Turnstile login fix, issues #56833, #56703, #56620
- Dax: 48 hours of attacks, personal accounts, models refusing, Console only
- Providers: Anthropic, Google
- Independent analysis: YFarmX
- First reports: Matt Johansen, Hacker News thread