Q38 of 40 · Git
A QA engineer discovers that an API key was committed to the test repository 6 months ago and is still in Git history. What is your remediation plan?
Short answer
Short answer: Immediate: revoke the key. Then rewrite history with `git filter-repo --path-glob '*.env' --invert-paths` or a text replacement filter. Force-push all branches, require all team members to re-clone, and notify GitHub secret scanning. The key must be rotated even after history rewrite.
Detail
History rewrite cannot be the only step — the key was exposed and must be treated as compromised regardless of whether history is cleaned. Any system that ever cloned the repo, any CI logs, any GitHub/GitLab diff views may have cached it.
Immediate triage:
- Revoke/rotate the key immediately — don't wait for history rewrite.
- Check access logs for the key in your API provider's dashboard.
- Assess blast radius: what does the key have access to?
History rewrite with git filter-repo (the modern successor to the deprecated git filter-branch):
- Remove a whole file:
git filter-repo --path secrets/.env --invert-paths - Replace a string everywhere:
git filter-repo --replace-text replacements.txtwherereplacements.txtcontainsACTUAL_KEY==>REDACTED
After the rewrite, all commit SHAs in the affected history change, so all branches must be force-pushed and all team members must re-clone (their clones contain the old history with the secret).
Platform cleanup:
- GitHub: contact support to purge caches. GitHub's secret scanning alerts will persist until acknowledged.
- GitLab: use the "Remove blob" API endpoint.
Prevention: enable GitHub secret scanning (free for public repos, available on Enterprise). Use git-secrets or gitleaks as pre-commit hooks. Never store real credentials in test fixture files — use environment variables or a secrets manager.
// EXAMPLE
# Step 1: rotate the key (do this FIRST, outside of Git)
# ... revoke in AWS/API provider dashboard ...
# Step 2: remove the file from all history (modern approach)
pip install git-filter-repo
git filter-repo --path config/test.env --invert-paths
# Or: replace just the secret string everywhere in history
cat > replacements.txt << 'EOF'
ACTUAL_API_KEY_VALUE_HERE==>REDACTED_ROTATE_THIS_KEY
EOF
git filter-repo --replace-text replacements.txt
# Step 3: force-push ALL branches (coordinate with team first)
git push --force --all origin
git push --force --tags origin
# Step 4: all teammates must re-clone (old clones still have the secret)
# rm -rf repo && git clone https://github.com/company/repo.git
# Step 5: expire the reflog and GC to remove local dangling objects
git reflog expire --expire=now --all
git gc --prune=now --aggressive
# Prevention: add gitleaks pre-commit hook
cat > .pre-commit-config.yaml << 'EOF'
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.2
hooks:
- id: gitleaks
EOF// WHAT INTERVIEWERS LOOK FOR
// Related questions
How would you implement a pre-commit hook that blocks QA engineers from committing test files containing skipped tests or hard-coded credentials?
Git
How do you secure secrets (API keys, credentials) in a CI pipeline running QA tests?
CI/CD & DevOps
Tell me about a time you found a critical bug — what happened?
Behavioural