Saltar al contenido principal
failproofai usa archivos de configuración JSON para controlar qué políticas están activas, cómo se comportan y desde dónde se cargan las políticas personalizadas. La configuración está diseñada para compartirse fácilmente con tu equipo: confírmala en tu repositorio y cada desarrollador tendrá la misma red de seguridad para el agente.

Ámbitos de configuración

Existen tres ámbitos de configuración, evaluados en orden de prioridad:
ÁmbitoRuta del archivoPropósito
proyecto.failproofai/policies-config.jsonAjustes por repositorio, confirmados en control de versiones
local.failproofai/policies-config.local.jsonAnulaciones personales por repositorio, ignoradas por git
global~/.failproofai/policies-config.jsonValores predeterminados del usuario en todos los proyectos
Cuando failproofai recibe un evento de hook, carga y fusiona los tres archivos que existen para el directorio de trabajo actual.

Reglas de fusión

enabledPolicies — la unión de los tres ámbitos. Una política habilitada en cualquier nivel está activa.
project:  ["block-sudo"]
local:    ["block-rm-rf"]
global:   ["block-sudo", "sanitize-api-keys"]

resolved: ["block-sudo", "block-rm-rf", "sanitize-api-keys"]  ← unión deduplicada
policyParams — el primer ámbito que define los parámetros para una política dada gana por completo. No hay fusión profunda de valores dentro de los parámetros de una política.
project:  block-sudo → { allowPatterns: ["sudo apt-get update"] }
global:   block-sudo → { allowPatterns: ["sudo systemctl status"] }

resolved: { allowPatterns: ["sudo apt-get update"] }   ← project gana, global ignorado
project:  (sin entrada block-sudo)
local:    (sin entrada block-sudo)
global:   block-sudo → { allowPatterns: ["sudo systemctl status"] }

resolved: { allowPatterns: ["sudo systemctl status"] }  ← cae hasta global
customPoliciesPath — el primer ámbito que lo define gana. llm — el primer ámbito que lo define gana.

Formato del archivo de configuración

{
  "enabledPolicies": [
    "block-sudo",
    "block-rm-rf",
    "block-push-master",
    "sanitize-api-keys",
    "sanitize-jwt",
    "block-env-files",
    "block-read-outside-cwd"
  ],
  "policyParams": {
    "block-sudo": {
      "allowPatterns": ["sudo systemctl status", "sudo journalctl"]
    },
    "block-push-master": {
      "protectedBranches": ["main", "release", "prod"]
    },
    "block-rm-rf": {
      "allowPaths": ["/tmp"]
    },
    "block-read-outside-cwd": {
      "allowPaths": ["/shared/data", "/opt/company"]
    },
    "sanitize-api-keys": {
      "additionalPatterns": [
        { "regex": "myco_[A-Za-z0-9]{32}", "label": "MyCo API key" }
      ]
    },
    "warn-large-file-write": {
      "thresholdKb": 512
    }
  },
  "customPoliciesPath": "/home/alice/myproject/my-policies.js"
}

Referencia de campos

enabledPolicies

Tipo: string[] Lista de nombres de políticas a habilitar. Los nombres deben coincidir exactamente con los identificadores de política que muestra failproofai policies. Consulta Políticas integradas para ver la lista completa. Las políticas que no están en enabledPolicies están inactivas, incluso si tienen entradas en policyParams.

policyParams

Tipo: Record<string, Record<string, unknown>> Anulaciones de parámetros por política. La clave externa es el nombre de la política; las claves internas son específicas de cada política. Cada política documenta sus parámetros disponibles en Políticas integradas. Si una política tiene parámetros pero no los especificas, se usan los valores predeterminados integrados de la política. Los usuarios que no configuren policyParams en absoluto obtendrán un comportamiento idéntico al de versiones anteriores. Las claves desconocidas dentro del bloque de parámetros de una política se ignoran silenciosamente cuando se dispara el hook, pero se marcan como advertencias cuando ejecutas failproofai policies.

hint (transversal)

Tipo: string (opcional) Un mensaje que se agrega al motivo cuando una política devuelve deny o instruct. Úsalo para dar a Claude orientación accionable sin modificar la política en sí. Funciona con cualquier tipo de política: integrada, personalizada (custom/), convención de proyecto (.failproofai-project/) o convención de usuario (.failproofai-user/).
{
  "policyParams": {
    "block-force-push": {
      "hint": "Try creating a fresh branch instead."
    },
    "block-sudo": {
      "allowPatterns": ["sudo apt-get"],
      "hint": "Use apt-get directly without sudo."
    },
    "custom/my-policy": {
      "hint": "Ask the user for approval first."
    }
  }
}
Cuando block-force-push deniega, Claude ve: “Force-pushing is blocked. Try creating a fresh branch instead.” Los valores que no sean cadenas de texto y las cadenas vacías se ignoran silenciosamente. Si hint no está definido, el comportamiento no cambia (compatible con versiones anteriores).

customPoliciesPath

Tipo: string (ruta absoluta) Ruta a un archivo JavaScript que contiene políticas de hook personalizadas. Se establece automáticamente mediante failproofai policies --install --custom <path> (la ruta se resuelve a absoluta antes de almacenarse). El archivo se carga de nuevo en cada evento de hook; no hay caché. Consulta Políticas personalizadas para detalles de creación.

Políticas basadas en convenciones

Además del customPoliciesPath explícito, failproofai descubre y carga automáticamente archivos de políticas desde directorios .failproofai/policies/:
NivelDirectorioÁmbito
Proyecto.failproofai/policies/Compartido con el equipo a través de control de versiones
Usuario~/.failproofai/policies/Personal, aplica a todos los proyectos
Coincidencia de archivos: Solo se cargan los archivos que coincidan con *policies.{js,mjs,ts} (p. ej., security-policies.mjs, workflow-policies.js). Los demás archivos del directorio se ignoran. Sin configuración necesaria: Las políticas de convención no requieren entradas en policies-config.json. Simplemente coloca los archivos en el directorio y se detectarán en el próximo evento de hook. Carga por unión: Se analizan tanto el directorio de convenciones del proyecto como el del usuario. Todos los archivos coincidentes de ambos niveles se cargan (a diferencia de customPoliciesPath, que usa el primer ámbito que gana). Consulta Políticas personalizadas para más detalles y ejemplos.

llm

Tipo: object (opcional) Configuración del cliente LLM para políticas que realizan llamadas a IA. No es necesario en la mayoría de los casos.
{
  "llm": {
    "model": "claude-sonnet-4-6",
    "apiKey": "sk-ant-..."
  }
}

Gestión de la configuración desde la CLI

Los comandos policies --install y policies --uninstall escriben en el archivo de configuración de hooks de tu CLI de agente (los puntos de entrada del hook), mientras que policies-config.json es el archivo que gestionas directamente. Son dos cosas distintas:
  • Ajustes de la CLI del agente — indica al agente que llame a failproofai --hook <event> en cada uso de herramienta:
    • Claude Code: ~/.claude/settings.json (usuario), <cwd>/.claude/settings.json (proyecto), <cwd>/.claude/settings.local.json (local)
    • OpenAI Codex: ~/.codex/hooks.json (usuario), <cwd>/.codex/hooks.json (proyecto) — Codex no tiene ámbito local
    • GitHub Copilot CLI (beta): ~/.copilot/hooks/failproofai.json (usuario), <cwd>/.github/hooks/failproofai.json (proyecto) — Copilot no tiene ámbito local. Las entradas de hook usan los campos de comando bash/powershell con clave por SO de Copilot con timeoutSec; el archivo lleva un marcador de nivel superior version: 1. La compatibilidad con Copilot CLI está en beta mientras verificamos el esquema de registros events.jsonl (que la documentación pública no especifica) con más sesiones del mundo real.
    • Cursor Agent (beta): ~/.cursor/hooks.json (usuario), <cwd>/.cursor/hooks.json (proyecto) — Cursor no tiene ámbito local. Las entradas de hook usan la forma {type, command, timeout} del estilo Claude (sin división bash/powershell), pero almacenadas bajo claves de evento en camelCase (preToolUse, beforeSubmitPrompt, …) en un array plano según el esquema de hooks de Cursor; el archivo lleva un marcador de nivel superior version: 1. El manejador canonicaliza camelCase → PascalCase mediante CURSOR_EVENT_MAP para que las políticas integradas existentes se activen sin cambios. La compatibilidad con Cursor Agent está en beta mientras verificamos el formato en disco de las transcripciones de Cursor (no especificado en la documentación pública) con más instalaciones del mundo real.
    • OpenCode (beta): ~/.config/opencode/opencode.json + ~/.config/opencode/plugins/failproofai.mjs (usuario), <cwd>/.opencode/opencode.json + <cwd>/.opencode/plugins/failproofai.mjs (proyecto) — OpenCode no tiene ámbito local. A diferencia de las otras seis CLIs, OpenCode no tiene un sistema de hooks de comandos externos: carga plugins JS/TS en proceso, registrados explícitamente mediante el array plugin: [] en opencode.json (el autodescubrimiento desde .opencode/plugins/ no es como se cargan los plugins en opencode v1.14.33). La instalación coloca un pequeño shim de plugin generado que llama como subproceso al binario de failproofai y traduce la respuesta JSON en forma Claude del binario a la semántica del plugin: throw new Error() para denegación de eventos de herramienta (cancela la llamada a la herramienta), client.session.prompt(...) para instruct Y para denegación de Stop/SubagentStop (envía el motivo de denegación como el siguiente mensaje de usuario — el único canal de reintento forzado, ya que session.idle es solo de notificación y lanzar desde él es un no-op), y no-op para allow. El shim canonicaliza tanto los nombres de herramientas (minúsculas → PascalCase mediante OPENCODE_TOOL_MAP) como las claves de argumentos de entrada de herramientas (camelCase → snake_case mediante OPENCODE_TOOL_INPUT_MAP para Read/Write/Edit, p. ej. filePathfile_path, oldStringold_string) antes de reenviar al binario, de modo que las políticas integradas de verificación de rutas como block-read-outside-cwd, block-env-files y block-secrets-write se activan sin cambios en las llamadas de herramientas de OpenCode. Las sesiones viven en la base de datos SQLite de opencode en ~/.local/share/opencode/opencode.db; el visor de sesiones del panel las lee mediante opencode db --format json y opencode export <id>. La compatibilidad con OpenCode está en beta mientras verificamos el comportamiento en distintas versiones y con más sesiones del mundo real. Consulta la documentación de plugins de OpenCode.
    • Pi (beta): ~/.pi/agent/settings.json (usuario), <cwd>/.pi/settings.json (proyecto) — Pi no tiene ámbito local. Pi carga paquetes de extensión TypeScript al inicio; el archivo de ajustes es un array plano de cadenas {"packages": ["./relative/path", …]}. failproofai escribe una única entrada en el array de paquetes que apunta a su directorio pi-extension/ incluido. La extensión se suscribe internamente a los eventos tool_call/user_bash/input/session_start de Pi y lanza failproofai --hook <Event> --cli pi; el manejador canonicaliza underscore_lower_snake_case → PascalCase mediante PI_EVENT_MAP para que las políticas integradas existentes se activen sin cambios. Los argumentos de entrada de herramientas también se canonizan mediante PI_TOOL_INPUT_MAP (Read/Write/Edit de Pi entregan path en lugar de file_path; mapear la clave de nivel superior permite que block-env-files y block-secrets-write se activen — block-read-outside-cwd ya tenía una alternativa con path). La compatibilidad con Pi está en beta mientras la API de extensión de Pi y el diseño del registro de sesiones se estabilizan.
    • Gemini CLI (beta): ~/.gemini/settings.json (usuario), <cwd>/.gemini/settings.json (proyecto) — Gemini no tiene ámbito local (documenta un ámbito system en /etc/gemini-cli/settings.json que failproofai no expone). Las entradas de hook usan la forma {type, command, timeout} de Claude envuelta en el esquema de matcher {matcher, hooks: [...]} de Gemini con matcher: "*" por defecto. Los eventos son PascalCase (SessionStart, BeforeAgent, AfterAgent, BeforeModel, AfterModel, BeforeToolSelection, BeforeTool, AfterTool, PreCompress, Notification, SessionEnd); el manejador mapea a nombres canónicos de Claude mediante GEMINI_EVENT_MAP. Los nombres de herramientas son snake_case (run_shell_command, read_file, write_file, replace, …) — el manejador los canonicaliza mediante GEMINI_TOOL_MAP para que las políticas integradas existentes se activen sin cambios. El evaluador de políticas emite la forma plana {decision: "deny", reason} de Gemini (preferida según el contrato de salida-0 de la “Regla de Oro” de Gemini), {hookSpecificOutput: {hookEventName, additionalContext}} para inyección de contexto en BeforeAgent/AfterTool/SessionStart, y {decision: "block", reason} en AfterAgent para semántica de reintento forzado. La compatibilidad con Gemini CLI está en beta mientras ampliamos la cobertura del mundo real. Consulta la documentación de hooks de Gemini CLI.
  • policies-config.json — indica a failproofai qué políticas evaluar y con qué parámetros (compartido entre todas las CLIs de agentes)
Pasa --cli claude|codex|copilot|cursor|opencode|pi|gemini para apuntar a un agente específico (separados por espacios o repetidos para cualquier subconjunto):
failproofai policies --install --cli codex --scope project
failproofai policies --install --cli copilot --scope project
failproofai policies --install --cli cursor --scope project
failproofai policies --install --cli opencode --scope project
failproofai policies --install --cli pi --scope project
failproofai policies --install --cli gemini --scope project
failproofai policies --install --cli claude codex copilot cursor opencode pi gemini
Cuando se omite --cli, failproofai detecta qué CLIs de agentes están instaladas (which claude / which codex / which copilot / which cursor-agent / which opencode / which pi / which gemini):
  • Una CLI detectada — la selecciona automáticamente sin preguntar.
  • Múltiples CLIs detectadas en una terminal interactiva — muestra un indicador de selección única con teclas de flecha agrupado en una sección Detected (N) (con una fila agregada Install for all N detected + cada CLI detectada individualmente) y una sección Not installed (M) · install hooks ahead of time que lista todas las CLIs compatibles no detectadas como opciones de instalación anticipada (↑↓ para moverse, Enter para seleccionar, ^C para salir). El flujo de desinstalación solo muestra la sección Detected.
  • Múltiples CLIs detectadas en una ejecución no interactiva (CI, sin TTY) — instala para todas las CLIs detectadas sin preguntar.
  • Ninguna detectada — recurre a claude, con una advertencia de que no se encontró ningún binario de agente en PATH; el comando de hook se escribe igualmente para que se active en cuanto instales uno.
Puedes editar policies-config.json directamente en cualquier momento; los cambios surten efecto de inmediato en el siguiente evento de hook sin necesidad de reiniciar.

Ejemplo: configuración a nivel de proyecto con valores predeterminados del equipo

Confirma .failproofai/policies-config.json en tu repositorio:
{
  "enabledPolicies": [
    "block-sudo",
    "block-rm-rf",
    "block-push-master",
    "sanitize-api-keys",
    "block-env-files"
  ],
  "policyParams": {
    "block-push-master": {
      "protectedBranches": ["main", "release", "hotfix"]
    }
  }
}
Cada desarrollador puede luego crear .failproofai/policies-config.local.json (ignorado por git) para sus anulaciones personales sin afectar a sus compañeros de equipo.