DEV Community

Clay Pask
Clay Pask

Posted on

Your AWS keys are in git history — here's how to remove them

GitHub just sent you a secret scanning alert. Or maybe you noticed your AWS bill jumped overnight. Either way, you've got credentials in your git history and you need them gone.

Here's the complete guide to removing secrets from git history — and how to make sure it never happens again.

Why deleting the file isn't enough

This is the most common mistake:

git rm .env
git commit -m "remove env file"
git push
Enter fullscreen mode Exit fullscreen mode

That removes the file from the current state of the repo. But anyone who clones it can still run:

git log -p | grep AWS_ACCESS_KEY
Enter fullscreen mode Exit fullscreen mode

And see your secret in full. Every commit that ever contained your .env file is permanently stored in git history — until you rewrite that history.

Step 1: Rotate your credentials immediately

Before doing anything else — rotate the exposed credentials. Assume they're already compromised. AWS keys, Stripe keys, GitHub tokens — rotate them all before proceeding.

Git history rewrites take time. The keys might already have been scraped.

Step 2: Check what's in your history

# Check if any .env files were ever committed
git log --all --full-history -- "*.env" ".env*"

# Search for specific patterns in history
git log -p --all | grep -E "AKIA[0-9A-Z]{16}"  # AWS keys
git log -p --all | grep -E "sk_(live|test)_"    # Stripe keys
Enter fullscreen mode Exit fullscreen mode

Or use GitCleanse to do it automatically:

npm install -g gitcleanse
gitcleanse scan           # scans full history for secrets
gitcleanse check          # quick .env check
Enter fullscreen mode Exit fullscreen mode

Step 3: Remove from history

Option A: git-filter-repo (recommended)

Install it first:

pip install git-filter-repo
Enter fullscreen mode Exit fullscreen mode

Remove specific files:

git filter-repo --path .env --invert-paths --force
git filter-repo --path .env.production --invert-paths --force
Enter fullscreen mode Exit fullscreen mode

Option B: BFG Repo Cleaner

# Install BFG
brew install bfg  # macOS

# Remove files
bfg --delete-files .env
git reflog expire --expire=now --all && git gc --prune=now --aggressive
Enter fullscreen mode Exit fullscreen mode

Option C: git filter-branch (always available, slower)

git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch .env .env.production' \
  --prune-empty --tag-name-filter cat -- --all

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

Or generate these commands automatically:

gitcleanse clean --auto --output cleanup.sh
# Review cleanup.sh, then:
bash cleanup.sh
Enter fullscreen mode Exit fullscreen mode

Step 4: Force push to remote

⚠️ Coordinate with your team first. This rewrites history — everyone will need to re-clone.

git push origin --force --all
git push origin --force --tags
Enter fullscreen mode Exit fullscreen mode

Step 5: Ask GitHub/GitLab to purge caches

Even after rewriting history, hosted services may cache old objects. Contact GitHub support or go to Settings ‚Üí Danger Zone and request a cache purge.

Step 6: Prevent it from happening again

Add to .gitignore:

.env
.env.*
!.env.example
Enter fullscreen mode Exit fullscreen mode

Use EnvGuard as a pre-commit hook:

npm install -g envguard
# .git/hooks/pre-commit:
envguard audit --strict
Enter fullscreen mode Exit fullscreen mode

It'll catch secrets before they're ever committed.

TL;DR

  1. Rotate all exposed credentials immediately
  2. Use git filter-repo to remove the file from history
  3. Force push to remote
  4. Ask GitHub to purge caches
  5. Add .env to .gitignore and use a pre-commit hook

The whole process takes about 15 minutes once you know the steps. The pain is in not knowing them at 2am when the alert hits.

Top comments (0)