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
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
Step 2: Delete from History
cd your-project
bfg --delete-files ".env" --no-blob-protection .
Output:
Deleted files:
Deleted 4 commits
Deleted 12 blob(s)
...
Step 3: Clean Up
git reflog expire --expire=now --all
git gc --prune=now --aggressive
Step 4: Verify
git log --all --full-history --name-only | grep ".env"
# (no output = success)
Step 5: Force Push
git push origin main --force-with-lease
Before & After
Before BFG:
$ git log --oneline | head -5
abc1234 Remove .env from version control
def5678 Enable SSL certificate verification
ghi9012 Standardize dependencies
After BFG:
$ git log --oneline | head -5
xyz3456 Remove duplicate service definition
uvw7890 Standardize dependencies
rst1234 Enable SSL certificate verification
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
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"
2. Create .env.example
# .env.example
ANTHROPIC_API_KEY=your-key-here
SUPABASE_URL=your-url-here
TELEGRAM_BOT_TOKEN=your-token-here
3. Use GitHub Actions Secrets
# .github/workflows/deploy.yml
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
SUPABASE_KEY: ${{ secrets.SUPABASE_KEY }}
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
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%)
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)