Detectar secrets
detect-secrets roda em todo PreToolUse de git commit e
falha a chamada se algum arquivo staged contiver um padrão de
credencial reconhecível. É a segunda linha de defesa depois da
convenção .env.octopus / .gitignore — a linha que pega o
momento em que uma credencial nova aparece inline em um config
ou em um script.
Por que isso existe
Secrets hardcoded são a causa dominante de vazamento de
credenciais em repositórios públicos. A relação sinal-ruído é
alta: secrets reais seguem gramáticas estreitas (sk_live_… para
Stripe, xoxb-… para Slack, AKIA… para AWS access keys, ghp_…
para GitHub tokens, JWT com três segmentos base64), então a
detecção por regex pega a grande maioria dos commits acidentais
com pouquíssimos falsos positivos.
O hook roda antes do commit ser criado, então um secret bloqueado nunca entra no histórico do git — nem mesmo local. Isso importa: uma vez que um secret entra em um objeto de commit, nem amend e force-push sempre conseguem apagá-lo de forks, mirrors e caches.
Padrões detectados
O ruleset atual cobre os providers que aparecem nos arquivos
.env.example deste codebase mais alguns de alto impacto
adicionados defensivamente:
- AWS access key IDs (prefixos
AKIA,ASIA) - Chaves Stripe live e test (
sk_live_,sk_test_,pk_live_) - SendGrid (
SG.…) - Slack bot e user tokens (
xoxb-,xoxp-,xoxa-) - GitHub personal access tokens (
ghp_,gho_,ghu_,ghs_,ghr_) - Chaves OpenAI (
sk-proj-…,sk-…) - JWTs genéricos (três segmentos base64url separados por pontos)
- Blocos de chave privada (
-----BEGIN … PRIVATE KEY-----)
Falsos positivos
Os padrões são apertados, mas os padrões de JWT e de chave genérica podem dar match em dois lugares legítimos:
- Valores de exemplo em docs e READMEs — placeholders que por
acaso têm o formato real (
sk-test-xxxxxxxx…). - Testes inline do próprio detector de secrets.
Para docs e tests, a convenção é usar prefixo ou sufixo com
example, placeholder, XXXX, ou usar caracteres
deliberadamente inválidos para o padrão não dar match. Quando um
falso positivo real acontecer, registre como bug e aperte a
regex — não adicione um ignore inline.
Como burlar
Não existe marcador de bypass por design. Se um valor parece um
secret para o hook, parece para um leitor futuro também — corrija
o valor (mova para .env.octopus, rotacione, ou substitua por um
placeholder claramente falso) em vez de anotar contornando o
aviso.
Combinação com a skill audit-security
detect-secrets pega o momento da introdução acidental. A skill
audit-security pega secrets que escaparam antes — rodando um
scan mais amplo na working tree, no histórico e nos arquivos
.env*. São complementares: um é um gate PreToolUse rápido, o
outro é uma passada de auditoria deliberada antes do merge.