Deleting the file doesn't help. The key is still live until you rotate it, and it's still readable in git history until you remove it from there too. Here's the order that actually matters.
Step 1 (right now): rotate the key in Stripe
Go to dashboard.stripe.com/apikeys in live mode. Find the exposed secret key, open its overflow menu, and choose Rotate key. In the expiration dropdown, pick Now — not a grace period. A grace period exists to avoid downtime during planned rotations; it does the opposite of what you want during a leak, since it keeps the compromised key valid.
Copy the new key straight into environment variables — server environment, CI secrets, any deployment platform's secret store, never back into a file. Redeploy before you do anything else on this list.
This is the only step that actually disables the key. Everything below matters, but none of it neutralizes the leak by itself.
Step 2: check what happened while it was live
- In the Stripe dashboard, check the API request logs for the exposed key — filter by key ID and look for requests you don't recognize, especially from unfamiliar IPs or at odd hours
- Check for unexpected refunds, payouts, or customer list queries — a live secret key can read customer records, not just process payments
- If anything looks wrong, Stripe support can help assess the blast radius; don't assume silence in the logs means nothing happened, but don't assume the worst either — check first
Step 3: remove it from git history
A key doesn't disappear from a repo when you delete the file and commit — it's still sitting in every commit before that one, retrievable with git log -p or a clone of the repo from before the deletion. If the repo is public or shared, treat the key as burned regardless of what you do next (that's what Step 1 was for), then clean the history so it stops being a liability going forward:
- Use
git filter-repo(the tool git.com itself now recommends) or BFG Repo-Cleaner to strip the key from every commit, not just the latest one - Force-push the cleaned history, and have every collaborator re-clone rather than pull — a stale local clone will just push the old history back
- If the repo is public and has been up for more than a few minutes, assume it's already been scraped by an automated bot regardless of history cleanup — see below
What GitHub does automatically — and what it doesn't
Stripe is one of over 100 partners in GitHub's secret scanning partner program (docs.github.com/en/code-security/secret-scanning/secret-scanning-partnership-program/secret-scanning-partner-program). It runs automatically and free on public repositories: when GitHub detects a live Stripe key pattern in a public push, it notifies Stripe directly, and Stripe can revoke it — sometimes within minutes, before you've even seen the push notification.
Two things this doesn't cover:
- Private repositories aren't scanned by default. A key in a private repo can sit exposed indefinitely to anyone with access — a contractor after their contract ends, a compromised collaborator account, a fork nobody remembers exists.
- There's still a window. Detection isn't instant, and a scraper watching public commits in real time can beat GitHub's own notification to Stripe. Rotating yourself in Step 1 is what closes that window — don't wait to see if GitHub catches it first.
Prevent the next one
- Use restricted keys scoped to only what each service needs — a webhook handler that only needs to read charges shouldn't hold the full secret key
- Add
.envto.gitignorebefore the first commit, not after the first leak - Scan before you push, not after GitHub or a customer tells you
FAQ
Does GitHub automatically revoke a leaked Stripe key?
Stripe is a partner in GitHub's secret scanning partner program, which runs automatically and free on public repositories. This does not cover private repositories, and there's still a window between the push and detection where the key is live.
Is deleting the file with the key enough?
No. Deleting the file and committing that change leaves the key readable in git history via git log or git show. The key must be rotated in the Stripe dashboard regardless of what you do to the repository.
Are restricted keys safer than the full secret key?
Yes. A restricted key scoped to only the operations your app needs limits what an attacker can do if it leaks. It doesn't prevent the leak, but it shrinks the blast radius.
Top comments (0)