Skip to content

Guide

Secrets in Git history: why deleting a key isn't enough

4 minute read · Published

Why deleting a key from your code doesn't erase it from history

When you delete an API key from a file and commit the change, git doesn't remove the earlier version: it just adds a new commit on top. Anyone with access to the repository can use `git log` or `git show` to go back to that older version and read the key exactly as it was written, even years later.

This also applies to repositories that later become private or public, to forks that already existed, and to mirrors that some collaborator may have cloned before the file was fixed. If the repository passed through GitHub, GitLab, or another provider, external caching or indexing systems may have kept a copy of that older version.

The right steps: rotate the key and rewrite the history

The first step isn't technical: it's rotating the key with the corresponding provider (Stripe, AWS, SendGrid, etc.) so the leaked version stops being valid. Rewriting history without invalidating the key leaves the problem intact, because any local copy that already exists will still hold the active key.

After that, you can use `git filter-repo` or BFG Repo-Cleaner to remove the file or string from every commit, and force a push with the rewritten history. You need to tell any collaborators to re-clone the repository, because their old local copies will still contain the original commits with the key.

What Audixa reviews in the source code

Audixa reviews the source code submitted for analysis and looks for secret patterns: API keys, access tokens, database connection strings, and similar credentials written directly into configuration files or code. The report shows the file and line where each match appears so you can review it.

This review focuses on the current state of the submitted files, not on running the project or walking through the entire git commit history. If you suspect a key was exposed in earlier versions, it's worth doing a separate search through the history with tools like `git log -p` or scanners built for that purpose.

Good practices to keep this from happening again

One way to reduce this risk is to avoid storing secrets in versioned files from the start: use environment variables loaded outside the repository, or a dedicated secrets manager. A pre-commit hook that blocks known key patterns also helps stop the problem before it reaches the history.

Reviewing the project before each launch, not just once, helps catch secrets added by mistake in recent changes before they pile up in more commits. The /resources/security-checklist-before-you-launch page covers other points to check before publishing an application.

Payment-provider secrets: a frequent case

A common case in projects with payments is storing a Stripe or other provider's secret key directly in frontend code, where it's visible to any site visitor, in addition to being in the git history. This kind of mistake often coexists with others, like a webhook endpoint that doesn't validate the request signature.

Audixa can flag when a key like this appears in the submitted code, and when a payment webhook doesn't check the signature before processing the event, two mistakes that often show up together in integrations built quickly. Fixing both reduces the risk of someone spoofing payment events or using the leaked key outside its intended context.

Continue from here

Have the repeatable checks run for you

One project and one scan a month are free. You see how many findings there are and how severe they are; titles and evidence unlock on a paid plan.

Analyze my projectBack to the guides

Start free. No automatic changes to your code.