You just noticed your API key is visible in your Git history. Maybe you pushed a .env file by habit, pasted a test credential into a script and forgot to remove it, or committed a screenshot of a dashboard during a support call. Whatever the path, the key is now part of the repository’s permanent record.

The hardest part of this situation is not the technical cleanup. It is the first ten minutes, when every instinct tells you to delete the commit, close the laptop, and hope the internet forgets you existed. That instinct is wrong, but it is understandable. Let us walk through exactly what to do, and more importantly, what not to do, while the window for damage control is still open.

The One Thing That Actually Matters

Delete the key from your latest commit. Push the change. Wait for relief. This is the most common reaction, and it is also the most dangerous thing you can do if you treat it as the solution. Git records every commit forever. If someone cloned your repository, forked it, or if a search engine indexed the raw commit before you removed it, the key still exists outside your control. Re-adding the key value to a later commit does not erase the earlier one. The secret is in the history. The history is public.

The single action that neutralises the threat is revocation. Go to the API provider’s dashboard right now and disable or delete the compromised credential. Generate a new one only after the old one is dead. Only then does it make sense to touch your Git history, because rotating the key first means any further work on the repository is protecting something that no longer has a valid exposure path.

This is counterintuitive for most developers who were taught that the repository is the source of truth. In a breach, the source of truth is the provider’s permission system, not your commit graph.

Step One: Revoke and Rotate Immediately

Open the dashboard for every service that uses the exposed key. Stripe, OpenAI, AWS, Twilio, any database provider, any analytics tool with a secret component. Revoke or delete the compromised credential in each one. Generate a replacement only after the old one cannot be used again.

There is no shortcut here. If you have multiple services using the same key pattern, assume every instance is exposed. A key leaked on GitHub is not limited to the one dashboard you remember putting it in. People paste keys into config files, .env files, hardcoded constants, environment variable declarations, and occasionally into comments that explain what the key does. Every occurrence needs its own rotation path.

While you are in the provider dashboards, check for any unusual activity. Stripe may show refunds you did not initiate. An OpenAI key will show token consumption that does not match your usage patterns. AWS access keys can provision infrastructure you did not request. Document what you see. This audit log will matter if you need to explain the scope of exposure to a co-founder, an investor, or a customer.

Step Two: Understand the Blast Radius

Not every exposed credential carries the same weight. Before you spend an evening rewriting Git history, take two minutes to classify what you actually leaked.

Some keys are designed to be visible. Public client keys for Google Maps, analytics tokens, SDK initialisation values that begin with NEXT_PUBLIC_ or VITE_ prefixes — these are meant to ship in browser bundles. They should still have usage restrictions configured, but exposure of these keys is rarely catastrophic. The worst outcome is usually increased billing or rate-limiting, not data loss.

True secrets are different. AWS access keys, Stripe live keys, database connection strings, OAuth client secrets, and any credential that grants write access, billing authority, or direct data access require immediate revocation. These are the keys that turn a nuisance into a business event.

If you cannot tell whether a key is public-facing or privileged, treat it as privileged. The cost of over-reacting to a client key is a few minutes of checking dashboard settings. The cost of under-reacting to a secret key is measured in refunds, breached compliance, or lost customer trust.

Step Three: Audit Your Repository Carefully

After revoking the key, you need to understand how deeply it lived in your codebase. Run a history scan to identify every commit that ever contained the exposed value. The command varies depending on your setup, but a broad grep across all branches will reveal the scope:

Search through commit diffs for common credential patterns and look for any file that was deleted, since deletion in one commit does not remove the file from earlier commits. You will likely find more than one occurrence. A single leaked key almost never arrives alone. AI coding assistants embed credentials from documentation, developers copy-paste environment variables during debugging, and projects often have several overlapping secret patterns across different files.

Run a full scan across your entire codebase, not just the commit you are worried about. Tools like the kind GitGuardian provides can surface secrets across 40-plus patterns without requiring configuration. The goal is to find every instance before you move on to prevention.

Step Four: Decide Whether to Rewrite History

Revoking the key was step one. Cleaning the repository is step two only if cleaning is possible and useful. If your repository is private and nobody outside your team has cloned it, the practical risk of leaving the old commits is low. You have already revoked the key, so anyone who finds it in history cannot use it.

If your repository is public, the calculation changes. Automated bots scan GitHub within seconds of a push. Forks may already exist. GitHub’s own search indexes commit diffs. In these cases, rewriting history removes the key from future visibility, even though it does not erase past copies that already exist somewhere on the internet.

Two tools can help you scrub secrets from history:

git-filter-repo is the modern recommended approach. It is faster and safer than older methods, but it rewrites history in a way that forces collaborators to re-clone. You install it separately, create a replacements file that maps the secret to a placeholder, and run the filter. The trade-off is clean history at the cost of disrupting anyone who has already cloned the repository.

git-filter-branch is the older built-in alternative. It carries more warnings and more room for mistakes, which is partly why it is less recommended today. It can also force-push rewritten history, with the same collaborative disruption.

Neither tool guarantees the key disappears from the internet. They only ensure it does not appear in your repository going forward. If the key was exposed publicly for any length of time, assume it has already been scraped, cached, or indexed. The history rewrite protects future readers, not past damage.

If you choose to rewrite history, do it after rotation, not before. There is no benefit to scrubbing commits that still reference a live key. Make the key invalid first, then clean the record.

Step Five: Prevent the Next Exposure

Incident response ends when you build a system that makes this mistake harder to repeat. The most effective barrier is a tool that stops secrets from reaching your repository in the first place. Several approaches exist, and each has a different trade-off depending on your workflow.

Pre-commit hooks run checks before every push. They can block commits that contain patterns matching known secret formats. The downside is that hooks are easy to bypass if developers disable them, and they do not protect against commits that reach the repository through other paths.

Push protection on platforms like GitHub can reject commits containing detected secrets before they land in your main branch. This is a server-side guard that cannot be turned off by a local configuration decision. It catches mistakes that pre-commit hooks miss, including accidental pushes from CI systems or force-pushes from collaborators.

Secret scanning services, whether built into your Git platform or provided by external tools, continuously crawl repositories for credential patterns. They do not prevent the leak, but they reduce the window between exposure and discovery from hours or days to minutes. For solo founders who might not notice a leaked key until a billing alert arrives, this early warning is often the difference between a contained incident and a full breach.

Environment variable management is the structural fix. Store every secret in a proper secrets manager or platform-provided environment variable system. Never hard-code credentials in source files, even temporarily. Use .env files only when your framework explicitly supports loading them securely, and add those files to .gitignore immediately.

The Founder Perspective

From the outside, an exposed API key looks like a technical mistake. From the inside, it looks like a business risk. A leaked Stripe key means someone can process charges against your account. A leaked OpenAI key means someone can run up a bill you will have to pay. A leaked AWS key means someone can spin up infrastructure in your name. Each of these outcomes has a direct line to revenue, cash flow, and customer trust.

The reason this guide emphasises revocation over history cleanup is simple: the cost of a leaked key is financial and reputational, not archival. Once the key is invalid, the repository cleanup becomes a housekeeping task, not an emergency. Order matters. Rotation first, then assessment, then prevention.

The tools available to solo founders make this process manageable. Pre-commit scanners, push protection, secret scanning services, and proper secrets management all exist to catch mistakes before they become incidents. The challenge is not the technology. The challenge is building the habit of treating every pushed commit as if it will be public, even when it is not.

If you have already pushed a secret, do not panic. Revoke the key. Audit the scope. Decide whether history cleanup is worth the disruption. Then put a guard in place so the next time you reach for a credential, your workflow catches the mistake before it leaves your machine.


Sources