Your git history is leaking secrets right now
A secret committed once lives in git history indefinitely, survives deletion, and copies itself into every clone, fork, and artifact. The remediation is rotation, not history rewriting; the prevention is history-deep scanning with baselines that gate only on new leaks. If you have never scanned full history, assume findings.
There is a specific moment every security team experiences once: the first full-history secrets scan of a mature repository. The working tree is clean. The history returns dozens of live credentials, some committed by people who left years ago. If your organization has not had that moment yet, it is scheduled; the only question is whether you run the scan or an attacker does.
Why deletion does not delete
Git is an immutable ledger by design. A credential committed years ago and removed the same week still exists in every clone of the repository, retrievable by anyone who can read the repo with a one-line command. It also propagates: into forks, into mirrors, into CI caches, into the vendored copies inside build artifacts. Public-facing incidents keep confirming the pattern, from corporate breaches that began with a token in a repository to research repeatedly showing thousands of live credentials sitting in public git history.
The corollary that surprises teams: repo access is credential access. Every contractor, every CI system, and every backup that can read the repository can read every secret ever committed to it.
Where secrets actually hide
Working-tree scans miss most of the problem. A serious sweep covers:
- Full commit history, every branch, because that is where the deleted-but-not-gone credentials live.
- Archives and build artifacts: credentials get baked into packages, container images, and compressed bundles, then distributed to places the repo never went.
- Encodings: base64-wrapped configs and nested archives defeat naive matching; content must be decoded before detection. SecuSecret unwraps these layers as a matter of course.
The remediation people get wrong
The instinct is to rewrite history and purge the secret. Resist it as a primary response. History rewriting is disruptive to every clone, and worse, it quietly implies the secret is now safe, when every pre-rewrite clone, fork, and cache still holds it.
The only remediation that works is rotation. The exposed credential must die at its issuer: revoked, reissued, and the new one stored properly. Treat the sequence as fixed: rotate first, then optionally clean history for hygiene, never the reverse. A found-in-history credential should be assumed compromised, because you cannot prove who cloned the repo in the intervening years.
Staying clean without drowning in alerts
The steady state to aim for has three parts:
- A baseline of judged findings. The first history scan produces a pile; each item gets a decision, rotate or accept with justification, recorded against a stable fingerprint so the decision persists across rescans.
- CI gates on new leaks only. With the baseline in place, the pipeline fails a merge only when a genuinely new secret appears, which keeps the gate trusted and catches leaks within minutes of commit, when rotation is cheapest.
- Detection that never exfiltrates. A subtle point: some tools verify candidate secrets by calling the real cloud provider with them, which transmits your credentials outward as a feature. In restricted environments that is disqualifying; detection should be provider-aware but fully local.
The uncomfortable audit question
Vendor assessments and regulators have started asking the direct version: do you scan version-control history for credentials, and what happened to what you found? A working-tree-only answer earns a follow-up. A baseline-plus-gate answer, with rotation records, closes the topic.
The first history scan is the hard one, organizationally: it always finds something, and the findings always have awkward timestamps. Run it anyway, on your own schedule, inside your own network, before someone else runs it on theirs.