I Accidentally Committed an API Key to Git: Now What?

Published March 9, 2026 · 9 min read · By SPUNK LLC

It happens to nearly every developer at least once. You are moving fast, testing a feature locally, and before you realize it, you have pushed a commit containing a plaintext API key to a public GitHub repository. Within seconds, automated scanners have found it. Within minutes, someone may already be using it. Here is exactly what to do, step by step, and how to make sure it never happens again.

Step 1: Revoke the Key Immediately

This is the single most important action, and it must happen before anything else. Do not waste time trying to remove the commit first. Every second the key remains active is a window for abuse.

Go to the API provider's dashboard and either revoke, rotate, or regenerate the key. Most major providers have one-click revocation:

Generate a new key and store it in your secrets manager (not in code). Update your application to use the new key. Only after the old key is fully revoked should you move to the next step.

Step 2: Assess the Damage

Before cleaning your git history, figure out how much exposure occurred:

Check the API provider's audit logs for any requests made with the compromised key that you did not originate. For AWS, check CloudTrail. For Stripe, check the event log. For Google Cloud, check the Activity Log.

Step 3: Remove the Key from Git History

Simply making a new commit that deletes the file or replaces the key does not help. The old key is still visible in the commit history. You need to rewrite history to fully remove it.

Option A: BFG Repo-Cleaner (Recommended)

BFG is faster and simpler than git filter-branch. It is specifically designed for removing unwanted data from git repositories.

# Install BFG (requires Java)
brew install bfg

# Create a file listing the strings to remove
echo "sk_live_abc123yoursecretkey" > passwords.txt

# Clone a bare copy of the repo
git clone --mirror git@github.com:you/your-repo.git

# Run BFG to replace the secret with ***REMOVED***
bfg --replace-text passwords.txt your-repo.git

# Clean up and push
cd your-repo.git
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git push --force

Option B: git filter-repo

If you prefer staying within the git ecosystem, git filter-repo (the modern replacement for git filter-branch) works well:

# Install git-filter-repo
pip install git-filter-repo

# Replace the secret in all files across all history
git filter-repo --replace-text expressions.txt

# expressions.txt format:
# literal:sk_live_abc123yoursecretkey==>***REMOVED***
Warning

Both BFG and git filter-repo rewrite commit hashes. Every collaborator must re-clone the repository after the force push. Coordinate with your team before running these commands.

Step 4: Check for Cached Copies

Even after rewriting git history, copies of your key may still exist in:

Step 5: Prevent It from Happening Again

Install pre-commit hooks

The most effective prevention is catching secrets before they enter git. These tools scan staged changes and block the commit if secrets are detected:

# Option 1: git-secrets (AWS-focused but extensible)
brew install git-secrets
cd your-repo
git secrets --install
git secrets --register-aws

# Option 2: detect-secrets (Yelp's tool, broader coverage)
pip install detect-secrets
detect-secrets scan > .secrets.baseline
detect-secrets-hook --baseline .secrets.baseline

# Option 3: gitleaks (fast, comprehensive)
brew install gitleaks
# Add to .pre-commit-config.yaml:
# - repo: https://github.com/gitleaks/gitleaks
#   rev: v8.18.0
#   hooks:
#     - id: gitleaks

Use environment variables properly

# Bad: hardcoded in source
API_KEY = "sk_live_abc123"

# Good: loaded from environment
import os
API_KEY = os.environ["STRIPE_API_KEY"]

# Better: loaded from a secrets manager
import boto3
client = boto3.client('secretsmanager')
secret = client.get_secret_value(SecretId='prod/stripe/api-key')
API_KEY = json.loads(secret['SecretString'])['api_key']

Configure .gitignore

# Add to .gitignore
.env
.env.local
.env.production
*.pem
*.key
config/secrets.yml
credentials.json

Enable GitHub's push protection

GitHub offers free secret scanning and push protection for public repositories. When enabled, GitHub blocks pushes that contain recognized secret patterns (API keys, tokens, private keys) before they reach the repository. Enable it in your repository settings under Security → Code security and analysis → Push protection.

How Fast Do Scanners Find Exposed Keys?

Research from security firms and independent studies shows that exposed credentials on public GitHub repositories are discovered incredibly quickly:

This is why revocation must be your first action, not cleaning the git history. The key must be considered burned the moment it is pushed.

What If It Was a Private Repository?

The risk is lower but not zero. Private repository keys can still leak through:

Best practice: treat private repos with the same hygiene as public repos. Never commit secrets to any repository. Use a secrets manager or environment variables for all credentials.

Key Takeaway

Accidentally committing an API key is recoverable, but only if you act fast. The priority order is: (1) revoke the key immediately, (2) assess damage, (3) clean git history, (4) check cached copies, (5) install prevention tools. The entire process should take less than 30 minutes. The prevention setup takes 10 minutes and saves you from ever repeating the experience.

Recommended Resources

To deepen your understanding of credential security and prevention techniques, these resources are highly recommended: