
Recibos firmados con Ed25519 + políticas Cedar para agentes de IA. Puerta de mandato financiero (Legate), paquetes de prueba, 3 borradores de Internet del IETF. npx protect-mcp
Pasarela de políticas Cedar de cierre ante fallos más recibos firmados para llamadas a herramientas de agentes de IA.
protect-mcp es una puerta de enlace que se sitúa frente a las llamadas a herramientas de un agente de IA. Evalúa cada llamada contra una política Cedar (el mismo lenguaje que AWS usa para IAM), bloquea lo que infringe las reglas antes de ejecutarlo y firma un recibo Ed25519 verificable sin conexión de cada decisión. Se ejecuta localmente, no envía telemetría de sus decisiones a ningún lugar y tiene licencia MIT.
would_deny: true, por lo que un fallo nunca es silencioso.serve --enforce y doctor ejecutan una autocomprobación de inicio y se niegan a armar la puerta a menos que puedan demostrar que una acción conocida como prohibida es realmente denegada. Una puerta que no puede demostrar que deniega no se inicia.@veritasacta/verify. No se requiere confianza en el proveedor: las matemáticas no importan quién lo ejecute.npx protect-mcp init
npx protect-mcp wrap -- node your-mcp-server.js
npx protect-mcp dashboard --open
npx protect-mcp recommend --write
npx protect-mcp --policy protect-mcp.recommended.json --enforce -- node your-mcp-server.js
Para Claude Desktop, ejecute primero un parche de configuración dry-run, luego aplíquelo:```bash
npx protect-mcp wrap --claude-desktop
npx protect-mcp wrap --claude-desktop --write
npx protect-mcp dashboard --open
El panel se enlaza a 127.0.0.1, lee solo archivos de registro/recibo locales y no sube nada. Usa npx protect-mcp connect solo si deseas explícitamente un panel ScopeBlind alojado.
Si prefieres llamar a la puerta como herramientas en lugar de conectar los hooks de Claude Code, ejecútala como un servidor MCP:```bash npx protect-mcp mcp
Habla MCP sobre stdio y expone cuatro herramientas de solo lectura, todo el bucle:
- **`evaluate_action`**: decide una llamada de herramienta propuesta contra una política Cedar en línea, falla cerrada (cualquier error de política es DENY). Devuelve `{ allowed, decision, reason, policy_digest }`.
- **`sign_decision`**: convierte una decisión en un recibo firmado con Ed25519 (una denegación firma un `gateway_restraint`, una concesión un `decision_receipt`). Devuelve el recibo y su clave pública; genera una clave efímera si no se proporciona una.
- **`verify_receipt`**: verifica un recibo firmado sin conexión contra una clave pública. Devuelve `{ valid, error, type, kid, issuer }`.
- **`self_test`**: demuéstrelo, sin entradas. Una acción conocida como prohibida es denegada, luego un recibo firmado da la vuelta y una copia alterada falla.
Apunta cualquier host MCP hacia él, por ejemplo Claude Desktop:```json
{
"mcpServers": {
"protect-mcp": { "command": "npx", "args": ["-y", "protect-mcp", "mcp"] }
}
}
Los recibos son compatibles a nivel de bytes con los que la puerta firma en tiempo de ejecución, por lo que un recibo acuñado aquí se verifica con @veritasacta/verify y el verificador del navegador de la misma manera.
protect-mcp dashboard es la vista del operador para pasar de la visibilidad a la aplicación de políticas:
Require approval, Block o Observe. Reinicie el wrapper después de revisar los cambios.Para aprobaciones de respaldo en escritorio en vivo, inicie el panel con el endpoint de aprobación de la puerta de enlace local y el nonce impreso por el wrapper:```bash
npx protect-mcp dashboard --open
--approval-endpoint http://127.0.0.1:9876
--approval-nonce "$PROTECT_MCP_APPROVAL_NONCE"
`Approve` reenvía a la puerta de enlace local en vivo cuando esas banderas están presentes.
`Deny`, `Edit` y `Take over` se registran localmente como registros de resolución de aprobación;
úsalos como instrucción del operador y vuelve a ejecutar la herramienta cuando sea necesario.
### MVP de límite pago: anclaje de resumen, no carga de datos
Los recibos autofirmados locales permanecen gratuitos y verificables sin conexión. El límite pago es
evidencia independiente de que ScopeBlind vio un resumen de recibo en un momento dado, bajo una
identidad de organización, sin recibir el aviso sin procesar, la carga útil de la herramienta, la salida, la clave privada ni el recibo sin procesar.```bash
# Create or refresh a local org identity and public-key directory.
npx protect-mcp registry init --org "Meridian Global Macro" --billing-account acct_meridian
# Local preview: writes a digest registry and shareable static verifier page.
npx protect-mcp registry anchor
# Hosted mode: uploads receipt digests only for independent anchoring.
SCOPEBLIND_TOKEN=... npx protect-mcp registry anchor \
--hosted \
--endpoint https://api.scopeblind.com \
--verifier-base https://legate.scopeblind.com
The local preview is deliberately labeled local-preview-not-independent.
Hosted mode anchors only receipt hashes, request ids, org public keys, and
billing metadata. It does not upload raw receipts or sensitive context.
protect-mcp killer-demo genera un paquete completo de ventas/demo de tres minutos:```bash
npx protect-mcp killer-demo --dir ./scopeblind-demo
Crea actividad ficticia del sistema de archivos, GitHub, correo electrónico y PMS; muestra llamadas arriesgadas en modo sombra; aplica un paquete de políticas; requiere aprobación para una reserva sensible de PMS; ejecuta a través de la puerta de enlace; escribe un recibo firmado; prueba que el recibo original se verifica; prueba que un recibo manipulado falla; y crea un paquete de divulgación selectiva que oculta el contexto sensible mientras muestra la prueba mínima.
Abra primero el `DEMO-RUNBOOK.md` generado. Luego ejecute el comando del panel impreso para guiar a un cliente a través de la secuencia exacta.
### Divulgación Selectiva v0
Los recibos en modo compromiso pueden llevar un `committed_fields_root` en lugar de exponer cada campo en texto claro. Luego, el titular puede divulgar solo los campos seleccionados:```bash
npx protect-mcp verify-disclosure \
--receipt ./receipts/selective-disclosure.receipt.json \
--disclosure ./receipts/selective-disclosure.tool-only.json
El verificador comprueba el parent receipt hash, la firma Ed25519, el commitment root y la prueba Merkle de cada campo divulgado. Luego explica qué campos fueron divulgados y qué campos comprometidos permanecen ocultos. Esto es salted commitment disclosure, no zero-knowledge completo, pero hace concreto el reclamo de privacidad: los auditores pueden verificar hechos seleccionados sin recibir la carga útil completa de la herramienta ni el contexto sensible del escritorio.
Puedes probar una DECLARACIÓN sobre tu registro sin revelarlo. Acuña una signed, position-blind attestation sobre todo el registro que divulgue solo categorías por decisión (un receipt digest, el veredicto, capability tags), nunca tus entradas, salidas o datos de la herramienta:```bash
npx protect-mcp claim --no net.egress
Cualquiera lo verifica sin conexión, viendo solo las categorías, nunca el contenido:```bash
npx protect-mcp verify-claim claim-<id>.json
El verificador recalcula una raíz de Merkle sobre el conjunto revelado y recalcula el predicado de forma independiente, por lo que el emisor no puede mentir sobre la afirmación dada la revelación. Agregue --anchor para registrar el resumen de la afirmación en el registro de transparencia ScopeBlind, público y de solo añadidura, para que una contraparte que no confíe en usted pueda confirmar que el conjunto revelado está completo y no fue re-cortado en secreto (solo se envía el hash; el registro permanece local):```bash
npx protect-mcp claim --no net.egress --anchor
Esta es una atestación responsable y ciega a la posición, no de conocimiento cero completo: revela la forma, no el contenido.
## Pruébalo en 60 segundos (sin agente necesario)
[](https://legate.scopeblind.com/record)
Mira el video de dos minutos en [legate.scopeblind.com/record](https://legate.scopeblind.com/record), luego repite la reproducción con tu propia copia:```bash
npx protect-mcp sample # seed a labeled sample record (8 decisions: 1 blocked, 2 payments)
npx protect-mcp record # open it: signatures verified in your browser
npx protect-mcp claim --payment-under 100 --anchor --output payments-under-100.json
npx protect-mcp verify-claim payments-under-100.json
npx protect-mcp anchor-record
Suelta el demo-tampered.jsonl generado en la página de registro para ver cómo se detecta una edición posterior a la firma. sample se niega a tocar un registro existente, así que ejecútalo en una carpeta vacía. Cuando estés listo para lo real, conecta la compuerta de abajo y los mismos comandos se ejecutarán contra el registro de tu propio agente.
npx protect-mcp init-hooks
npx protect-mcp serve --enforce --cedar ./cedar
Evaluación one-shot, tal como lo llama un hook PreToolUse. El código de salida 2 significa denegar (la herramienta está bloqueada); el código de salida 0 significa permitir:```bash
npx protect-mcp evaluate --cedar ./cedar --tool Bash --input '{"command":"rm"}'
echo $? # 2 -> denied, fail-closed
npx protect-mcp evaluate --cedar ./cedar --tool Read --input '{"path":"README.md"}'
echo $? # 0 -> allowed
Una política faltante o no cargable deniega (exit 2) a menos que pases explícitamente
--fail-on-missing-policy false.
protect-mcp init-hooks escribe un .claude/settings.json para ti. Para conectar la
puerta manualmente, los dos verbos que necesitas son evaluate (PreToolUse, bloquea con exit 2)
y sign (PostToolUse, registra un comprobante). Fija la versión para que una sesión de Claude Code
siempre ejecute la puerta que probaste:```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "npx [email protected] evaluate --cedar ./cedar --tool "$TOOL_NAME" --input "$TOOL_INPUT""
}
]
}
],
"PostToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "npx [email protected] sign --tool "$TOOL_NAME" --receipts ./receipts --key ./keys/gateway.json"
}
]
}
]
}
}
`evaluate` sale con código 2 en caso de denegación, por lo que Claude Code bloquea la llamada a la herramienta, y con 0 en caso de permitir.
`sign` es de mejor esfuerzo: agrega un recibo firmado con Ed25519 cuando se configura una clave, y si no hay un firmante disponible, registra una línea honesta sin firmar (`"signed": false`) en lugar de hacer fallar la herramienta.
## Úsalo en otros agentes (Codex, Cursor, Gemini, Hermes)
La misma puerta de fallo-cerrado se ejecuta como un gancho de herramienta en cualquier agente que los soporte. Agrega
`--format <host>` para que el verbo lea el payload del gancho de ese host desde stdin y deniegue en su contrato:```bash
# the PreToolUse / before-tool command for each host
npx -y protect-mcp@latest evaluate --format codex --cedar ./cedar # OpenAI Codex
npx -y protect-mcp@latest evaluate --format gemini --cedar ./cedar # Gemini CLI BeforeTool
npx -y protect-mcp@latest evaluate --format cursor --cedar ./cedar # Cursor beforeShellExecution
npx -y protect-mcp@latest evaluate --format hermes --cedar ./cedar # Hermes pre_tool_call
Empareje cada uno con sign --format <host> en el evento post-tool para recibos. El
caso importante es Hermes, que ignora los códigos de salida del hook y lee el veredicto
de stdout, por lo que --format hermes deniega mediante {"decision":"block"} en lugar de
exit 2 (un raw exit-2 fallaría silenciosamente en modo abierto allí). Sin --format, los
verbos leen las banderas --tool/--input exactamente como en la sección de Claude Code anterior.
Las políticas Cedar residen en un directorio al que apuntas con --cedar. Una regla forbid
deniega, una regla permit permite. Para coincidir con un valor en la entrada de la herramienta,
usa el modismo .contains():```cedar
// Allow read-only tools.
permit(
principal,
action == Action::"MCP::Tool::call",
resource == Tool::"Read"
);
// Deny dangerous shell commands by matching the command against a list. forbid( principal, action == Action::"MCP::Tool::call", resource == Tool::"Bash" ) when { ["rm", "dd", "mkfs"].contains(context.command) };
// Block destructive tools outright. forbid( principal, action == Action::"MCP::Tool::call", resource == Tool::"delete_file" );
> **Peligro:** NO escriba `context.command in ["rm", "dd"]` para comparar una cadena
> con una lista. `in` es para jerarquías de entidades, no para pertenencia a cadenas. Cedar
> trata la expresión como un error de tipo y descarta silenciosamente toda la regla `forbid`,
> lo que (bajo una puerta de fallo abierto) deja un `permit` residual en pie. Este
> es el defecto exacto detrás del aviso a continuación. Use `[...].contains(context.command)`
> en su lugar. Desde la versión 0.7.0, la puerta deniega ante ese error en lugar de permitir, y una
> prueba de control CI falla la compilación si el patrón se reintroduce en una política
> enviada. Ver [GHSA-hm46-7j72-rpv9](https://github.com/ScopeBlind/scopeblind-gateway/security/advisories/GHSA-hm46-7j72-rpv9).
### Paquetes de políticas iniciales
La mayoría de los equipos no deberían escribir Cedar desde cero el primer día. Instale un paquete
inicial, ejecútelo en modo sombra, inspeccione los recibos, luego ajuste o aplique:```bash
npx protect-mcp policy-packs list
npx protect-mcp policy-packs show secrets-safe
npx protect-mcp policy-packs install filesystem-safe --dir ./cedar
npx protect-mcp policy-packs install all --dir ./cedar
npx protect-mcp serve --cedar ./cedar
Packs incluidos:
filesystem-safe: acciones destructivas de archivos y lecturas de rutas similares a secretos.git-safe: forzados de push, resets duros, limpieza destructiva, eliminación de repositorio.email-safe: permitir borradores, bloquear envíos desatendidos.database-safe: postura de BD orientada a lectura, bloquear SQL de escritura/administración.cloud-spend-safe: creación evidente de gastos en la nube y destrucción de infraestructura.secrets-safe: exfiltración común de secretos de archivos, entorno, shell y nube.finance-mandate-safe: violaciones de listas restringidas y concentración en flujos de reserva.Los recibos están firmados y son verificables sin conexión por cualquier persona que tenga la clave pública. Sin red, sin proveedor, sin confianza en ScopeBlind:```bash npx @veritasacta/verify ./receipts/receipts.jsonl --format jsonl
`npx protect-mcp bundle --output audit.json` exporta un paquete de auditoría autocontenido y verificable sin conexión de tus recibos más la clave de firma pública.
## Security
`protect-mcp` 0.7.0 falla cerrado por diseño. Ante cualquier error de evaluación de política, un motor faltante o una política que haya fallado en la evaluación, la decisión es DENEGAR, no permitir. `serve --enforce` y `doctor` ejecutan una autocomprobación de arranque que demuestra que la puerta deniega un vector conocido prohibido antes de ser confiada, y se niegan a armar si no puede.
**Versiones afectadas: 0.5.x y 0.6.x.** Esas líneas fallan abiertas (devuelven PERMITIR en error de evaluación) y no evalúan Cedar correctamente contra el motor fijado, por lo que una regla de `prohibir` podría no bloquear. **Actualice a >= 0.7.0.**
Detalles y corrección: [GHSA-hm46-7j72-rpv9](https://github.com/ScopeBlind/scopeblind-gateway/security/advisories/GHSA-hm46-7j72-rpv9). Para reportar una vulnerabilidad, consulte [SECURITY.md](https://github.com/scopeblind/scopeblind-gateway/blob/HEAD/SECURITY.md).
## Commands
| Comando | Descripción |
|---------|-------------|
| `serve` | Inicia el servidor HTTP hook para Claude Code (puerto 9377). `--enforce` ejecuta la autocomprobación de restricción primero; `--cedar <dir>` y `--policy <path>` seleccionan la política. |
| `init` | Genera un par de claves Ed25519 (`keys/gateway.json`), una plantilla de configuración y una política de ejemplo. |
| `sample` | Siembra un registro de muestra claramente etiquetado (8 decisiones: una llamada bloqueada, dos pagos; kid `sample-demo`) más una copia manipulada, para que `record`, `claim`, `verify-claim` y `anchor-record` sean reproducibles desde cero antes de conectar un agente. Se niega a tocar un registro existente; `--force` lo anula. |
| `policy` | Ver y cambiar la política Cedar desde la terminal: `policy list` (permitir / prohibir / denegar por defecto por herramienta, con la frecuencia con la que la puerta lo permitió o denegó), `policy show`, `policy allow <tool>`, `policy deny <tool>`, `policy path`. Un `serve` en ejecución recarga en caliente ante el cambio. |
| `wrap` | Imprime un comando MCP protegido o parchea servidores MCP de Claude Desktop. Simulación por defecto; use `--write` para actualizar la configuración de Claude Desktop. |
| `dashboard` | Inicia un panel solo local en `127.0.0.1` que muestra inventario de herramientas, riesgo, cobertura de políticas, aprobaciones de acciones exactas, cadenas de recibos y exportación de auditoría. |
| `recommend` | Redacta una política JSON revisable a partir de llamadas locales observadas. Simulación por defecto; use `--write` para crear `protect-mcp.recommended.json`. |
| `registry` | Crea una identidad de organización, ancla resúmenes de recibos y escribe una página verificadora estática. El modo alojado carga solo los resúmenes. |
| `record` | Abre un visor local y buscable sobre tus recibos (`--live` transmite mientras el agente se ejecuta): firmas Ed25519 verificadas en tu navegador contra tu clave de puerta, etiquetas de capacidad, un árbol de procedencia y exportación firmada con un clic. Todo local, nada cargado. |
| `claim` | Acuña una atestación firmada y ciega a la posición de un predicado sobre el registro (`--no <cap>` incl. `--no payment`, `--only <c1,c2>`, `--no-verdict <verdict>`, `--count <verdict>`, `--payment-under <cap>`), revelando solo categorías de decisión. Agregue `--anchor` para registrar el resumen del reclamo en el registro de transparencia público; las claves inscritas anclan como una organización nombrada. |
| `anchor-record` | Punto de control de la raíz Merkle del registro + recuento + rango de tiempo en el registro público (amigable con latidos: omite cuando no hay cambios). Un reclamo posterior cuyo compromiso coincida con un punto de control anclado es demostrablemente sobre el registro completo a partir de ese punto de control. |
| `verify-claim` | Verifica un paquete de reclamo sin conexión: firma, raíz Merkle recalculada, predicado recalculado independientemente y el sidecar de anclaje cuando está presente (vincula el sobre anclado a este reclamo exacto, luego confirma que el registro público lo contiene). `--check-anchor` requiere el anclaje; `--offline` omite el salto de registro. |
| `killer-demo` | Genera un paquete de demostración completo desde modo sombra a política a aprobación a recibo firmado. |
| `verify-disclosure` | Verifica un paquete `scopeblind.selective_disclosure.v0` y explica los campos divulgados versus ocultos. |
| `policy-packs` | Enumera, inspecciona e instala paquetes de política Cedar de inicio. |
| `evaluate` | Evalúa una llamada de herramienta contra una política Cedar (puerta PreToolUse). Salida 2 = denegar (fallo cerrado), salida 0 = permitir. |
| `sign` | Firma una llamada de herramienta en un recibo (PostToolUse). Mejor esfuerzo: registra una línea honesta sin firmar si no hay clave. |
| `simulate` | Simula una política contra un registro de decisiones grabado para ver qué habría bloqueado. |
| `demo` | Inicia un servidor de demostración integrado envuelto con la puerta, para ver los recibos al instante. |
| `doctor` | Verifica tu configuración (claves, políticas, motor Cedar, verificador) y ejecuta la autocomprobación de restricción. |
| `bundle` | Exporta un paquete de auditoría verificable sin conexión de recibos más la clave pública. |
| `report` | Genera un informe de cumplimiento (Markdown o JSON) a partir del registro de decisiones y los recibos. |
Ejecute `npx protect-mcp --help` para la referencia completa de banderas.
## Links
- Protocolo (IETF): [draft-farley-acta-signed-receipts](https://datatracker.ietf.org/doc/draft-farley-acta-signed-receipts/)
- [CHANGELOG](https://github.com/scopeblind/scopeblind-gateway/blob/HEAD/CHANGELOG.md)
- [npm](https://www.npmjs.com/package/protect-mcp)
- [scopeblind.com](https://scopeblind.com)
Con licencia MIT. Construido por [ScopeBlind](https://scopeblind.com).