
scopeblind-gateway v0.13.1
Ricevute firmate Ed25519 + politiche Cedar per agenti AI. Gate del mandato finanziario (Legate), proof packs, 3 IETF Internet-Drafts. npx protect-mcp
protect-mcp
Gate di policy Cedar fail-closed più ricevute firmate per le chiamate agli strumenti degli agenti AI.
protect-mcp è un gate che si pone davanti alle chiamate agli strumenti di un agente AI. Valuta
ogni chiamata rispetto a una policy Cedar (lo stesso linguaggio
che AWS usa per IAM), blocca ciò che viola le regole prima che venga eseguito, e firma una
ricevuta Ed25519 verificabile offline di ogni decisione. Viene eseguito localmente, non invia
telemetria delle tue decisioni da nessuna parte, ed è distribuito con licenza MIT.
Perché è diverso
- Fail-closed per impostazione predefinita. In caso di qualsiasi errore di policy, engine mancante, o
fallimento di valutazione, la decisione è DENY. Il gate non consente mai silenziosamente. Esiste una
modalità observe per il rollout in shadow, ma anche lì una chiamata che verrebbe
bloccata è contrassegnata con
would_deny: true, così un fallimento non è mai silenzioso. - Dimostra la propria moderazione.
serve --enforceedoctoreseguono un self-test all'avvio e rifiutano di armare il gate a meno che non possano dimostrare che un'azione notoriamente proibita venga effettivamente negata. Un gate che non può dimostrare di negare non si avvia. - Ogni decisione è una ricevuta che chiunque può verificare. Le decisioni sono firmate con Ed25519
e verificabili offline con
@veritasacta/verify. Nessuna fiducia nel fornitore richiesta: la matematica non si cura di chi la esegue.
Quickstart: dall'installazione alla prima prova utile```bash
1. Generate an Ed25519 keypair, config template, and sample policy.
npx protect-mcp init
2. Wrap any MCP server in shadow mode. Nothing is blocked yet; calls are logged.
npx protect-mcp wrap -- node your-mcp-server.js
3. Inspect the local-only dashboard: tool inventory, risk, approvals, receipts.
npx protect-mcp dashboard --open
4. Draft a reviewable policy from observed calls.
npx protect-mcp recommend --write
5. When reviewed, restart the wrapper in enforce mode with that policy.
npx protect-mcp --policy protect-mcp.recommended.json --enforce -- node your-mcp-server.js
Per Claude Desktop, esegui prima una patch di configurazione dry-run, poi applicala:```bash
npx protect-mcp wrap --claude-desktop
npx protect-mcp wrap --claude-desktop --write
npx protect-mcp dashboard --open
La dashboard si associa a 127.0.0.1, legge solo file di log/ricevute locali e non
carica nulla. Usa npx protect-mcp connect solo se desideri esplicitamente una
dashboard ScopeBlind ospitata.
Il gate come server MCP
Se preferisci chiamare il gate come strumenti anziché configurare gli hook di Claude Code, eseguilo come server MCP:```bash npx protect-mcp mcp
Parla MCP su stdio ed espone quattro strumenti di sola lettura, l'intero ciclo:
- **`evaluate_action`**: valuta una chiamata a uno strumento proposta rispetto a una policy Cedar inline, fail-closed (qualsiasi errore di policy è DENY). Restituisce `{ allowed, decision, reason, policy_digest }`.
- **`sign_decision`**: trasforma una decisione in una ricevuta firmata Ed25519 (un diniego firma un `gateway_restraint`, un'autorizzazione un `decision_receipt`). Restituisce la ricevuta e la sua chiave pubblica; genera una chiave effimera se non ne fornisci una.
- **`verify_receipt`**: verifica una ricevuta firmata offline rispetto a una chiave pubblica. Restituisce `{ valid, error, type, kid, issuer }`.
- **`self_test`**: lo dimostra, senza input. Un'azione nota come vietata viene negata, poi una ricevuta firmata completa un round-trip e una copia manomessa fallisce.
Punta qualsiasi host MCP verso di esso, ad esempio Claude Desktop:```json
{
"mcpServers": {
"protect-mcp": { "command": "npx", "args": ["-y", "protect-mcp", "mcp"] }
}
}
I receipt sono byte-compatibili con quelli che il gate firma a runtime, quindi un
receipt generato qui si verifica con @veritasacta/verify
e il verificatore del browser allo stesso modo.
Dashboard delle azioni locali
protect-mcp dashboard è la vista dell'operatore per passare dalla visibilità
all'applicazione:
- Inventario degli strumenti: ogni strumento osservato, conteggio delle chiamate, rischio alto/medio/basso e se la policy attiva ha una regola esatta, un fallback con wildcard o nessuna regola.
- Copertura della policy: modifiche alla policy locale con un clic per
Require approval,BlockoObserve. Riavvia il wrapper dopo aver esaminato le modifiche. - Coda di approvazione delle azioni esatte: lo strumento esatto, l'azione, la destinazione, l'anteprima del payload redatto, l'hash del payload, la base della policy e la cattura del motivo prima che un umano approvi, neghi, modifichi o prenda il controllo.
- Catena dei receipt: id delle richieste correlati con gli hash dei receipt firmati, così un revisore di audit può vedere quali decisioni hanno una prova crittografica.
- Esportazione dell'audit: scarica il bundle di audit verificabile offline quando esistono receipt firmati. Se esistono solo log locali non firmati, la dashboard spiega che la firma deve essere abilitata prima.
Per le approvazioni di fallback desktop in tempo reale, avvia la dashboard con l'endpoint di approvazione
del gateway locale e il nonce stampati dal wrapper:```bash
npx protect-mcp dashboard --open
--approval-endpoint http://127.0.0.1:9876
--approval-nonce "$PROTECT_MCP_APPROVAL_NONCE"
`Approve` inoltra al gateway locale live quando quei flag sono presenti.
`Deny`, `Edit` e `Take over` vengono registrati localmente come record di
risoluzione dell'approvazione; usali come istruzione dell'operatore e riesegui lo strumento quando necessario.
### Paid Boundary MVP: ancoraggio del digest, non caricamento dei dati
Le ricevute locali auto-firmate restano gratuite e verificabili offline. Il confine a pagamento è
una prova indipendente che ScopeBlind ha visto un digest di una ricevuta in un determinato momento, sotto un'identità
di organizzazione, senza ricevere il prompt grezzo, il payload dello strumento, l'output, la chiave privata o la
ricevuta grezza.```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'anteprima locale è deliberatamente etichettata local-preview-not-independent.
La modalità ospitata ancora solo gli hash delle ricevute, gli ID delle richieste, le chiavi pubbliche dell'organizzazione e i metadati di fatturazione. Non carica ricevute grezze o contesto sensibile.
Killer Demo: da shadow a policy a proof
protect-mcp killer-demo genera un pacchetto completo di vendita/demo di tre minuti:```bash
npx protect-mcp killer-demo --dir ./scopeblind-demo
Crea un filesystem, GitHub, email e attività PMS fittizi; mostra le chiamate rischiose in
modalità shadow; applica un policy pack; richiede l'approvazione per una prenotazione PMS sensibile;
esegue attraverso il gateway; scrive una ricevuta firmata; dimostra che la ricevuta
originale viene verificata; dimostra che una ricevuta manomessa fallisce; e crea un pacchetto
di divulgazione selettiva che nasconde il contesto sensibile mostrando la prova minima.
Apri prima il file `DEMO-RUNBOOK.md` generato. Poi esegui il comando della dashboard
stampato per guidare un cliente attraverso la sequenza esatta.
### Selective Disclosure v0
Le ricevute in modalità commitment possono contenere un `committed_fields_root` invece di esporre
ogni campo in chiaro. Successivamente, il titolare può divulgare solo i campi selezionati:```bash
npx protect-mcp verify-disclosure \
--receipt ./receipts/selective-disclosure.receipt.json \
--disclosure ./receipts/selective-disclosure.tool-only.json
Il verificatore controlla l'hash della ricevuta padre, la firma Ed25519, la radice di commitment e la prova di Merkle di ogni campo divulgato. Spiega poi quali campi sono stati divulgati e quali campi oggetto di commitment rimangono nascosti. Si tratta di divulgazione con commitment salato, non di zero-knowledge completo, ma rende concreta l'affermazione sulla privacy: i revisori possono verificare fatti selezionati senza ricevere il payload completo dello strumento o il contesto sensibile del desk.
Dimostrare un'affermazione sul record (attestazioni position-blind)
Puoi dimostrare un'ASSERZIONE sul tuo record senza rivelarlo. Conia un'attestazione firmata e position-blind sull'intero record che divulga solo categorie per decisione (un digest della ricevuta, il verdetto, i tag di capacità), mai i tuoi input, output o dati dello strumento:```bash
"No action reached the network across the record":
npx protect-mcp claim --no net.egress
other predicates:
--only fs.read,fs.write all actions were confined to these capabilities
--no-verdict blocked no action was blocked
--count blocked how many were blocked
Chiunque può verificarlo offline, vedendo solo le categorie, mai il contenuto:```bash
npx protect-mcp verify-claim claim-<id>.json
Il verificatore ricalcola una radice Merkle sull'insieme divulgato e ricalcola il predicato in modo indipendente, quindi l'emittente non può mentire sulla dichiarazione data la divulgazione. Aggiungi --anchor per registrare il digest della dichiarazione nel registro di trasparenza ScopeBlind pubblico e append-only, così una controparte che non si fida di te può confermare che l'insieme divulgato è completo e non è stato silenziosamente ritagliato (viene inviato solo l'hash; il record rimane locale):```bash
npx protect-mcp claim --no net.egress --anchor
Questa è un'attestazione responsabile e cieca alla posizione, non un zero-knowledge completo: rivela la forma, non il contenuto.
## Provalo in 60 secondi (nessun agente richiesto)
[](https://legate.scopeblind.com/record)
Guarda il film di due minuti su [legate.scopeblind.com/record](https://legate.scopeblind.com/record), poi riproducilo sulla tua 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
Metti il file demo-tampered.jsonl generato nella pagina del record per vedere
un'alterazione successiva alla firma venire individuata. sample si rifiuta di toccare un record esistente, quindi
eseguilo in una cartella vuota. Quando sei pronto per il caso reale, collega il gate
qui sotto e gli stessi comandi verranno eseguiti sul record del tuo agente.
Avvio rapido dell'hook di Claude Code```bash
Generate hook config and a sample Cedar policy.
npx protect-mcp init-hooks
Serve the Claude Code hook gate in enforce mode. It runs a restraint self-test
first and refuses to start if it cannot prove it denies a forbidden vector.
npx protect-mcp serve --enforce --cedar ./cedar
Valutazione one-shot, nel modo in cui la chiama un hook PreToolUse. Il codice di uscita 2 significa nega
(lo strumento è bloccato); il codice di uscita 0 significa consenti:```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 policy mancante o non caricabile nega l'accesso (exit 2) a meno che tu non passi esplicitamente
--fail-on-missing-policy false.
Hook di Claude Code
protect-mcp init-hooks scrive un .claude/settings.json per te. Per collegare il
gate manualmente, i due verbi di cui hai bisogno sono evaluate (PreToolUse, blocca con exit 2)
e sign (PostToolUse, registra una ricevuta). Fissa la versione in modo che una sessione di Claude Code
esegua sempre il gate che hai testato:```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"
}
]
}
]
}
}
### Firma la decisione politica stessa
Dalla versione 0.13.0, `sign` può valutare la policy e registrare la decisione reale nella
ricevuta invece di un'autorizzazione incondizionata. Passa la directory della policy e lo
stesso input e contesto che l'hook passerebbe a `evaluate`:```bash
npx [email protected] sign --cedar ./cedar --tool Bash \
--input '{"command":"rm -rf /"}' --context '{"command_pattern":"rm -rf"}' \
--receipts ./receipts --key ./keys/gateway.json
Il payload del receipt porta quindi decision (allow o deny), reason
(cedar_allow o cedar_deny), e policy_digest (il digest acta-policy-digest-v1
del set di policy), e cita draft-farley-acta-signed-receipts-03. Il
comando stampa la decisione e il digest su stdout. Un deny viene comunque firmato: il
receipt è il record della decisione, non il permesso di procedere.
Sono supportati due modelli di azione Cedar. Il runtime gate valuta
Action::"MCP::Tool::call" con il tool come risorsa, che è ciò che le
policy in cedar/ si aspettano e ciò che sign --cedar usa per impostazione predefinita. Le policy
che nominano il tool come azione (action == Action::"Bash"), come la
policy di conformità pubblicata in agent-governance-testvectors, richiedono
--action-model tool. evaluate accetta lo stesso flag.
evaluate esce con 2 in caso di deny così Claude Code blocca la chiamata al tool, e 0 in caso di allow.
sign è best-effort: aggiunge un receipt firmato con Ed25519 quando una chiave è
configurata, e se nessun firmatario è disponibile registra una riga non firmata onesta
("signed": false) invece di far fallire il tool.
Usalo in altri agenti (Codex, Cursor, Gemini, Hermes)
Lo stesso gate fail-closed viene eseguito come hook del tool in qualsiasi agente che li supporti. Aggiungi
--format <host> così il verbo legge il payload dell'hook di quell'host da stdin e nega
nel suo contratto:```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
Associa ciascuno con `sign --format <host>` sull'evento post-tool per le ricevute. Il caso importante è **Hermes**, che ignora i codici di uscita degli hook e legge il verdetto da stdout, quindi `--format hermes` nega tramite `{"decision":"block"}` anziché exit 2 (un exit-2 grezzo fallirebbe silenziosamente in modalità aperta in quel contesto). Senza `--format`, i verbi leggono i flag `--tool`/`--input` esattamente come nella sezione Claude Code sopra.
## Scrivere una policy
Le policy Cedar risiedono in una directory che indichi con `--cedar`. Una regola `forbid` nega, una regola `permit` consente. Per confrontare un valore nell'input del tool, usa l'idioma `.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"
);
Pericolo: NON scrivere
context.command in ["rm", "dd"]per confrontare una stringa con una lista.inè per le gerarchie di entità, non per l'appartenenza a stringhe. Cedar tratta l'espressione come un errore di tipo e scarta silenziosamente l'intera regolaforbid, il che (sotto un gate fail-open) lascia in piedi unpermitresiduo. Questo è il difetto esatto alla base dell'advisory seguente. Usa invece[...].contains(context.command). Dalla 0.7.0 il gate nega su quell'errore anziché permettere, e un test tripwire in CI fa fallire la build se il pattern viene reintrodotto in una policy distribuita. Vedi GHSA-hm46-7j72-rpv9.
Pacchetti di policy iniziali
La maggior parte dei team non dovrebbe scrivere Cedar da zero il primo giorno. Installa un pacchetto iniziale, esegui in modalità shadow, ispeziona le ricevute, poi stringi o applica:```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
Pacchetti integrati:
- `filesystem-safe`: azioni distruttive sui file e letture di percorsi simili a segreti.
- `git-safe`: force push, hard reset, pulizie distruttive, cancellazione di repository.
- `email-safe`: consente la bozza, blocca gli invii non presidiati.
- `database-safe`: postura DB orientata alla lettura, blocca SQL di scrittura/admin.
- `cloud-spend-safe`: creazione evidente di spesa cloud e distruzione di infrastrutture.
- `secrets-safe`: esfiltrazione comune di segreti da file, env, shell e cloud.
- `finance-mandate-safe`: violazioni di liste ristrette e concentrazione nei flussi di prenotazione.
## Verificare una ricevuta
Le ricevute sono firmate e verificabili offline da chiunque possieda la chiave pubblica. Nessuna
rete, nessun fornitore, nessuna fiducia in ScopeBlind:```bash
npx @veritasacta/verify ./receipts/receipts.jsonl --format jsonl
# Exit 0 = valid, non-zero = tampered or malformed
npx protect-mcp bundle --output audit.json esporta un bundle di audit autonomo e verificabile offline dei tuoi receipt più la chiave di firma pubblica.
Sicurezza
protect-mcp 0.7.0 fallisce in modo chiuso per progettazione. In caso di qualsiasi errore di valutazione della policy, un engine mancante o una policy che ha generato un errore in fase di valutazione, la decisione è DENY, non allow. serve --enforce e doctor eseguono un self-test all'avvio che dimostra che il gate nega un vettore noto come proibito prima che venga considerato attendibile, e rifiutano di attivarsi se non può farlo.
Versioni interessate: 0.5.x e 0.6.x. Quelle linee falliscono in modo aperto (restituiscono ALLOW in caso di errore di valutazione) e non valutano Cedar correttamente rispetto all'engine fissato, quindi una regola forbid potrebbe non riuscire a bloccare. Aggiorna a >= 0.7.0.
Dettagli e remediation: GHSA-hm46-7j72-rpv9. Per segnalare una vulnerabilità, vedi SECURITY.md.
Comandi
| Comando | Descrizione |
|---|---|
serve | Avvia il server HTTP hook per Claude Code (porta 9377). --enforce esegue prima il self-test di restraint; --cedar <dir> e --policy <path> selezionano la policy. |
init | Genera una coppia di chiavi Ed25519 (keys/gateway.json), un template di configurazione e una policy di esempio. |
sample | Inizializza un record di esempio chiaramente etichettato (8 decisioni: una chiamata bloccata, due pagamenti; kid sample-demo) più una copia manomessa, così record, claim, verify-claim e anchor-record sono riproducibili da zero prima di collegare un agente. Rifiuta di toccare un record esistente; --force lo forza. |
policy | Visualizza e modifica la policy Cedar dal terminale: policy list (permit / forbid / default-deny per tool, con quante volte il gate l'ha consentito o negato), policy show, policy allow <tool>, policy deny <tool>, policy path. Un serve in esecuzione ricarica a caldo alla modifica. |
wrap | Stampa un comando MCP protetto o applica patch ai server MCP di Claude Desktop. Dry-run per impostazione predefinita; usa --write per aggiornare la configurazione di Claude Desktop. |
dashboard | Avvia una dashboard solo locale su 127.0.0.1 che mostra inventario dei tool, rischio, copertura delle policy, approvazioni di azioni esatte, catene di receipt ed export di audit. |
recommend | Redige una policy JSON revisionabile dalle chiamate locali osservate. Dry-run per impostazione predefinita; usa --write per creare protect-mcp.recommended.json. |
registry | Crea un'identità di organizzazione, ancora i digest dei receipt e scrive una pagina di verifica statica. La modalità hosted carica solo i digest. |
record | Apre un visualizzatore locale e ricercabile sui tuoi receipt (--live trasmette mentre l'agente è in esecuzione): firme Ed25519 verificate nel tuo browser contro la chiave del tuo gateway, tag di capability, un albero di provenienza ed export firmato con un clic. Tutto locale, nulla caricato. |
claim | Conia un'attestazione firmata e position-blind di un predicato sul record (--no <cap> incl. --no payment, --only <c1,c2>, --no-verdict <verdict>, --count <verdict>, --payment-under <cap>), divulgando solo le categorie di decisione. Aggiungi --anchor per registrare il digest del claim nel log di trasparenza pubblico; le chiavi registrate si ancorano come organizzazione nominata. |
anchor-record | Registra come checkpoint la Merkle root del record + conteggio + intervallo temporale nel log pubblico (compatibile con heartbeat: salta quando invariato). Un claim successivo il cui commitment corrisponde a un checkpoint ancorato è dimostrabilmente relativo al record completo a partire da quel checkpoint. |
verify-claim | Verifica un claim pack offline: firma, Merkle root ricalcolata, predicato ricalcolato in modo indipendente e il sidecar di ancoraggio quando presente (collega l'envelope ancorato a questo esatto claim, poi conferma che il log pubblico lo contiene). --check-anchor richiede l'anchor; --offline salta il passaggio al log. |
killer-demo | Genera un demo pack completo da modalità shadow a policy, ad approvazione, a receipt firmato. |
verify-disclosure | Verifica un pacchetto scopeblind.selective_disclosure.v0 e spiega i campi divulgati rispetto a quelli nascosti. |
policy-packs | Elenca, ispeziona e installa pacchetti di policy Cedar iniziali. |
evaluate | Valuta una chiamata a un tool rispetto a una policy Cedar (gate PreToolUse). Exit 2 = deny (fail-closed), exit 0 = allow. |
sign | Firma una chiamata a un tool in un receipt (PostToolUse). Best-effort: registra una riga non firmata onesta se non c'è chiave. |
simulate | Esegue un dry-run di una policy rispetto a un log di decisioni registrato per vedere cosa avrebbe bloccato. |
demo | Avvia un server demo integrato avvolto con il gate, per vedere i receipt istantaneamente. |
doctor | Controlla la tua configurazione (chiavi, policy, engine Cedar, verifier) ed esegue il self-test di restraint. |
bundle | Esporta un bundle di audit verificabile offline dei receipt più la chiave pubblica. |
report | Genera un report di conformità (Markdown o JSON) dal log delle decisioni e dai receipt. |
Esegui npx protect-mcp --help per il riferimento completo dei flag.
Link
- Protocollo (IETF): draft-farley-acta-signed-receipts
- CHANGELOG
- npm
- scopeblind.com
Licenza MIT. Creato da ScopeBlind.