My API key leaked. What now?

You pushed a key to a public repo, or got a secret-scanning email, or found one sitting in your frontend bundle. This is a normal thing that happens to careful people. Here's what to do, in order.

Do this first

  1. Rotate the key. Not delete โ€” rotate. Generate a new one at the provider and revoke the old one.
  2. Then update wherever the app reads it from.
  3. Then check your usage and billing for anything you didn't do.

Everything else โ€” cleaning git history, working out how it happened, feeling bad about it โ€” comes after those three. A revoked key is a harmless string.

Why rotating is the only fix

The instinct is to delete the line, commit, and hope. That doesn't work, for three reasons:

So the honest assumption is: if it was exposed, treat it as known. Rotating makes that irrelevant. Nothing else does.

Where to rotate, by provider

ProviderWhereAlso do this
OpenAIplatform.openai.com โ†’ API keys โ†’ revoke, create newCheck Usage for spend you don't recognise ยท full guide
Anthropicconsole.anthropic.com โ†’ API keysCheck Usage ยท full guide
StripeDevelopers โ†’ API keys โ†’ roll the secret keyCheck Payments and Refunds for anything unfamiliar. Contact Stripe support if you find any. ยท full guide
AWSIAM โ†’ Users โ†’ Security credentials โ†’ deactivate, then deleteSee the AWS note below โ€” this is the expensive one
SupabaseSettings โ†’ API โ†’ rotate service_roleAssume every row was readable ยท full guide
GitHubSettings โ†’ Developer settings โ†’ Personal access tokensCheck recent activity on your repos
Google CloudAPIs & Services โ†’ CredentialsAdd referrer/API restrictions to the replacement
TelegramMessage @BotFather โ†’ /revokeโ€”

Rotating usually breaks your deployed app for a minute, because it's still using the old value. That's fine, and it's the correct order โ€” a briefly broken app is better than a live key in the wild.

Three cases that need more than a rotation

AWS keys

This is the one that generates the horror-story bills. Attackers use stolen AWS credentials to run compute โ€” usually crypto mining โ€” and they do it in regions you've never opened, because that's where you won't look.

After deactivating the key: check the Billing dashboard, then check EC2 in every region, not just yours. Also look at IAM for users or access keys you didn't create โ€” a common move is to create a second set of credentials so revoking the first one changes nothing. If you find charges, contact AWS support; they routinely waive fraudulent usage when you report it promptly.

Supabase service_role keys

That key bypasses Row Level Security completely, so while it was exposed, every row in your database was readable and writable by anyone holding it. Rotate it, then assume the data was read. If it included other people's personal information, you may have a legal obligation to tell them โ€” that's a data breach, not just a leak.

Live Stripe secret keys

Roll it immediately, then review Payments, Refunds and Customers for activity you didn't initiate. Stripe's support team deals with this often and are worth contacting early rather than late.

Then: clean up and prevent the repeat

  1. Get it out of the codebase. Move the value to an environment variable, and make sure the file that held it is gone from the working tree. Set the real value in your host's dashboard โ€” Vercel, Netlify, Supabase and the rest all have an environment variables screen. A .env file on your laptop is not read by your host.
  2. Make sure .env is ignored. Add .env and .env.* to .gitignore. If .env was already committed, git keeps tracking it until you run git rm --cached .env.
  3. Consider rewriting history โ€” but don't rely on it. Tools like git filter-repo or BFG can strip a secret from past commits. Worth doing for tidiness and for anyone cloning fresh. It does not undo the exposure: forks and caches keep their copies. The rotation is what saved you; this is housekeeping.
  4. Turn on push protection. GitHub can block pushes containing recognised secret formats, and it's free on public repositories. It catches this class of mistake before it becomes a public one.
  5. Check whether anything else is exposed. Keys rarely leak alone. The habit that put one in the code โ€” pasting a value in to get something working โ€” usually put several. Worth a look before you close the laptop.

On feeling stupid: don't. Every provider has a one-click rotation flow, GitHub built a scanner, and Stripe auto-detects leaked keys, because this happens constantly to experienced engineers. You caught it. That's the part that matters.

Check whether anything else leaked

vibecheck scans your project or your live URL for exposed keys and the mistakes that cause them, in plain English โ€” with a fix prompt you can paste straight into your AI tool. Free, and your code doesn't leave the scan.

Scan my app