DEV Community

JustJinoIT
JustJinoIT

Posted on

Removing API Keys from Git History: BFG + Force Push (A Security Incident Response)

Published on: 2026-06-06

Reading time: 5 min

Tags: #security #git #devops #secrets

The Situation

API keys were committed to .env file in Git history. Anyone with repo access could do git log and see them.

git log --all --full-history --name-only | grep ".env"
# abc1234 Remove .env from version control
# def5678 Initial commit: Contest Agent
Enter fullscreen mode Exit fullscreen mode

Immediate risk:

  • Clone repo → check git history → steal API keys
  • If pushed to GitHub, keys are potentially searchable/cached

Solution: BFG Repo-Cleaner

Better than git filter-branch (faster, safer):

Step 1: Install BFG

brew install bfg
Enter fullscreen mode Exit fullscreen mode

Step 2: Delete from History

cd your-project
bfg --delete-files ".env" --no-blob-protection .
Enter fullscreen mode Exit fullscreen mode

Output:

Deleted files:
  Deleted 4 commits
  Deleted 12 blob(s)
  ...
Enter fullscreen mode Exit fullscreen mode

Step 3: Clean Up

git reflog expire --expire=now --all
git gc --prune=now --aggressive
Enter fullscreen mode Exit fullscreen mode

Step 4: Verify

git log --all --full-history --name-only | grep ".env"
# (no output = success)
Enter fullscreen mode Exit fullscreen mode

Step 5: Force Push

git push origin main --force-with-lease
Enter fullscreen mode Exit fullscreen mode

Before & After

Before BFG:

$ git log --oneline | head -5
abc1234 Remove .env from version control
def5678 Enable SSL certificate verification
ghi9012 Standardize dependencies
Enter fullscreen mode Exit fullscreen mode

After BFG:

$ git log --oneline | head -5
xyz3456 Remove duplicate service definition
uvw7890 Standardize dependencies
rst1234 Enable SSL certificate verification
Enter fullscreen mode Exit fullscreen mode

Unnecessary commits removed, history cleaned.

BFG vs git filter-branch

Factor git filter-branch BFG
Speed Slow (1000+ commits) Fast
Safety Complex, error-prone Simple, clear feedback
Usability Requires scripting One-liner
Recommendation

CRITICAL: Rotate API Keys

Cleaning git history is step 1. Step 2 is mandatory:

Timeline: Do This Immediately

Within 1 hour:

# Anthropic
# → https://console.anthropic.com/account/keys
# → Delete old key, generate new one

# Supabase
# → https://app.supabase.com → Settings → API
# → Click "Reset secret key"

# Telegram
# → Open @BotFather
# → /token → select bot → /revoke
# → Generate new token
Enter fullscreen mode Exit fullscreen mode

Within 24 hours:

  • Update all deployed servers with new keys
  • Test that services still work
  • Monitor logs

Best Practices Going Forward

1. Initialize Correctly from Day One

# First thing in new project:
echo ".env" >> .gitignore
git add .gitignore
git commit -m "Add .env to .gitignore"
Enter fullscreen mode Exit fullscreen mode

2. Create .env.example

# .env.example
ANTHROPIC_API_KEY=your-key-here
SUPABASE_URL=your-url-here
TELEGRAM_BOT_TOKEN=your-token-here
Enter fullscreen mode Exit fullscreen mode

3. Use GitHub Actions Secrets

# .github/workflows/deploy.yml
env:
  ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
  SUPABASE_KEY: ${{ secrets.SUPABASE_KEY }}
Enter fullscreen mode Exit fullscreen mode

4. Add Pre-Commit Hook (Optional)

#!/bin/bash
# .git/hooks/pre-commit

if git diff --cached --name-only | grep -E '\.env'; then
    echo "❌ Error: Attempting to commit .env file"
    exit 1
fi
Enter fullscreen mode Exit fullscreen mode

Real Impact (After Remediation)

Before:
- .env in git history
- 79 commits total
- History size: 50MB

After BFG:
- .env removed from all commits
- 75 commits total (4 cleaned)
- History size: 42MB (-16%)
Enter fullscreen mode Exit fullscreen mode

Execution Checklist

Phase 1: Immediate (Next 1 hour)

  • [ ] Run BFG: bfg --delete-files ".env" .
  • [ ] Clean git: git reflog expire ... && git gc ...
  • [ ] Force push: git push origin main --force-with-lease

Phase 2: Rotate (Next 24 hours)

  • [ ] Anthropic API key
  • [ ] Supabase Secret Key
  • [ ] Telegram Bot token

Phase 3: Prevention

  • [ ] Update deployed servers with new keys
  • [ ] Create .env.example
  • [ ] Update .gitignore
  • [ ] Add GitHub Actions secrets
  • [ ] Notify team (force push happened)

Phase 4: Future

  • [ ] Set up pre-commit hooks
  • [ ] Monthly secret audit
  • [ ] Use Secret scanning tools (GitHub, GitLab)

Key Takeaway

API key exposure is a security incident, not a "mistake."

  • Act fast (BFG)
  • Rotate keys (mandatory)
  • Document the response
  • Prevent recurrence

Your security posture will be better for it—and you'll have a good story for the next security audit.

Top comments (0)