Pular para o conteúdo

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.

Fonte: hooks/pre-tool-use/detect-secrets.sh