What This Actually Looks Like
1// Don't do this
2const STRIPE_SECRET_KEY = "sk_live_51H8x...";
3const DB_PASSWORD = "prod-p@ssw0rd-2024";It doesn't have to be this obvious - secrets end up committed inside test fixtures, example config files copied from a real one, CI YAML files, or even code comments left in during debugging.
The Moment You Find One: Rotate First
- Revoke and reissue the credential immediately, at the source (Stripe dashboard, database, cloud provider IAM) - before doing anything else. Assume it's already compromised.
- Then remove it from history, since a rotated-but-still-visible secret is a much lower priority once it no longer works, but should still be purged.
Purging It From Git History
1git filter-repo --path config.ts --invert-paths
2# then force-push the rewritten history and have all collaborators re-cloneDeleting the file in a new commit does not remove it from history - anyone can still retrieve it with git log -p or by checking out an earlier commit. Only rewriting history removes it, and that requires every collaborator to re-clone or hard-reset, so coordinate it deliberately.
Preventing the Next One
Move secrets to environment variables
1const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;Add a pre-commit secret scanner
Tools like gitleaks or detect-secrets can run as a pre-commit hook, blocking a commit before a secret-shaped string ever reaches your history in the first place.
Never commit real values in example/template config files
Use clearly-fake placeholder values (sk_live_xxxxxxxx) in any .env.example or sample config committed to the repo.
How Scanverra Detects This
Scanverra's repo scanner scans your full file tree for secret-shaped patterns - API key formats, private keys, connection strings, common vendor token prefixes - and flags each match with its location, as part of the same scan that also checks dependencies, code quality, and SAST findings.