
Reçus signés Ed25519 + politiques Cedar pour les agents IA. Finance mandate gate (Legate), packs de preuves, 3 Internet-Drafts IETF. npx protect-mcp
Passerelle de politique Cedar à défaut fermé avec reçus signés pour les appels d'outils d'agent IA.
protect-mcp est une passerelle qui se place devant les appels d'outils d'un agent IA. Elle évalue chaque appel par rapport à une politique Cedar (le même langage qu'AWS utilise pour IAM), bloque ce qui enfreint les règles avant son exécution, et signe un reçu Ed25519 vérifiable hors ligne de chaque décision. Elle s'exécute localement, n'envoie aucune télémétrie de vos décisions où que ce soit, et est sous licence MIT.
would_deny: true, donc un échec n'est jamais silencieux.serve --enforce et doctor exécutent un auto-test au démarrage et refusent d'armer la passerelle à moins de pouvoir démontrer qu'une action connue comme interdite est effectivement refusée. Une passerelle qui ne peut pas prouver qu'elle refuse ne démarre pas.@veritasacta/verify. Aucune confiance en un fournisseur requise : les maths ne se soucient pas de qui l'exécute.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
Pour Claude Desktop, exécutez d'abord un correctif de configuration à sec, puis appliquez-le :```bash
npx protect-mcp wrap --claude-desktop
npx protect-mcp wrap --claude-desktop --write
npx protect-mcp dashboard --open
Le tableau de bord se lie à 127.0.0.1, lit uniquement les fichiers journaux/reçus locaux et ne
télécharge rien. Utilisez npx protect-mcp connect uniquement si vous souhaitez explicitement un
tableau de bord ScopeBlind hébergé.
Si vous préférez appeler la passerelle comme des outils plutôt que de câbler les hooks Claude Code, exécutez-la en tant que serveur MCP :```bash npx protect-mcp mcp
Il communique via MCP sur stdio et expose quatre outils en lecture seule, la boucle complète :
- **`evaluate_action`** : décide de l'appel d'un outil proposé par rapport à une politique Cedar intégrée, fermé par défaut (toute erreur de politique est DENY). Renvoie `{ allowed, decision, reason, policy_digest }`.
- **`sign_decision`** : transforme une décision en un reçu signé Ed25519 (un refus signe un `gateway_restraint`, une autorisation un `decision_receipt`). Renvoie le reçu et sa clé publique ; génère une clé éphémère si vous n'en fournissez pas.
- **`verify_receipt`** : vérifie un reçu signé hors ligne par rapport à une clé publique. Renvoie `{ valid, error, type, kid, issuer }`.
- **`self_test`** : faites vos preuves, aucune entrée. Une action interdite connue est refusée, puis un reçu signé fait un aller-retour et une copie falsifiée échoue.
Pointez n'importe quel hôte MCP vers celui-ci, par exemple Claude Desktop :```json
{
"mcpServers": {
"protect-mcp": { "command": "npx", "args": ["-y", "protect-mcp", "mcp"] }
}
}
Receipts are byte-compatible with the ones the gate signs at runtime, so a
receipt minted here verifies with @veritasacta/verify
and the browser verifier just the same.
protect-mcp dashboard est la vue opérateur pour passer de la visibilité à
l'application des règles :
Require approval,
Block, ou Observe. Redémarrez le wrapper après avoir examiné les modifications.Pour les approbations de repli en direct sur le bureau, démarrez le tableau de bord avec le point de terminaison d'approbation de la passerelle locale
et le nonce imprimés par le wrapper :```bash
npx protect-mcp dashboard --open
--approval-endpoint http://127.0.0.1:9876
--approval-nonce "$PROTECT_MCP_APPROVAL_NONCE"
`Approve` transmet vers la passerelle locale en direct lorsque ces indicateurs sont présents.
`Deny`, `Edit` et `Take over` sont enregistrés localement comme enregistrements de résolution d'approbation ; utilisez-les comme instruction de l'opérateur et relancez l'outil si nécessaire.
### MVP de limite payante : ancrage de condensé, pas d'upload de données
Les reçus auto-signés locaux restent gratuits et vérifiables hors ligne. La limite payante est une preuve indépendante que ScopeBlind a vu un condensé de reçu à un moment donné, sous une identité organisationnelle, sans recevoir l'invite brute, la charge utile de l'outil, la sortie, la clé privée ou le reçu brut.```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
L'aperçu local est délibérément étiqueté local-preview-not-independent.
Le mode hébergé n'ancre que les hachages de reçus, les identifiants de requête, les clés publiques d'organisation et les métadonnées de facturation. Il ne télécharge pas les reçus bruts ni le contexte sensible.
protect-mcp killer-demo génère un pack de vente/démo complet de trois minutes :```bash
npx protect-mcp killer-demo --dir ./scopeblind-demo
Il crée une activité fictive de système de fichiers, GitHub, e-mail et PMS ; montre les appels risqués en mode ombre ; applique un pack de politiques ; nécessite une approbation pour une réservation PMS sensible ; exécute via la passerelle ; écrit un reçu signé ; prouve que le reçu original se vérifie ; prouve qu'un reçu falsifié échoue ; et crée un paquet de divulgation sélective qui cache le contexte sensible tout en montrant la preuve minimale.
Ouvrez d'abord le `DEMO-RUNBOOK.md` généré. Ensuite, exécutez la commande du tableau de bord imprimée pour guider un client à travers la séquence exacte.
### Selective Disclosure v0
Les reçus en mode engagement peuvent porter un `committed_fields_root` au lieu d'exposer chaque champ en clair. Plus tard, le détenteur peut divulguer uniquement les champs sélectionnés :```bash
npx protect-mcp verify-disclosure \
--receipt ./receipts/selective-disclosure.receipt.json \
--disclosure ./receipts/selective-disclosure.tool-only.json
Le vérificateur vérifie le hash du reçu parent, la signature Ed25519, la racine d'engagement, et chaque preuve Merkle des champs divulgués. Il explique ensuite quels champs ont été divulgués et quels champs engagés restent cachés. Il s'agit d'une divulgation d'engagement salé, pas de zero-knowledge complet, mais cela rend la revendication de confidentialité concrète : les auditeurs peuvent vérifier des faits sélectionnés sans recevoir l'intégralité de la charge utile de l'outil ou le contexte sensible du poste de travail.
Vous pouvez prouver une REVENDICATION sur votre enregistrement sans le révéler. Frappez une attestation signée et sans position sur l'enregistrement complet qui ne divulgue que des catégories par décision (un résumé de reçu, le verdict, des balises de capacité), jamais vos entrées d'outil, sorties ou données :```bash
npx protect-mcp claim --no net.egress
Quiconque le vérifie hors ligne, ne voyant que les catégories, jamais le contenu :```bash
npx protect-mcp verify-claim claim-<id>.json
Le vérificateur recalcule une racine de Merkle sur l'ensemble divulgué et recalcule le prédicat de manière indépendante, de sorte que l'émetteur ne peut pas mentir sur la déclaration étant donné la divulgation. Ajoutez --anchor pour enregistrer le condensé de la déclaration dans le journal de transparence ScopeBlind, public et à ajout uniquement, afin qu'une contrepartie qui ne vous fait pas confiance puisse confirmer que l'ensemble divulgué est complet et n'a pas été silencieusement re-découpé (seul le hachage est envoyé ; l'enregistrement reste local) :```bash
npx protect-mcp claim --no net.egress --anchor
Il s'agit d'une attestation responsable et aveugle à la position, pas d'une preuve de connaissance complète : elle révèle la forme, pas le contenu.
## Essayez en 60 secondes (aucun agent requis)
[](https://legate.scopeblind.com/record)
Regardez le film de deux minutes sur [legate.scopeblind.com/record](https://legate.scopeblind.com/record), puis rejouez-le sur votre propre copie :```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
Déposez le fichier demo-tampered.jsonl généré dans la page d'enregistrement pour voir une modification post-signature être détectée. sample refuse de toucher un enregistrement existant, exécutez-le donc dans un dossier vide. Lorsque vous êtes prêt pour la vraie opération, connectez la gate ci-dessous et les mêmes commandes s'exécuteront contre l'enregistrement de votre propre agent.
npx protect-mcp init-hooks
npx protect-mcp serve --enforce --cedar ./cedar
Évaluation unique, comme un hook PreToolUse l'appelle. Le code de sortie 2 signifie refuser (l'outil est bloqué) ; le code de sortie 0 signifie autoriser :```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
Une politique manquante ou non chargeable est refusée (exit 2) sauf si vous passez explicitement
--fail-on-missing-policy false.
protect-mcp init-hooks écrit un fichier .claude/settings.json pour vous. Pour configurer la
porte manuellement, les deux verbes dont vous avez besoin sont evaluate (PreToolUse, bloque sur exit 2)
et sign (PostToolUse, enregistre un reçu). Épinglez la version pour qu'une session Claude Code
exécute toujours la porte que vous avez testée :```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` renvoie 2 en cas de refus, donc Claude Code bloque l'appel à l'outil, et 0 en cas d'autorisation.
`sign` est effectué au mieux : il ajoute un reçu signé avec Ed25519 lorsqu'une clé est configurée,
et si aucun signataire n'est disponible, il enregistre honnêtement une ligne non signée
(`"signed": false`) plutôt que de faire échouer l'outil.
## Utilisez-le dans d'autres agents (Codex, Cursor, Gemini, Hermes)
La même porte fermée par défaut fonctionne comme un crochet d'outil dans tout agent qui les prend en charge. Ajoutez
`--format <host>` pour que la commande lise la charge utile du crochet de cet hôte depuis l'entrée standard et refuse
dans son contrat :```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
Pair each with sign --format <host> on the post-tool event for receipts. The
important case is Hermes, which ignores hook exit codes and reads the verdict
from stdout, so --format hermes denies via {"decision":"block"} rather than
exit 2 (a raw exit-2 would silently fail open there). Without --format, the
verbs read --tool/--input flags exactly as in the Claude Code section above.
Les politiques Cedar se trouvent dans un répertoire que vous spécifiez avec --cedar. Une règle forbid refuse, une règle permit autorise. Pour faire correspondre une valeur dans l’entrée de l’outil, utilisez l’idiome .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" );
> **Danger :** n'écrivez PAS `context.command in ["rm", "dd"]` pour faire correspondre une chaîne
> à une liste. `in` est pour les hiérarchies d'entités, pas l'appartenance à une chaîne. Cedar
> traite l'expression comme une erreur de type et ignore silencieusement toute la règle `forbid`,
> ce qui (sous une porte ouverte par défaut) laisse une règle `permit` résiduelle en vigueur. C'est
> exactement le défaut derrière l'avis ci-dessous. Utilisez `[...].contains(context.command)`
> à la place. Depuis la version 0.7.0, la porte refuse sur cette erreur plutôt que d'autoriser, et
> un test CI déclenche un échec de build si le motif est réintroduit dans une politique expédiée.
> Voir [GHSA-hm46-7j72-rpv9](https://github.com/ScopeBlind/scopeblind-gateway/security/advisories/GHSA-hm46-7j72-rpv9).
### Packs de politiques de démarrage
La plupart des équipes ne devraient pas écrire Cedar à partir de zéro dès le premier jour. Installez un pack de démarrage, exécutez en mode shadow, inspectez les reçus, puis resserrez ou appliquez :```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 intégrés :
filesystem-safe : actions destructrices de fichiers et lectures de chemins de type secret.git-safe : forcages de push, réinitialisations dures, nettoyage destructeur, suppression de dépôt.email-safe : autoriser la rédaction, bloquer les envois non supervisés.database-safe : posture de base de données orientée lecture, bloquer les requêtes SQL d'écriture/administration.cloud-spend-safe : création évidente de dépenses cloud et destruction d'infrastructure.secrets-safe : exfiltration courante de secrets via fichiers, variables d'environnement, shell et cloud.finance-mandate-safe : violations de liste restreinte et de concentration dans les flux de réservation.Les reçus sont signés et vérifiables hors ligne par toute personne disposant de la clé publique. Aucun réseau, aucun fournisseur, aucune confiance dans ScopeBlind :```bash npx @veritasacta/verify ./receipts/receipts.jsonl --format jsonl
`npx protect-mcp bundle --output audit.json` exporte un bundle d'audit autonome et vérifiable hors ligne de vos reçus, ainsi que la clé de signature publique.
## Sécurité
`protect-mcp` 0.7.0 est en échec fermé (fail-closed) par conception. En cas d'erreur d'évaluation de politique, d'un moteur manquant ou d'une politique ayant généré une erreur lors de l'évaluation, la décision est DENY, pas allow. `serve --enforce` et `doctor` exécutent un auto-test de démarrage qui prouve que la passerelle refuse un vecteur connu interdit avant d'être considérée comme fiable, et refusent de s'armer si elle ne le peut pas.
**Versions affectées : 0.5.x et 0.6.x.** Ces versions échouent en mode ouvert (elles renvoient ALLOW en cas d'erreur d'évaluation) et n'évaluent pas correctement Cedar par rapport au moteur épinglé, de sorte qu'une règle `forbid` pourrait ne pas bloquer. **Mettez à jour vers >= 0.7.0.**
Détails et correctif : [GHSA-hm46-7j72-rpv9](https://github.com/ScopeBlind/scopeblind-gateway/security/advisories/GHSA-hm46-7j72-rpv9). Pour signaler une vulnérabilité, consultez [SECURITY.md](https://github.com/scopeblind/scopeblind-gateway/blob/HEAD/SECURITY.md).
## Commandes
| Commande | Description |
|---------|-------------|
| `serve` | Démarrer le serveur hook HTTP pour Claude Code (port 9377). `--enforce` exécute d'abord l'auto-test de contrainte ; `--cedar <dir>` et `--policy <path>` sélectionnent la politique. |
| `init` | Générer une paire de clés Ed25519 (`keys/gateway.json`), un modèle de configuration et une politique exemple. |
| `sample` | Alimenter un enregistrement exemple clairement étiqueté (8 décisions : un appel bloqué, deux paiements ; kid `sample-demo`) plus une copie falsifiée, afin que `record`, `claim`, `verify-claim` et `anchor-record` soient rejouables à partir de zéro avant de connecter un agent. Refuse de toucher un enregistrement existant ; `--force` passe outre. |
| `policy` | Voir et modifier la politique Cedar depuis le terminal : `policy list` (permit / forbid / default-deny par outil, avec combien de fois la passerelle l'a autorisé ou refusé), `policy show`, `policy allow <tool>`, `policy deny <tool>`, `policy path`. Un `serve` en cours recharge automatiquement les modifications. |
| `wrap` | Afficher une commande MCP protégée ou patcher les serveurs MCP de Claude Desktop. Simulation par défaut ; utilisez `--write` pour mettre à jour la configuration Claude Desktop. |
| `dashboard` | Démarrer un tableau de bord local uniquement sur `127.0.0.1` montrant l'inventaire des outils, le risque, la couverture de politique, les approbations d'actions exactes, les chaînes de reçus et l'export d'audit. |
| `recommend` | Rédiger une politique JSON révisable à partir des appels locaux observés. Simulation par défaut ; utilisez `--write` pour créer `protect-mcp.recommended.json`. |
| `registry` | Créer une identité d'org, ancrer des condensés de reçus et écrire une page de vérification statique. Le mode hébergé télécharge uniquement les condensés. |
| `record` | Ouvrir un visualiseur local et consultable de vos reçus (`--live` diffuse en continu pendant l'exécution de l'agent) : signatures Ed25519 vérifiées dans votre navigateur par rapport à votre clé de passerelle, étiquettes de capacité, arbre de provenance et export signé en un clic. Tout en local, rien n'est téléchargé. |
| `claim` | Émettre une attestation signée et indépendante de la position d'un prédicat sur l'enregistrement (`--no <cap>` incl. `--no payment`, `--only <c1,c2>`, `--no-verdict <verdict>`, `--count <verdict>`, `--payment-under <cap>`), ne divulguant que les catégories de décisions. Ajoutez `--anchor` pour enregistrer le condensé de la revendication dans le journal de transparence publique ; les clés enregistrées ancrent en tant qu'org nommé. |
| `anchor-record` | Point de contrôle de la racine Merkle + nombre + plage temporelle de l'enregistrement dans le journal public (compatible avec les battements de cœur : ignoré si inchangé). Une revendication ultérieure dont l'engagement correspond à un point de contrôle ancré est prouvablement sur l'enregistrement complet à ce point de contrôle. |
| `verify-claim` | Vérifier un pack de revendication hors ligne : signature, racine Merkle recalculée, prédicat recalculé indépendamment, et le sidecar d'ancrage lorsqu'il est présent (lie l'enveloppe ancrée à cette revendication exacte, puis confirme que le journal public la contient). `--check-anchor` nécessite l'ancrage ; `--offline` saute l'étape du journal. |
| `killer-demo` | Générer un pack de démo complet allant du mode fantôme à la politique, à l'approbation et aux reçus signés. |
| `verify-disclosure` | Vérifier un package `scopeblind.selective_disclosure.v0` et expliquer les champs divulgués par rapport aux champs cachés. |
| `policy-packs` | Lister, inspecter et installer des packs de politique Cedar de démarrage. |
| `evaluate` | Évaluer un appel d'outil par rapport à une politique Cedar (porte PreToolUse). Code de sortie 2 = refusé (échec-fermé), code de sortie 0 = autorisé. |
| `sign` | Signer un appel d'outil dans un reçu (PostToolUse). Au mieux : enregistre une ligne honnête non signée si aucune clé. |
| `simulate` | Simuler une politique par rapport à un journal de décisions enregistré pour voir ce qu'elle aurait bloqué. |
| `demo` | Démarrer un serveur de démo intégré enveloppé avec la passerelle, pour voir les reçus instantanément. |
| `doctor` | Vérifier votre installation (clés, politiques, moteur Cedar, vérificateur) et exécuter l'auto-test de contrainte. |
| `bundle` | Exporter un bundle d'audit vérifiable hors ligne des reçus plus la clé publique. |
| `report` | Générer un rapport de conformité (Markdown ou JSON) à partir du journal de décisions et des reçus. |
Exécutez `npx protect-mcp --help` pour la référence complète des options.
## Liens
- Protocole (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)
Sous licence MIT. Construit par [ScopeBlind](https://scopeblind.com).