I Leaked an API Key or .env File: What to Do Now
Quick answer: Pushed a .env file or shipped a secret key? Revoke and rotate it first, check usage and billing, set spend caps, then purge it from git history. Step by step.
The problem
You notice one of these:
- A
.envfile (or a file withsk-...,sk_live_...,AKIA...or a Supabaseservice_rolekey) was committed and pushed to GitHub. - A secret key was put in frontend code, or behind a
VITE_,NEXT_PUBLIC_orEXPO_PUBLIC_variable, so it ships to every visitor's browser. - Your
.envfile was deployed with your site and can be opened athttps://your-site/.env. - You got an email from GitHub, OpenAI or another provider saying a key was exposed, or your bill suddenly jumped.
Why it matters
Assume the key is already compromised. Automated bots continuously scan public repositories and websites for keys, and anyone who cloned, forked or cached your repo still has a copy, even if you delete the file. Deleting the commit is not enough. The only real fix is making the leaked key useless.
Fixes (in this order)
1. Revoke or rotate the key right now
Go to the provider's dashboard, create a new key, and delete or disable the leaked one:
- OpenAI / Anthropic / other AI APIs: API keys page → revoke the key, create a new one.
- Stripe: Developers → API keys → roll the secret key (you can choose for the old one to expire immediately).
- Supabase: if you use the newer
sb_secret_...keys, delete the leaked key and create a new one. If a legacyservice_rolekey leaked, follow Supabase's instructions to rotate the JWT secret or migrate to the new API keys. Note that rotating the JWT secret also changes the anon key and signs users out. - AWS: IAM → the user's access keys → deactivate, then delete the key and create a new one.
- Google Cloud / Firebase: delete or regenerate the API key, and add API and app restrictions to the new one.
2. Put the new key where your app needs it, then redeploy
Update your local .env and your host's environment variables (Netlify, Vercel, Supabase secrets), then trigger a new deploy so the app picks up the new key. Keep secrets server-side only, never behind a public prefix.
3. Check usage, logs and billing
Look at the provider's usage and billing pages for activity you don't recognize since the leak, and check for new resources you didn't create (cloud VMs, new API keys, new users). For AWS, review CloudTrail. If you see fraudulent charges, contact the provider's support quickly. Many have a process for leaked-key incidents.
4. Set spend limits and alerts
Turn on whatever protection the provider offers: usage limits or budgets on AI APIs, billing alerts, and project-level limits. Some cloud budgets (for example on Google Cloud and AWS) only alert by default and don't stop spending, so read what your setting actually does.
5. Remove the secret from your code and git history
Stop tracking the file and ignore it from now on:
git rm --cached .env
printf ".env\n.env.*\n!.env.example\n" >> .gitignore
git commit -m "Stop tracking .env"
That removes it from future commits only. To scrub it from history, back up the repo, then use git filter-repo (or BFG Repo-Cleaner):
git filter-repo --invert-paths --path .env
# filter-repo removes the 'origin' remote as a safety step; add it back:
git remote add origin https://github.com/you/your-repo.git
git push origin --force --all
git push origin --force --tags
Anyone else working on the repo needs to re-clone afterwards. On GitHub, copies can survive in forks and cached views, which you can ask GitHub Support to remove. This is why step 1 comes first.
6. Remove it from your live site
If the .env file was deployed, delete it from the publish folder, redeploy, and confirm https://your-site/.env now returns a 404. If the key was in frontend code, move the API call into a server route or edge function, then search your built JavaScript for the old key to confirm it's gone.
7. Prevent the next leak
- Keep
.envfiles in.gitignorefrom day one, and commit a.env.examplewith empty values instead. - Turn on GitHub secret scanning and push protection for your repositories, so pushes containing known key formats are blocked.
- Run a scanner such as Gitleaks before you push.
- Use the most restricted key you can: test keys in development, restricted or scoped keys where the provider supports them.
Prompt to paste into your AI tool
A secret key may have leaked from this project. Find every place a secret is used or stored (including .env files, config files, and any VITE_/NEXT_PUBLIC_/EXPO_PUBLIC_ variables). List which keys must be rotated. Move any secret used in browser code into a server-side route or edge function, make sure .env files are in .gitignore, and add a .env.example with empty values. Don't print any secret values in your answer.
FAQ
I deleted the file and pushed again. Am I safe? No. The key is still in your git history and may already have been copied. Rotate it.
My repo is private. Do I still need to rotate? It's lower risk, but if the key was shared with collaborators, CI tools or an AI tool you don't fully control, rotating is the safe choice and only takes a few minutes.
Is the Supabase anon key a leak? No. The anon or publishable key is designed to be public, as long as Row Level Security protects your tables. The service_role and sb_secret_... keys are the ones that must never be exposed.
Related guides
- Invalid API key or undefined env vars on Vercel
- Supabase returns empty data with no error
- Supabase RLS errors in Lovable and Bolt apps
- Stripe checkout succeeds but the app never records the payment
Still stuck? Paste your exact error into the free Error Fixer to get a plain-English cause, the fix, and a prompt to paste back into your AI tool.