GitHub flagged a leaked key in your repo: what to do
GitHub can detect credentials that appear in repositories, issues, pull requests, and related surfaces via secret scanning, and can block a push when push protection is in play. Per GitHub’s documentation on secret scanning, scanning covers known secret types across git history on branches, and GitHub also describes scanning issues, pull requests, discussions, wikis, and gists. Availability differs for public vs private repos (public repos are scanned automatically; private repos depend on your plan and Secret Protection). Do not assume every provider key is always detected — treat a flag as “this one was found,” not “GitHub caught everything.”
1. Rotate first (do this before polishing git history)
If the alert is a real secret (API key, token, private credential):
- Open the provider (Stripe, Supabase, OpenAI, AWS, etc.).
- Roll / revoke the exposed key and create a replacement.
- Put the new value only in server-side environment variables or a secret manager — not in the client bundle.
- Redeploy so production uses the new secret.
GitHub’s own guide to removing sensitive data states that for secrets you should revoke or rotate first; once the credential cannot be used, history cleanup may be unnecessary for risk reduction.
Deleting the line from the latest commit without rotating leaves the old key valid for anyone who already copied it (including from older commits or forks).
2. Fix the code and config
- Remove secrets from tracked files; add
.env(and friends) to.gitignore. - If a Vite/Lovable-style app inlined a secret because of a
VITE_prefix, rename and move the call server-side. See How to remove leaked VITE_ keys. - Commit and push the fix so the default branch no longer contains the live secret in the current tree.
3. History cleanup (only if you still need it)
After rotation, rewrite history only if you have a reason (compliance request, still-sensitive non-credential data, etc.). GitHub documents using git-filter-repo, force-pushing, coordinating clones/forks, and contacting Support to clear cached views — and warns about side effects (re-contamination on pull/push, broken PR diffs, changed SHAs). Follow: Removing sensitive data from a repository.
If push protection blocked the push, remove the secret from the commits you are pushing and try again; see About push protection.
4. Check whether the old key was used
In the provider dashboard, review:
- API logs / audit logs around the time the key was in the repo
- Billing spikes or new resources you did not create
- Stripe: unexpected customers, webhooks, or keys list
- Supabase: whether a
service_rolekey was the one exposed (rotate JWT secret / service role per Supabase’s docs)
Document what you checked. If you see abuse, follow that provider’s incident steps.
5. Partner notifications (what GitHub says)
GitHub partners with providers to validate detected secrets; for some partner secrets GitHub notifies the provider so they can act (for example revoke). Partner-reported secrets may not appear the same way as repository alerts. Details: About secret scanning (partner integration section). Rely on GitHub’s current docs for which alert UI you will see — do not assume every leak emails you.
6. Reduce repeat leaks
- Prefer platform secret stores and server routes over pasting keys into chat or
.envfiles that get committed. - Enable push protection where your plan allows it so future pushes containing known secret patterns are blocked (push protection docs).
- Run a free passive scan of the deployed app URL for keys that shipped in JavaScript even when git looks clean.
- For Supabase exposure patterns, also read Supabase RLS.
What this guide is not
This is not a guarantee that GitHub scans every vendor, that your private repo is covered, or that rotation alone meets a legal obligation. It is a practical order of operations: revoke → fix → optional history purge → check usage → prevent recurrence. If you want a scoped fix plus a before/after verification report on an AI-built app, see Rescue pricing.