Deleting the line does not delete the secret
Here is a moment that has happened to almost every team: someone hard-codes a database password or an API key into a config file, commits it, pushes, and then — a commit or an hour later — realizes what they did and quietly deletes the line. Crisis averted, it feels like. Except it isn't. Git is a history, not a whiteboard. The commit that added the secret is still there, reachable by anyone who clones the repository or reads it on the hosting provider. The delete only changed the current state; the credential lives on in the past, fully intact, one git log -p away.
This is why leaked secrets in source control are such a durable problem. The exposure window is not the few minutes the line was on the tip of the branch — it is every moment from the commit that added it until the credential is actually rotated. For a public repository, that window is often measured in seconds before an automated scanner finds it, because attackers watch public code pushes precisely for this. For a private repo it is slower, but a private repo becomes public more often than anyone plans for: a fork, a misconfigured visibility toggle, a departing contributor's local clone.
Why this is a watch problem, not just a hygiene problem
A team that has read the secrets management playbook already knows the goal — credentials belong in a vault or an environment, never in code. But the gap between the policy and reality is exactly where leaks live, and you close that gap by looking, continuously, rather than trusting that everyone remembered the rule on every commit. Your repositories are part of your external attack surface: a public repo, a public gist, an old fork on a personal account. Each is a place a secret can surface, and none of them is watched unless you decide to watch it.
- The commit history, not just the current tree — a scanner that only checks the tip misses the deleted-but-still-present key entirely.
- Every branch and every fork, because the secret you cleaned from
mainmay still be alive on an abandoned feature branch or a fork you forgot existed. - Public code beyond your own org — an employee's personal account, a public paste, a Stack Overflow answer with a real key left in. These sit outside your repos but leak your credentials all the same.
When a scanner hits, rotation is the fix — not deletion
The reflex when a secret scanner fires is to reach for the history-rewriting tools and scrub the credential out of every commit. That is worth doing, but it is the second step and it is not the one that closes the exposure. The credential has been public; you must assume someone copied it. The only action that actually revokes the attacker's access is rotating the secret at its source — issuing a new key, invalidating the old one, changing the password. History surgery makes the repo clean; rotation makes the credential safe. Do them in that order and never skip the second.
That is why a leaked secret is not a cleanup task, it is a finding with an owner and a clock. And its severity follows the same exposure-first triage as everything else in the program — ranked by what the leaked credential can reach:
- A live production database credential in a public repo is a five-alarm fire: rotate now, then investigate access.
- An expired test token in a private repo is real but lower — rotate on a reasonable clock and record why.
- Tie the severity to the blast radius using your data classification: a key that unlocks restricted customer data earns the shortest deadline, a read-only key to a public dataset waits behind it.
Feeding every hit through the same remediation workflow — owner, severity, deadline — is what keeps a leaked-secret alert from becoming just another line in a channel nobody reads.
Prevention lowers the noise, monitoring catches the rest
Watching is the safety net; you still want fewer things falling into it. The controls a lean team can finish:
- Pre-commit and server-side secret scanning so a credential is caught before it ever reaches shared history — the cheapest place to stop a leak is the commit that would have created it.
- A rotation runbook you have actually run, so the response to a hit is a fifteen-minute procedure and not an improvised scramble. This is the same incident-response discipline applied to a narrow, common event.
- Short-lived and scoped credentials wherever possible, so a leaked key is both less powerful and expires on its own — the least-privilege principle turned toward secrets.
- A standing scan of the history, not a one-time cleanup, because new leaks arrive on the schedule of human error, which is to say constantly.
The evidence it produces
An assessor asking how you protect credentials will want more than a policy that says "no secrets in code." They will want to know how you detect violations of that policy and what happens when you find one. A record that your repositories are continuously scanned, that hits become tracked findings, and that the response is rotation-then-cleanup with dates attached is exactly that answer — and it drops into continuous monitoring and evidence collection so you are proving the control over time, not reconstructing it the week before a review.
One honest caveat: a platform can watch your repositories and public code for leaked credentials, raise a tracked finding when one surfaces, and keep the record of detection and response current for an auditor — it organizes, watches, and proves the work. It does not rotate your keys, rewrite your history, or configure your vault for you, and it does not grant or guarantee any certification; the rotation, the cleanup, and the prevention controls are operational steps your team owns, and which notification obligations a leaked credential triggers is a question for counsel.
Git never forgets, so deleting the line that held a secret does nothing — the credential lives in the history until you rotate it. Scan the whole history and every fork, treat each hit as a finding ranked by what the key can reach, and remember that the fix is rotation, not deletion. Watch your own repositories for the thing you already told everyone not to do.