Step 1: Rotate the credential immediately
Before anything else, revoke the exposed credential and issue a new one. Do this now, before touching git history — if the key has been in a public or shared repository, assume it has already been read.
After rotation, update the new credential in your deployment secrets manager (environment variables, Vault, AWS Secrets Manager, etc.) — not in code.
Step 2: Remove the credential from current code
If the credential is still in your codebase (not just in history), remove it:- Find all occurrences:
grep -r "AKIAIOSFODNN7EXAMPLE" .(use your actual key prefix) - Replace with an environment variable reference:
process.env.AWS_ACCESS_KEY_ID - Add the secret to your secrets manager or
.envfile (not committed) - Add
.envto.gitignoreif it isn’t already
Step 3: Purge the credential from git history
Removing a secret from current code doesn’t remove it from git history. You need to rewrite history. Option A:git filter-repo (recommended)
Step 4: Force-push to the remote
After rewriting history locally, push the rewritten history to the remote:Step 5: Notify anyone who has access to the repository
If the repository is or was public, or if it’s a shared private repository, assume the credential has been seen. Notify your team that they need to re-clone and that the old credential is revoked. If the key had write or admin access to a production system, check your audit logs for unexpected activity during the period the key was exposed.Step 6: Prevent recurrence
BattleTest’s secret scanning runs against the full commit history of every PR branch — not just the diff — so it catches secrets that were committed and then “removed” before the PR was opened. To avoid future incidents:- Use environment variables. Never hardcode credentials, even in config files committed to a private repo.
- Add pre-commit hooks. Tools like
detect-secretsorgitleakscan prevent secrets from being committed in the first place. - Connect BattleTest to your repositories. Every PR gets scanned automatically. See Get your first PR security review.
BattleTest scans the full commit history of every PR branch, not just the diff — so a secret that was committed and later “removed” is still caught. For how secret scanning works, see How PR review works. To dismiss a secret found in a test fixture, see How to review, dismiss, and track findings.