Scan every commit reachable from every branch and tag, looking at the changes each commit introduced, not only the files at the tip. Use a scanner built for history, or a manual search with Git's own log options. Then revoke whatever you find, because a deleted secret is still in history.
Why the latest files are not enough
Developers often remove a key in a later commit. The file looks clean, but the old commit still holds the value, and anyone with repository access can read it. GitHub's secret scanning documentation says it scans the entire Git history on all branches, for this reason. Your own tooling should do the same.
Steps for a full history scan
- Make a fresh, full clone. A shallow clone hides older commits.
- Fetch all branches and tags, not just the default branch.
- Run a history aware scanner across all refs. Make sure it reads commit diffs.
- Collect findings with the commit, file and author date.
- Check each against the provider to see if it is still live.
- Revoke and rotate live ones, then record the result.
A manual search with Git
For a quick check before you adopt a tool, git log can walk everything. The --all option treats every ref under refs/, plus HEAD, as a starting point. Combine it with a patch view and a search.
git log --all -p -G "AKIA[0-9A-Z]{16}" --oneline
The -G option, a pickaxe search, shows commits whose changes add or remove a line matching the pattern. The example looks for the shape of an AWS style access key ID. Swap in the format your own systems use. This is a spot check, not a substitute for a scanner with many rules.
What a history scan can miss
| Gap | Why | What to do |
|---|---|---|
| Shallow clones | Old commits not present | Use a full clone |
| Other copies | Forks and local clones keep old data | Treat the secret as exposed, rotate |
| Unreferenced commits | Not reachable from any branch | Ask your host about dangling data |
| Secrets in other places | Issues, wikis, images, logs | Scan those separately |
| Unknown formats | No rule matches | Add custom rules, see below |
For the last row, see writing a custom detection rule.
After the scan
Rotation comes first. Rewriting history is optional and has costs: GitHub's own guidance says history rewriting can be destructive and disruptive, may need force pushing, and is often unnecessary once the secret is revoked. OWASP notes it can also break links to commits. Our post on what survives a history rewrite goes through that decision.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how repeated checks catch things a one time scan would miss.
Quick check
How often should I scan history?
Scan it fully once when you adopt a tool, then scan new commits on every push or pull request. Rescan fully when you add new detection rules.
Does scanning history change my repository?
No. Scanning only reads. Any cleanup, such as a rewrite, is a separate decision.
Safeguard offers repository scanning, and you can run a free scan to see findings for a repository.
Sources
- Git documentation: git log
- GitHub docs: about secret scanning
- GitHub docs: remediating a leaked secret
- OWASP Secrets Management Cheat Sheet
Last reviewed: 19 October 2026.