protect-mcp — плагин для Claude Code: Cedar-политики и подписанные
Проверяет каждый вызов инструмента по политике Cedar и выдаёт Ed25519-подписанную квитанцию. Пригодится, когда агенту нужно ограничить доступ к файлам и командам.
/plugin marketplace add wshobson/agents
/plugin install protect-mcp@claude-code-workflowsЧто делает protect-mcp
Плагин ставит два хука: PreToolUse прогоняет вызов через движок Cedar, PostToolUse пишет подписанную квитанцию. Если политика запрещает действие, хук завершается с кодом 2 и инструмент не запускается. Разрешённый вызов выполняется как обычно, а в ./receipts/receipts.jsonl добавляется запись с полями payload.tool, payload.decision, payload.request_id, issued_at и kid.
Внутри — скилл protect-mcp-setup с руководством по настройке, агент policy-enforcer для написания политик под вашу модель угроз и receipt-verifier для разбора ошибок проверки. Есть слэш-команды /verify-receipt <path> и /audit-chain [--last N]. Политику вы пишете сами в ./protect.cedar: готового набора правил плагин не приносит, а примеры в руководстве разбирают только чтение, запись внутри проекта и запрет на rm -rf.
Ключ подписи лежит в ./protect-mcp.key, и его нужно создать один раз до первого запуска — команда init его не генерирует. Существующий ключ плагин не перезаписывает, поэтому для ротации сначала архивируйте ключ и receipts.jsonl. Проверка идёт офлайн через npx @veritasacta/[email protected] --replay-chain, но npx тянет верификатор из сети при первом вызове: перед отключением от интернета выполните npm install --no-save @veritasacta/[email protected] в проекте. Квитанции не связаны ссылкой с предыдущей, так что удалённую строку проверка не заметит.
Какие задачи решает
- запретить агенту писать за пределами каталога проекта
- заблокировать разрушительные команды вроде
rm -rfдо запуска - получить журнал вызовов инструментов, который можно проверить офлайн
- описать правила доступа декларативно вместо правок в коде хуков
- разобраться, почему проверка квитанции вернула ошибку
Примеры запросов агенту
- Помоги написать политику Cedar для
./protect.cedar: разреши чтение и запись только внутри проекта - Проверь квитанцию из
./receipts/receipts.jsonlкомандой/verify-receipt - Покажи последние 20 записей цепочки через
/audit-chain --last 20
Как установить protect-mcp
Через маркетплейс плагинов
/plugin marketplace add wshobson/agents/plugin install protect-mcp@claude-code-workflowsПо шагам, с командами для каждой платформы: Плагины Claude Code: маркетплейсы, установка и как собрать свой
Вопросы о protect-mcp
Как установить protect-mcp в Claude Code?
Сначала добавьте маркетплейс: /plugin marketplace add wshobson/agents. Затем установите плагин: /plugin install protect-mcp@claude-code-workflows.
Что делает protect-mcp?
Проверяет каждый вызов инструмента по политике Cedar и блокирует запрещённые до выполнения. Разрешённые вызовы получают Ed25519-подписанную квитанцию в ./receipts/receipts.jsonl.
Что нужно подготовить до первого запуска?
Файл политики ./protect.cedar и ключ подписи ./protect-mcp.key — команда init ключ не создаёт. Ключ стоит добавить в .gitignore.
Исходный текст
protect-mcp · MIT
# protect-mcp Cedar policy enforcement + Ed25519 signed receipts for every Claude Code tool call. [](https://www.npmjs.com/package/protect-mcp) [](https://www.npmjs.com/package/protect-mcp) [](../../LICENSE) The first Claude Code plugin that enforces declarative authorization policies and produces cryptographically verifiable audit trails. Every tool call is evaluated against a Cedar policy, every tool call that runs gets an Ed25519-signed receipt, and every receipt is verifiable offline by anyone with the public key. ## What You Get - **Cedar policy enforcement** — Block tool calls that violate your rules before they execute. Cedar is AWS's open authorization engine, formally verified. - **Ed25519 signed receipts**: every tool call that runs produces a tamper-evident receipt, signed with RFC 8032 Ed25519 over RFC 8785 JCS canonical bytes. - **Receipts file**: receipts are appended to `./receipts/receipts.jsonl`. A modified receipt fails verification, but receipts carry no link to the previous receipt, so a deleted line goes undetected. - **Offline verification**: `npx @veritasacta/[email protected] --replay-chain` with the public key needs no vendor lookup or account. `npx` downloads the verifier on first use, so run `npm install --no-save @veritasacta/[email protected]` in the project before you go offline. ## Quick Start ```bash # 1. Install this plugin claude plugin install wshobson/agents/protect-mcp # 2. Create a Cedar policy file at ./protect.cedar # (see skills/protect-mcp-setup/SKILL.md for examples) # 3. Create the signing key once (protect-mcp 0.7.4 sign does not create it). # Installing the plugin already registers the hooks. An existing key is # never replaced. To rotate it, archive the key and receipts.jsonl first. if [ ! -e ./protect-mcp.key ]; then d=$(mktemp -d) && npx [email protected] init --dir "$d" && mv "$d/keys/gateway.json" ./protect-mcp.key fi echo "/protect-mcp.key" >> .gitignore # 4. Run Claude Code normally — every tool call is now policy-evaluated # and produces a signed receipt in ./receipts/ ``` ## What's Included ``` plugins/protect-mcp/ ├── skills/protect-mcp-setup/SKILL.md — Full setup and usage guide ├── agents/policy-enforcer.md — Cedar policy author (Opus) ├── agents/receipt-verifier.md — Chain verification expert (Sonnet) ├── commands/verify-receipt.md — /verify-receipt <path> ├── commands/audit-chain.md — /audit-chain [--last N] └── hooks/hooks.json — PreToolUse + PostToolUse hooks ``` ## How It Works ``` ┌─────────────────────────────────────────────┐ │ Claude Code tool call │ │ (Bash, Edit, Write, Read, WebFetch...) │ └────────────────┬────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────┐ │ PreToolUse hook → Cedar policy evaluation │ │ │ │ permit / forbid based on: │ │ - principal (the agent) │ │ - action (the tool) │ │ - resource (the target) │ │ - context (command patterns, paths, etc) │ │ │ │ Cedar deny → exit 2, tool blocked │ │ Cedar permit → tool executes │ └────────────────┬────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────┐ │ Tool executes (or doesn't) │ └────────────────┬────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────┐ │ PostToolUse hook → Ed25519 signed receipt │ │ │ │ Receipt fields (v2 envelope): │ │ - payload.tool, payload.decision │ │ - payload.request_id, issued_at, kid │ │ - signature over every other field │ │ - no public key, no link to the │ │ previous receipt │ │ │ │ Appended to ./receipts/receipts.jsonl │ └─────────────────────────────────────────────┘ ``` ## Example Cedar Policy ```cedar // Allow read-only tools. One rule can cover several tools: leave `resource` // open in the scope and compare it in `when`. permit ( principal, action == Action::"MCP::Tool::call", resource ) when { resource == Tool::"Read" || resource == Tool::"Glob" || resource == Tool::"Grep" }; // Writes and edits only inside the project. Claude Code passes absolute // paths, so match your project's path, not "./*". `like` matches the raw // string, so it is not a path containment check: the forbid rejects `..`. permit ( principal, action == Action::"MCP::Tool::call", resource ) when { (resource == Tool::"Write" || resource == Tool::"Edit") && context has input && context.input has file_path && context.input.file_path like "/path/to/project/*" }; forbid ( principal, action == Action::"MCP::Tool::call", resource ) when { (resource == Tool::"Write" || resource == Tool::"Edit") && context has input && context.input has file_path && (context.input.file_path like "*/../*" || context.input.file_path like "*/..") }; // Never allow destructive shell commands. Substring patterns also catch // `cd x && rm -rf y`, but matching shell commands as strings is best-effort: // a determined rewording can still get through. forbid ( principal, action == Action::"MCP::Tool::call", resource == Tool::"Bash" ) when { context has input && context.input has command && (context.input.command like "*rm -rf*" || context.input.command like "*dd if=*" || context.input.command like "*mkfs*" || context.input.command like "*shred*") }; ``` Ask the `policy-enforcer` agent to help you author policies for your project's threat model. ## Verification Every receipt can be verified by any party, offline, with the `publicKey` value from `./protect-mcp.key`: ```bash PUB=$(node -p 'JSON.parse(require("fs").readFileSync("./protect-mcp.key")).publicKey') npx @veritasacta/[email protected] --replay-chain ./receipts/receipts.jsonl --key "$PUB" # Exit 0 = every receipt verified # Exit 1 = a receipt failed (tampered, wrong key, or malformed line) # Exit 2 = the file could not be read ``` The receipts carry no link to the previous receipt, so a deleted line goes undetected. Use the `receipt-verifier` agent for help interpreting verification failures. ## Standards - **Ed25519** — [RFC 8032](https://datatracker.ietf.org/doc/html/rfc8032) - **JCS** — [RFC 8785](https://datatracker.ietf.org/doc/html/rfc8785) - **Cedar** — [AWS's open authorization engine](https://www.cedarpolicy.com/) - **IETF Internet-Draft** — [draft-farley-acta-signed-receipts](https://datatracker.ietf.org/doc/draft-farley-acta-signed-receipts/) ## Related - **npm**: [protect-mcp](https://www.npmjs.com/package/protect-mcp) - **Verification CLI**: [@veritasacta/verify](https://www.npmjs.com/package/@veritasacta/verify) - **Cedar integration**: Contributor to [cedar-policy/cedar-for-agents](https://github.com/cedar-policy/cedar-for-agents) (PR #64 merged) - **Microsoft AGT**: Integrated in [microsoft/agent-governance-toolkit](https://github.com/microsoft/agent-governance-toolkit) (PR #667 merged) - **Source**: [github.com/ScopeBlind/scopeblind-gateway](https://github.com/ScopeBlind/scopeblind-gateway) - **Protocol docs**: [veritasacta.com](https://veritasacta.com) ## License MIT. See [LICENSE](../../LICENSE).
© Tom Farley · MIT · wshobson/agents