TroubleshootingIntermediate

How to Rotate a Leaked API Key Without Downtime

Respond to a committed or exposed API key safely by rotating it and purging it from history.

9 minIntermediate

If a key landed in a public repo, a screenshot, or a log, treat it as compromised immediately. Bots scan GitHub for keys within minutes and will run up charges. The goal is to revoke the old key, deploy a new one, and remove the key from your git history so it cannot be recovered.

  • Access to the provider dashboard to create and revoke keys
  • Your deploy platform or secret store
  • git, and optionally the git filter-repo tool

Step 1: Create a replacement key first

To avoid downtime, generate the new key before you revoke the old one. Add the new key to your secret store and deploy it, so the moment you revoke the leaked key the app is already using the new one.

Provider dashboard - API keys
API keys
Name Status Action
prod (leaked) active [ Revoke ]
prod-new active in use
[ Create new key ]
Have the new key live and deployed before you revoke the old one.

Step 2: Revoke the leaked key

Once the new key serves traffic, revoke the leaked one in the dashboard. From that moment the exposed key is dead even if it is still floating around in a cache or a fork.

Revoking is not optional
Removing the key from your code does not disable it. Until you revoke it in the dashboard, the leaked key still works for anyone who has it.

Step 3: Purge the key from git history

Deleting the line in a new commit leaves the key visible in older commits. Rewrite history to remove it, then force push. Coordinate with collaborators because this changes commit hashes.

zsh - cleanup
$git filter-repo --replace-text <(echo 'sk-leaked-key==>REMOVED')
Parsed 412 commits
New history written
$git push --force origin main
$

Step 4: Prevent the next leak

Add the secret file to .gitignore and install a pre-commit secret scanner so a key never gets committed again. Many teams add a CI check that fails the build if a key pattern appears.

.gitignore
.env
.env.local
*.pem
secrets/

Result

By creating and deploying the new key first, the app never lost a request, the leaked key stopped working the instant it was revoked, and the rewritten history removed it from every commit. A pre-commit hook now blocks the mistake from happening again.

Watch related tutorials

Tags
#security#api keys#rotation#git