Why deleting the file doesn't work
Git is built to remember. When you delete a file and commit, the old version stays in history — anyone can check out the previous commit, or just browse it on GitHub, and read the key. Force-pushing a cleaned branch doesn't reliably help either: forks, clones, local copies, and caches all retain the old commits.
On a public repo, you should also assume the key was harvested the moment it was pushed. Automated scrapers watch public GitHub for credential patterns continuously; the window between push and harvest can be minutes. That's why the only fix that actually ends the exposure is making the key worthless.
Rotate first, clean up second
Rotation means revoking the exposed credential and issuing a new one at the provider — the AWS console, the Stripe dashboard, the OpenAI or Anthropic settings page, wherever the key came from. Once the old key is revoked, the copy in git history is dead weight: anyone who harvested it has a string that no longer opens anything.
Only then is it worth cleaning history, and the right tool is git filter-repo (the maintained successor to filter-branch and BFG for this job). It rewrites the repository's history to remove the secret, after which you force-push and ask collaborators to re-clone. While you're at it, check whether the key was used: most providers show usage logs, and a key that was exploited may mean more cleanup than rotation.
Make the next one impossible to miss
One committed key usually means the habits that produce committed keys, so check for siblings: other keys, hardcoded passwords, connection strings with credentials, committed .env files. A securevibes scan covers all of these in one pass — secrets and credentials is its heaviest category at weight 30 — and every secret finding comes back with redacted evidence, the file and line, and rotation-first next steps in order.
Prevention is the boring part that works: keep secrets in environment variables, make sure .gitignore covers .env and key files (securevibes checks this too, under data exposure), and re-scan before you push anything significant. The free monthly credits are enough to make a scan before significant pushes a habit.
how it works
- 01
Rotate the credential now
Go to the provider and revoke the exposed key, issuing a new one. Do this before touching the repo — it's the only step that actually ends the exposure.
- 02
Check for abuse
Review the provider's usage logs and billing for activity you don't recognise. An exploited key can mean more cleanup than an unused one.
- 03
Purge the key from history
Use git filter-repo to rewrite history and remove the secret, then force-push. Collaborators should re-clone; old clones and forks may still hold the dead key, which is why rotation came first.
- 04
Sweep for other secrets
Scan the repo for sibling issues — other keys, hardcoded passwords, committed .env files, connection strings. securevibes checks all of these in one pass with redacted evidence.
- 05
Prevent the repeat
Move secrets to environment variables, cover .env and key files in .gitignore, and make a scan part of your pre-push routine.
frequently asked
- I deleted the file and force-pushed. Am I safe?
- No. The key persists in forks, clones, and caches, and on a public repo it was likely harvested by automated scrapers within minutes of the push. Rotate the credential at the provider — that's the step that ends the exposure.
- How fast do exposed keys actually get found?
- Fast enough that you should treat a pushed key as already compromised. Credential scrapers monitor public GitHub continuously, so the safe assumption is minutes, not days.
- What's git filter-repo and do I really need it?
- It's the maintained tool for rewriting git history to remove a file or string everywhere it ever appeared. You need it if you want the key gone from history rather than just from the latest commit — but it's step three, after rotation, not step one.
- Can securevibes tell me if I have keys committed right now?
- Yes, for public repos: paste the link and the secrets & credentials check covers AWS, Anthropic, OpenAI, Stripe live, GitHub, Google, and Slack keys, private key blocks, connection strings with credentials, hardcoded passwords, JWTs, and generic api-key assignments — each with file, line, and redacted evidence.
Published June 10, 2026 · Last updated June 11, 2026