Skip to content
matthewcm.dev

    ↑ ↓ move · ↵ open · tab scopeopen graph →

    Removing Secrets from Git History

    Scan for leaks, rotate first, rewrite history with regex patterns rather than literal lists, and add a pre-commit scanner so it never happens again.

    Growingtended planted 1 min read
    On this page

    Running a secret scanner over an old repository is a humbling experience. Mine found tokens scattered across years of history: test credentials, pasted bearer tokens, config that should never have been committed. Here’s the process I’d follow again.

    1. Rotate first

    Before touching history, revoke and rotate every secret found. Rewriting history doesn’t make a leaked secret safe: other clones still have it, and the host keeps old objects until its garbage collection runs. Rotation is the fix; rewriting is the clean-up.

    2. Find everything

    Tools like Gitleaks scan both file contents and commit history. In CI, scan just the commits in the current change so pipelines stay fast:

    gitleaks detect --log-opts="main...HEAD"

    3. Rewrite with patterns, not lists

    My first attempt used a literal list of the secrets found. It missed variants: the same kind of token with different contents. Regex patterns caught them all. With BFG Repo-Cleaner (or the maintained alternative, git filter-repo --replace-text), a pattern matching the token format replaces every occurrence across history.

    4. Expect friction

    • Prune dead branches first. Less history to rewrite, fewer surprises.
    • Hidden refs (merge-request refs on hosted Git) can’t be force-pushed and will make the push partly fail.
    • Big rewrites are heavy. Force-pushing a long rewritten history can strain the host. Do it in a quiet window and warn the team that everyone needs a fresh clone.

    5. Make it not happen again

    Add the scanner as a pre-commit hook and as a pipeline step. Expect teething problems: ignore files not honoured in CI, hooks that fail to install on some machines. Fix those quickly or people will route around the tool.

    In practice

    I did this on a large frontend repo and then rolled secret scanning out to a handful of related repositories. Most of the effort wasn’t the rewrite; it was making the prevention stick. It’s a textbook case for Shift Left Testing: a scanner before commit costs seconds, and a rewrite after the fact costs days.

    • #security
    • #git
    • #secret-scanning
    • #gitleaks
    • #devsecops

    ↪ Links to (1)