secretgate — cortafuegos local de secretos para agentes de codificación
Una credencial nunca debe viajar a una API de LLM. secretgate lo garantiza localmente,
con un motor determinista (node scripts/secretgate.mjs, sin npm install, sin
claves): 221 reglas convertidas de gitleaks + puertas de entropía + tarjetas validadas con Luhn.
Donde la API de hooks del agente permite reescribir, los secretos se redactan como
marcadores de posición estables y se restauran localmente cuando el agente los vuelve a escribir
(redactar-y-restaurar); donde solo permite bloquear (prompts en Claude
Code/Codex), el prompt se bloquea con una copia redactada para reenviar.
Activación → instalar (haga esto primero cuando se active la skill)
Cuando esta skill se activa (el usuario pide proteger secretos / instalar secretgate / configurar el cortafuegos), ejecute el doctor, luego conecte lo que no esté aún conectado. secretgate es una skill, no un paquete npm — ejecute su propio bundle:
node scripts/secretgate.mjs status # qué está ya conectado
node scripts/secretgate.mjs install --claude-code # hooks + permissions.deny en ~/.claude/settings.json
node scripts/secretgate.mjs install --codex # ~/.codex/hooks.json + [features] hooks = true
node scripts/secretgate.mjs install --opencode # plugin autocontenido en ~/.config/opencode/plugin/
node scripts/secretgate.mjs install --all # los tres
--project limita la instalación de Claude Code a ./.claude/settings.json.
install fija una copia del bundle en ~/.secretgate/bin/ y conecta el
agente para que LLAME a ESE, de modo que siga funcionando después de que se borre la caché de la skill.
Indique siempre al usuario que REINICIE la sesión del agente después — los hooks se cargan al iniciar.
Una vez conectado, la redacción es automática y determinista (el hook lo hace, no usted).
Comandos
| Comando | Qué hace |
|---|---|
status | Doctor: cableado por agente, motor, salud del vault, limitaciones |
| `scan <archivo | dir |
pipe | stdin → stdout con secretos redactados como marcadores de posición |
allow <valor> / allow --rule <id> / allow --path <glob> | Lista blanca (valores almacenados como SHA-256, nunca en claro) |
vault list / vault clear | Inspecciona los mapeos de marcadores de posición (nunca muestra secretos) |
uninstall --<agente> | Elimina exactamente lo que se añadió con install |
Cómo funciona la protección (explíqueselo al usuario cuando pregunte)
- Prompts: Claude Code/Codex → bloqueados con una copia redactada (añada
[allow-secret]para omitir una vez). OpenCode → redactados silenciosamente en su lugar. - Lecturas de archivos:
.env*, claves,~/.aws,~/.ssh… se deniegan directamente (.env.example/.sample/.templatepermanecen legibles). El valor nunca entra en el modelo. - Salida de herramientas/bash: redactada como marcadores de posición
SECRETGATE_<hash>(Claude Code + OpenCode; Codex aún no puede reescribir la salida). - Restauración: cuando el agente escribe un marcador de posición en un archivo (Write/Edit),
el valor REAL se guarda en el disco. La restauración en Bash está DESACTIVADA por defecto
(protección contra filtración por inyección de prompt) — actívela con
restoreBash: trueen~/.secretgate/config.json. - Llamadas limpias a herramientas: el hook pre-tool-use de Claude Code responde con JSON
mínimo (
{}, sin decisión = flujo de permisos normal) en lugar de stdout vacío. La salida vacía del hook activa un error de Claude Code (anthropics/claude-code#77782) que fuerza un permiso interactivo en cada llamada a herramienta coincidente, incluso en modo automático — y el valor de decisión documentado"defer"es rechazado por Claude Code <= 2.1.212, por lo que{}es la abstención que funciona en todas partes.
NO cubierto (sea honesto con el usuario)
- Las menciones
@filede Claude Code incorporan contenido en línea sin disparar hooks de herramienta (las reglas permissions.deny son la única cobertura allí). - Ejecuciones no interactivas de Codex (
codex exec) — error upstream, los hooks no se disparan. - Imágenes/capturas/portapapeles, tráfico de herramientas MCP y cualquier cosa ya en la conversación antes de la instalación.
- Si un proceso hook es eliminado/excede el tiempo de espera, el agente continúa (fail-open del lado del agente); secretgate falla CERRADO en sus propios errores para eventos previos.
- Un prompt bloqueado se muestra localmente por Claude Code (
Original prompt:en la terminal y enclaude -pJSONresult) — la API nunca lo ve, pero trate la salida sin cabeza canalizada como sensible.
Falsos positivos
Prefiera la solución más específica: # pragma: allowlist secret en línea
(o gitleaks:allow) en la línea → allow <valor> (con hash) → allow --path <glob> → allow --rule <id> (último recurso). Un proyecto puede incluir
entradas adicionales de lista blanca en .secretgate.json ({"allowlist": {"paths": […]}}).