O segredo que você apagou ainda está no histórico do Git
Semana passada abri um repositório pra revisar e, antes de qualquer coisa, rodei o de sempre:
git log -p | grep -i -E "(api[_-]?key|secret|password|token)"
Achei uma AWS_SECRET_ACCESS_KEY num commit de oito meses atrás. O detalhe: o .env que continha ela já tinha sido apagado do projeto fazia tempo. No HEAD, nada. No histórico, lá estava, em texto puro.
Esse é o mal-entendido que mais vejo. Apagar o arquivo (ou dar git rm) tira o segredo do estado atual, não do histórico. O Git é append-only: todo commit que já teve aquela chave continua guardando ela, e qualquer pessoa com acesso ao repo faz git log -p e lê.
Como checar de verdade, no histórico inteiro e não só no HEAD:
git log -p -S 'AKIA' --all
# ou uma ferramenta dedicada
docker run --rm -v "$(pwd):/repo" zricethezav/gitleaks detect --source /repo
gitleaks e trufflehog varrem o histórico com regex e entropia. Rodam em segundos e pegam o que o grep manual deixa passar.
Achou? Duas coisas, nesta ordem:
- Rotacione a chave agora. Se foi commitada, considere vazada. Purgar o histórico não desvaza o que já esteve ao alcance de alguém.
- Depois limpe o histórico, se fizer sentido:
# BFG é mais simples que git filter-branch
bfg --replace-text passwords.txt
git reflog expire --expire=now --all && git gc --prune=now --aggressive
Reescrever histórico muda os hashes de todos os commits afetados. Combine com o time antes: todo mundo vai precisar reclonar.
O passo que quase todo mundo pula é o primeiro. Já vi gente gastar uma tarde no filter-branch e esquecer de rotacionar a chave — que era o único passo que realmente importava.
Melhor ainda: deixa um job de gitleaks no CI, quebrando o merge quando aparecer segredo novo. É barato e evita a arqueologia depois.
Versão completa no blog: https://revin.com.br/pt/blog/o-codigo-que-passa-no-pitch-e-reprova-na-due-diligence