Ir al contenido

kovra sobre MCP

kovra se construyó pensando primero en este caso: un agente de codificación de IA que necesita los secretos para hacer trabajo real, pero que nunca debe leer los sensibles. Se conecta a kovra como servidor MCP, de modo que el agente recibe un pequeño conjunto de herramientas gobernadas en lugar del vault.

Todo lo que hace el agente fluye por la misma decisión de política que la CLI y el Dashboard — el agente nunca decide qué tiene permitido tocar. Lo único que cambia para un agente es quién está pidiendo: las solicitudes llevan el origen agent y corren bajo un scope, y la política sopesa ambos.

Un solo comando registra el servidor MCP con el agente e inserta un bloque de convenciones en CLAUDE.md para que el agente sepa cómo usarlo:

zsh
~/my-app % kovra setup
Vault ready; project `my-app`.
Updated .mcp.json (register the kovra MCP server).
Updated CLAUDE.md (insert/update the kovra conventions block).
Updated .claude/settings.json (deny Read of secrets files).
Updated .claude/settings.local.json (install the credential gate's Claude Code hooks).
Credential gate: Claude Code now asks kovra before a prompt or a tool output
reaches the model (it reloads hooks on its own). Notes:
- Hooks fail closed on a crash only from Claude Code 2.1.295 (`onFailure`).
- Recommended: set CLAUDE_CODE_DISABLE_FILE_MENTIONS=1 in your user settings
(~/.claude/settings.json, "env") or your shell (Claude Code 2.1.299+). Then
@file mentions go through Read and the gate. Project settings ignore it, so
kovra setup does not write it.
kovrad: registered to run at login.
Setup complete. Review CLAUDE.md and .mcp.json, then reload your agent to pick up the MCP server.

En macOS (kovra 0.10.0 y posteriores) además instala los hooks del gate de credenciales en .claude/settings.local.json y registra kovrad, el servicio de kovra en segundo plano, para que arranque al iniciar sesión. Dentro de una sesión de Claude Code sin esos hooks, kovra no entrega valores.

kovra setup apunta al .mcp.json de Claude Code, donde registra el comando kovra con el argumento mcp. Con otro cliente MCP, registre ese mismo comando (kovra mcp) en la configuración propia de ese cliente y fije el mismo scope KOVRA_MCP_ENVIRONMENTS / KOVRA_MCP_PROJECTS. El comando tiene que estar en su PATH: en macOS, kovra.app lo instala en /usr/local/bin/kovra (vea Instalación).

A partir de ahí, una sesión de codificación ve las herramientas de kovra y una lista de metadatos con scope — las coordenadas que tiene permitido direccionar, con su sensibilidad — y nada de los valores que hay detrás de ellas.

Las herramientas se reparten por los tres ejes de operación que kovra gobierna — metadatos, inject y reveal — más las herramientas de gestión para crear y editar secretos. La separación es justamente el punto: un agente puede ser genuinamente útil en la parte superior de esta lista y aun así ser incapaz de exfiltrar nada en la inferior.

El agente puede aprender libremente que un secreto existe y razonar sobre el proyecto, sin que ningún valor sea tocado:

  • list — todos los secretos direccionables en esta sesión: coordenada, sensibilidad, modo, fingerprint, flags. Los secretos fuera de scope simplemente no aparecen.
  • status — los metadatos de una coordenada (da error si no es direccionable).
  • fingerprint — un fingerprint corto y truncado de un valor. Suficiente para verificar “¿es este el mismo secreto que antes?”, nunca suficiente para reconstruir o confirmar una conjetura. Un valor high, inject-only o de prod no tiene ninguno (—).

Ninguno de estos devuelve jamás un valor. Así es como un agente mapea el cableado — qué servicios necesitan qué claves — sin leer un solo secreto.

Esta es la vía cotidiana para un agente que necesita un valor real para ejecutar algo:

  • inject_run — resuelve un .env.refs en línea y ejecuta un programa con los valores colocados en el entorno del proceso hijo. El texto plano va al proceso, nunca de vuelta al contexto del modelo. El resultado es {status, stdout, stderr} con cualquier valor del vault enmascarado en la salida.

Inyectar un valor high o prod agrega dos guardas independientes: debe apuntar a un ejecutable de la allowlist, y se pausa para una bioProve en la ventana de revisión de kovra en la Mac — nunca algo que el agente pueda responder. La confirmación nombra al cliente MCP que pide (por ejemplo claude-code 2.1.301), tal como se presentó ante kovra, nunca con texto que escribió el modelo. Un agente no puede encaminar silenciosamente una clave de producción a un programa que escribió él mismo: la allowlist fija el contenido de cada programa y rechaza los intérpretes genéricos, y el programa arranca en un entorno saneado (un PATH fijo, sin variables que cargan código).

Reveal — la única excepción estrecha y resguardada

Sección titulada «Reveal — la única excepción estrecha y resguardada»
  • reveal — devuelve un valor en texto plano al contexto del agente. Esto se permite solo para un secreto que se marcó explícitamente como revelable y que es no-prod y no-high. Todo lo demás — prod, high, inject-only — nunca se devuelve a un agente, punto.

Así que lo único que un agente puede llegar a leer de vuelta es un valor ordinario, no de producción, que se abrió deliberadamente. Los secretos sensibles no son “difíciles de revelar” a un agente; son inalcanzables por esa vía. E incluso un valor revelable con forma de credencial (un token con un prefijo conocido) lo redacta el gate de credenciales antes de que salga de kovra.

El agente también puede ayudar a configurar secretos. Estas herramientas cambian el vault pero nunca devuelven un valor:

  • set — almacena un valor literal. Vuelven los metadatos, no el valor. Un secreto prod nace high automáticamente. Sobrescribir un secreto crítico (high/inject-only) — o crear uno en la bóveda de un proyecto sobre uno global crítico, que un run en ese proyecto entregaría en su lugar — se pausa para su bioProve.
  • generate — hace que kovra genere un valor aleatorio fuerte del lado del servidor y lo almacene. Solo se devuelven los metadatos — el valor nunca se expone, ni siquiera una vez.
  • edit_metadata — ajusta sensibilidad, descripción, el flag revealable o una referencia. Bajar la sensibilidad de un secreto se audita por separado, y todo cambio que salga de high o inject-only se pausa para su bioProve. En un secreto crítico, una sola edición no puede cambiar a la vez su sensibilidad y su referencia: cada cambio lleva su propia edición y su propia aprobación.
  • delete — elimina un secreto (da error si no es direccionable en esta sesión).
  • request_secret — encola una solicitud para crear un secreto que el agente no tiene pero necesita: nombra la coordenada, una sensibilidad y una descripción corta, y recibe de vuelta un id de solicitud. No aporta ningún valor — un humano cumple la solicitud fuera de banda. Sobre un secreto que ya existe, la solicitud lo rota, tras la aprobación de la persona.

generate es la forma recomendada para que un agente cree credenciales: el valor existe solo dentro del vault desde el primer instante, así que no hay ventana en la que quede en el contexto del modelo.

Cuando el agente necesita un secreto que aún no se ha almacenado

Sección titulada «Cuando el agente necesita un secreto que aún no se ha almacenado»

A veces un agente choca con un muro: necesita un token de API o una contraseña que simplemente no está en el vault. En lugar de pedir que se pegue en el chat — donde aterrizaría en el contexto del modelo — llama a request_secret para encolar una solicitud que nombra solo la coordenada. Luego se cumple fuera de banda: desde la app de barra de menú kovra-menulet en macOS, el Dashboard o kovra intake fulfill en la terminal. Se escribe el valor en una ventana que solo un humano puede invocar (el agente no tiene shell para abrirla), y kovra lo sella — las solicitudes high detrás de una bioProve. El agente se entera de que el secreto ahora existe; nunca ve el valor.

Sin importar cómo se dirija una sesión — incluso una con prompt-injection o secuestrada — la política se sostiene:

  • No puede leer el texto plano de un secreto high, prod o inject-only.
  • No puede alcanzar nada fuera de su scope; esas coordenadas son no direccionables, no meramente denegadas.
  • No puede inyectar un valor high/prod en un programa que no esté en la allowlist, ni sin la bioProve.
  • No puede fabricar el prompt de confirmación que se ve — ese texto lo construye kovra a partir de la solicitud real, nunca del llamante.

Para el orden preciso en que se juzga cada solicitud, ver el proceso de decisión; para el límite en sí, ver scope del agente.