secretgate — firewall local de segredos para agentes de codificação
Uma credencial nunca deve viajar para uma API de LLM. secretgate impõe isso localmente,
com um mecanismo determinístico (node scripts/secretgate.mjs, sem npm install, sem
chaves): 221 regras convertidas do gitleaks + gates de entropia + cartões verificados por Luhn.
Onde a API de hook do agente permite reescrita, os segredos são redigidos em placeholders
estáveis e restaurados localmente quando o agente os escreve de volta
(redact-and-restore); onde permite apenas bloqueio (prompts no
Claude Code/Codex), o prompt é bloqueado com uma cópia redigida para reenvio.
Ativação → instalação (faça isso primeiro quando a skill for acionada)
Quando esta skill for ativada (o usuário pedir para proteger segredos / instalar secretgate / configurar o firewall), execute o doctor e então conecte o que ainda não estiver conectado. secretgate é uma skill, não um pacote npm — você executa seu próprio bundle:
node scripts/secretgate.mjs status # o que já está conectado
node scripts/secretgate.mjs install --claude-code # hooks + permissions.deny em ~/.claude/settings.json
node scripts/secretgate.mjs install --codex # ~/.codex/hooks.json + [features] hooks = true
node scripts/secretgate.mjs install --opencode # plugin autocontido em ~/.config/opencode/plugin/
node scripts/secretgate.mjs install --all # todos os três
--project escopa a instalação do Claude Code para ./.claude/settings.json.
install fixa uma cópia do bundle em ~/.secretgate/bin/ e conecta o
agente para CHAMAR ESSA cópia, para que continue funcionando após o cache da skill ser removido. Sempre
instrua o usuário a REINICIAR a sessão do agente depois — hooks carregam na inicialização.
Uma vez conectado, a redação é automática e determinística (o hook faz isso, não você).
Comandos
| Comando | O que faz |
|---|---|
status | Doctor: conexão por agente, mecanismo, saúde do cofre, limitações |
| `scan <arquivo | dir |
pipe | stdin -> stdout com segredos redigidos para placeholders |
allow <valor> / allow --rule <id> / allow --path <glob> | Lista de permissões (valores armazenados como SHA-256, nunca em texto claro) |
vault list / vault clear | Inspeciona mapeamentos de placeholders (nunca mostra segredos) |
uninstall --<agente> | Remove exatamente o que foi adicionado pela instalação |
Como a proteção funciona (explique ao usuário quando perguntado)
- Prompts: Claude Code/Codex → bloqueados com uma cópia redigida (adicione
[allow-secret]para ignorar uma vez). OpenCode → redigido silenciosamente no local. - Leituras de arquivos:
.env*, chaves,~/.aws,~/.ssh… são negados completamente (.env.example/.sample/.templatepermanecem legíveis). O valor nunca entra no modelo. - Saída de ferramenta/bash: redigida para placeholders
SECRETGATE_<hash>(Claude Code + OpenCode; Codex ainda não pode reescrever saída). - Restauração: quando o agente escreve um placeholder em um arquivo (Write/Edit),
o valor REAL chega ao disco. A restauração do bash está DESLIGADA por padrão
(proteção contra exfiltração por injeção de prompt) — ative com
restoreBash: trueem~/.secretgate/config.json. - Chamadas de ferramenta limpas: o hook pré-uso-de-ferramenta do Claude Code responde com JSON
mínimo (
{}, sem decisão = fluxo de permissão normal) em vez de stdout vazio. Saída vazia do hook aciona um bug do Claude Code (anthropics/claude-code#77782) que força uma solicitação de permissão interativa em cada chamada de ferramenta correspondente, mesmo em modo automático — e o valor de decisão documentado"defer"é rejeitado pelo Claude Code <= 2.1.212, então{}é a abstenção que funciona em todos os lugares.
NÃO coberto (seja honesto com o usuário)
- Menções inline
@filedo Claude Code sem acionar hooks de ferramenta (regras permissions.deny são a única cobertura lá). - Execuções não interativas do Codex (
codex exec) — bug upstream, hooks não são acionados. - Imagens/screenshots/área de transferência, tráfego de ferramentas MCP e qualquer coisa já na conversa antes da instalação.
- Se um processo de hook for morto/timeout, o agente prossegue (falha aberta do lado do agente); o secretgate em si falha FECHADO em seus próprios erros para pré-eventos.
- Um prompt bloqueado é ecoado localmente pelo Claude Code (
Original prompt:no terminal e no JSONresultdoclaude -p) — a API nunca o vê, mas trate a saída headless canalizada como sensível.
Falsos positivos
Prefira a correção mais restrita: # pragma: allowlist secret inline (ou
gitleaks:allow) na linha → allow <valor> (com hash) → allow --path <glob> → allow --rule <id> (último recurso). Um projeto pode adicionar
entradas extras de lista de permissões em .secretgate.json ({"allowlist": {"paths": […]}}).