protect-mcp 实战:为 Claude Code 接入 Cedar 策略门控与 Ed25519 签名审计链
protect-mcp 实战为 Claude Code 接入 Cedar 策略门控与 Ed25519 签名审计链【免费下载链接】agentsMulti-harness agentic plugin marketplace for Claude Code, Codex, Cursor, OpenCode, GitHub Copilot, and Google Antigravity项目地址: https://gitcode.com/GitHub_Trending/agents24/agentsprotect-mcp是 agents 仓库中一个面向 Claude Code 的插件plugins/protect-mcp/README.md它为每一个工具调用提供两层防护调用前由 AWS 开源授权引擎 Cedar 执行策略评估拒绝即拦截调用后生成 Ed25519 签名的、哈希链式相连的不可篡改回执。本文以 skills/protect-mcp-setup/SKILL.md 为骨架结合仓库内的真实钩子配置、测试夹具与配套 Agent完整讲解从安装、策略编写、签名回收到离线验证的落地全流程。Claude Code 工具调用存在三个审计缺口Claude Code 暴露了Bash、Edit、Write、WebFetch等强大工具默认状态下它们既没有策略约束也没有审计痕迹。会话日志session log看似记录了操作但本质上存在三个致命缺陷可篡改Mutable——任何有权限的人都能编辑日志内容未签名Unsigned——无法证明日志的完整性依赖运营方Operator-bound——验证结果建立在相信日志持有者的基础上。对于金融、医疗、受监管研究等合规场景这种事后可以赖账的日志远远不够。你需要的是第三方无需信任你即可独立验证的防篡改证据。方案总览策略门控 签名回执 离线验证protect-mcp用三个技术支柱补齐上述缺口Cedar 策略每个工具调用在执行前都先经过 Cedar 策略评估deny是权威性的命中即拦截Ed25519 签名回执每次 allow/deny 决策都会生成包含输入、治理策略与结果的回执回执之间通过parent_receipt_id哈希链式相连插入、删除、修改均可被检测离线验证npx veritasacta/verify纯本地运行无需服务器、无需账号、无需信任运营方可在断网air-gapped环境工作。整体数据流在 plugins/protect-mcp/README.md 中描述为一条完整流水线工具调用 →PreToolUse钩子做 Cedar 求值permit 放行 / deny 以 exit 2 拦截→ 工具执行 →PostToolUse钩子生成 Ed25519 签名回执写入./receipts/timestamp.json。快速接入四步完成项目治理在项目根目录执行以下操作即可启用# 1. 安装插件向项目注入 hooks 与 skill claude plugin install wshobson/agents/protect-mcp # 2. 在 .claude/settings.json 中配置 hooks见下文 # 3. 启动回执签名服务本地运行无外部调用 npx protect-mcplatest serve --enforce # 4. 正常使用 Claude Code每个工具调用都会被策略评估 # 并在 ./receipts/ 下生成签名回执说明serve --enforce以强制模式启动本地签名服务SKILL.md 中的示例使用latest而仓库内 hooks/hooks.json 固定为0.7.4实际接入时建议锁定版本以保证可复现性。钩子配置PreToolUse 拦截 PostToolUse 签名SKILL.md 给出的最小配置如下写入项目.claude/settings.json{ hooks: { PreToolUse: [ { matcher: .*, hook: { type: command, command: npx protect-mcplatest evaluate --policy ./protect.cedar --tool \$TOOL_NAME\ --input \$TOOL_INPUT\ || exit 2 } } ], PostToolUse: [ { matcher: .*, hook: { type: command, command: npx protect-mcplatest sign --tool \$TOOL_NAME\ --input \$TOOL_INPUT\ --output \$TOOL_OUTPUT\ --receipts ./receipts/ } } ] } }每个钩子做什么PreToolUse工具执行前对工具调用进行 Cedar 策略评估。若策略返回deny钩子以退出码 2 结束Claude Code 会完全拦截该工具调用。PostToolUse工具执行后为已完成的操作签名回执包含工具名、输入哈希、输出哈希、决策结果、策略摘要与时间戳写入./receipts/timestamp.json。仓库内 hooks.json 的进阶配置项实际随插件分发的 hooks/hooks.json 比 SKILL.md 示例更完整引入了三个可通过环境变量覆盖的配置点{ hooks: { PreToolUse: [ { matcher: .*, hooks: [ { type: command, command: npx protect-mcp0.7.4 evaluate --policy \${PROTECT_MCP_POLICY:-./protect.cedar}\ --tool \$TOOL_NAME\ --input \$TOOL_INPUT\ --fail-on-missing-policy false } ] } ], PostToolUse: [ { matcher: .*, hooks: [ { type: command, command: npx protect-mcp0.7.4 sign --tool \$TOOL_NAME\ --input \$TOOL_INPUT\ --output \$TOOL_OUTPUT\ --receipts \${PROTECT_MCP_RECEIPTS:-./receipts/}\ --key \${PROTECT_MCP_KEY:-./protect-mcp.key}\ } ] } ] } }逐项解读配置点默认值作用PROTECT_MCP_POLICY./protect.cedar指定 Cedar 策略文件路径不设置则使用项目根目录默认文件PROTECT_MCP_RECEIPTS./receipts/回执输出目录PROTECT_MCP_KEY./protect-mcp.key签名私钥文件路径用于 Ed25519 签名--fail-on-missing-policy false—策略文件缺失时不阻断调用避免误伤开发流程SKILL.md 示例未包含此开关matcher: .*—匹配全部工具名确保 Bash/Edit/Write/Read/WebFetch 等一律纳入治理可以看到sign命令额外暴露了--key参数说明回执签名使用项目级密钥而非全局密钥不同项目可持有各自的签名身份。编写 Cedar 策略允许清单与禁止规则在项目根目录创建./protect.cedar。SKILL.md 给出的基线策略演示了三类规则写法// 默认放行只读类工具 permit ( principal, action in [Action::Read, Action::Glob, Action::Grep, Action::WebFetch], resource ); // 对破坏性工具要求显式放行仅允许安全命令 permit ( principal, action Action::Bash, resource ) when { // 仅放行安全命令 context.command_pattern in [git, npm, ls, cat, echo, pwd, test] }; // 永远禁止递归删除 forbid ( principal, action Action::Bash, resource ) when { context.command_pattern rm -rf }; // 禁止对项目目录之外的文件执行写入必须二次确认 forbid ( principal, action in [Action::Edit, Action::Write], resource ) when { context.path_starts_with ! . };要点permit与forbid成对出现对高风险动作既写带条件的permit又写覆盖明显危险用例的forbid。Cedar 语义下forbid命中即权威即使存在匹配的permit也一律拒绝context携带工具输入特征Bash用context.command_pattern匹配命令族git/npm/ls 等Edit/Write用context.path_starts_with限定文件系统作用域注释即文档策略是安全关键配置每条规则都应以注释说明意图与所针对的威胁模型。策略实际求值时的实体形状重要实现细节SKILL.md 中的示例为了可读性使用了简化写法如Action::Read。而仓库测试夹具 test/fixtures/test-policy.cedar 的注释明确指出protect-mcp ≥ 0.7.0 实际求值时使用的实体形状是principal Agent::id——调用方是 Agent 实体action Action::MCP::Tool::call——动作统一收敛为一次工具调用而不是每种工具一个 Actionresource Tool::toolName——资源是具体工具名如Tool::Read、Tool::Bash工具入参放在context.input中。对应的真实求值策略形如// 放行只读类工具 permit ( principal, action Action::MCP::Tool::call, resource ) when { resource Tool::Read || resource Tool::Glob || resource Tool::Grep || resource Tool::WebSearch }; // Bash 仅放行安全命令前缀 permit ( principal, action Action::MCP::Tool::call, resource Tool::Bash ) when { context has input context.input has command (context.input.command like git* || context.input.command like npm* || context.input.command like ls* || context.input.command like cat* || context.input.command like echo* || context.input.command like pwd* || context.input.command like node*) }; // 对破坏性命令显式拒绝Cedar forbid 权威 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 * || context.input.command like *mkfs* || context.input.command like *shred*) };注意这里命令匹配使用like通配符如git*作用于context.input.command与 SKILL.md 中基于context.command_pattern集合包含的写法形态不同这正是新旧求值语义差异的体现——接入时请以你所用protect-mcp版本实际求值的实体形状为准可先对照仓库测试策略验证行为再投入生产。三种场景的成熟策略模板agents/policy-enforcer.mdCedar 策略编写 Agent推荐 Opus 模型提供了按风险画像划分的三档模板可直接演化研究型项目只读安全permit全部只读工具 WebSearchforbid覆盖Write/Edit/Bash/WebFetch开发型项目受限写入只读放行Write/Edit仅在context.path_starts_with ./时放行Bash白名单扩展到git/npm/pnpm/yarn/ls/cat/pwd/echo/test/node/python/makeforbid覆盖rm -rf/dd/mkfs/shred生产部署严格显式授权所有动作按context.trust_tierevidenced/institutional分级放行Write仅限./deployments/、./config/Bash仅限kubectl apply、terraform plan、terraform apply最后用兜底forbid拒绝一切未授权动作。编写完成后建议用cedar validate做类型检查若项目带 Cedar schema并对照政策 Agent 提供的审计清单逐条复核是否存在已知危险操作缺少forbid、是否存在无when条件的过度宽泛permit、Edit与Write的放行是否一致、是否存在逻辑缝隙。签名回执格式与密码学基础每次决策产生一个 JSON 回执结构如下来自 SKILL.md{ receipt_id: rec_8f92a3b1, receipt_version: 1.0, issuer_id: claude-code-protect-mcp, event_time: 2026-04-15T10:30:00.000Z, tool_name: Bash, input_hash: sha256:a3f8..., decision: allow, policy_id: autoresearch-safe, policy_digest: sha256:b7e2..., parent_receipt_id: rec_3d1ab7c2, public_key: 4437ca56815c0516..., signature: 4cde814b7889e987... }agents/receipt-verifier.md 给出了更严格的字段规约receipt_id为rec_hashdecision仅允许allow或denypolicy_digest/input_hash为sha256:hexpublic_key为 64 位十六进制32 字节公钥signature为 128 位十六进制64 字节签名首个回执的parent_receipt_id为null。回执的四个密码学属性Ed25519 签名RFC 8032确定性、高性能、安全性经过充分研究的 Edwards 曲线签名方案JCS 规范化RFC 8785签名前对 JSON 按键字典序排序得到确定性字节序列。因为同一份 JSON 有多种合法序列化方式规范化是签名可复现验证的前提哈希链Hash Chain通过parent_receipt_id指向前一张回执形成有页码的账本——撕页、插页都能被发现离线可验证验证不依赖任何网络调用或厂商查询。理解回执时可以参考 agents/receipt-verifier.md 中的三个类比签名如同信封上的火漆印任何人可核对寄件人信封被拆过封印即破损JCS 规范化如同封口前把字词按字母序排列使封印模式可预测哈希链如同有编号的账页页码跳号即证明有人撕过页。验证单张回执与整链审计验证单张回执npx veritasacta/verify receipts/2026-04-15T10-30-00Z.json # Exit 0 有效 # Exit 1 被篡改 # Exit 2 结构畸形验证整条链npx veritasacta/verify receipts/*.json配合 commands/verify-receipt.md 的实现说明veritasacta/verify内部执行六步读取 JSON → 校验结构必填字段与类型→ 提取公钥与签名 → 重建 JCS 规范化形式 → 对规范化字节做 Ed25519 验签 → 输出结果。三个退出码的语义在 agents/receipt-verifier.md 中有完整映射退出码含义处置建议0签名有效、结构规范报告 Verified. Receipt authentic.1签名与载荷不匹配回执被改动报告 TAMPERED提示与已知完好副本比对定位被改字段2缺少必填字段或类型错误报告 MALFORMED列出结构性问题可能签名器有 bug 或伪造者不懂格式常见失败原因的精确诊断签名不匹配说明签名后任一受签字段被修改链断裂parent_receipt_id与前一回执receipt_id不符可能意味着插入、删除或链分叉畸形则是结构层面问题。注意验证失败时不要臆断而是先检查对应回执文件是否确实存在、顺序是否按event_time排序。在 Claude Code 内使用斜杠命令SKILL.md 提供了两个内置命令分别对应 commands/verify-receipt.md 与 commands/audit-chain.md/verify-receipt receipts/latest.json /audit-chain ./receipts/ --last 20/audit-chain支持三个形态/audit-chain——校验./receipts/下全部回执/audit-chain --last 50——只校验最近 50 张/audit-chain --dir /var/log/receipts——指定其他回执目录。其内部流程是列出目标目录全部*.json→ 按event_time排序建立时间序 → 逐张独立验签 → 核对parent_receipt_id与前一张receipt_id是否衔接 → 输出诊断。链级校验还可显式启用--chain标志npx veritasacta/verify --chain $RECEIPT_DIR/*.json。诊断输出会区分两种失败模式链断裂个体签名全部有效但结构被破坏多为插入/删除攻击与单张被篡改链链接完好但某张签名不通过多为事后改载荷。建议在以下时机执行整链审计发布前确认开发链无篡改安全审计时向审计方证明链完整性事件响应后确认日志未被动手脚周期性 CI 任务捕获静默损坏合规评审前提供连续性完整性证据。测试保障从策略求值到防篡改回归仓库在 test/ 下内置了完整的往返测试round-trip体系验证evaluate → sign → verify全链路包括篡改检测路径。夹具设计如下test/fixtures/test-policy.cedar——统一测试策略即上文真实实体形状示例test/fixtures/pretool-allow-read.json——Read应被放行test/fixtures/pretool-allow-bash-safe.json——Bash git status应被放行context.command_pattern: gittest/fixtures/pretool-deny-bash-destructive.json——Bash rm -rf /应被拒绝context.command_pattern: rm -rftest/fixtures/pretool-deny-write.json——Write应被拒绝test/expected/receipt-schema.json——回执的期望 JSON Schema。运行完整往返测试需 node ≥ 18、npx、python3./run-tests.sh首跑会从 npm 拉取protect-mcp与veritasacta/verify随后执行八个场景#场景期望退出码1PreToolUse作用于Read0放行2PreToolUse作用于Bash git status0放行3PreToolUse作用于Bash rm -rf /2拒绝4PreToolUse作用于Write2拒绝5PostToolUse签名生成回执文件0成功6生成回执符合 Schema0有效7veritasacta/verify接受该回执0有效8被篡改的回执被拒绝1被篡改其中测试 8 是关键的回归防线翻转已签名回执中的decision字段必须导致 Ed25519 验签失败veritasacta/verify必须退出 1 而非 0——这直接证明签名锁定载荷的防篡改承诺成立。另有一个 CI 友好的静态校验脚本仅需 python3、无网络调用./verify-fixtures.sh它逐份校验夹具是否为合法 JSON 且结构符合预期适合沙箱或离线 CI。两个脚本均遵循 autotools 惯例退出码 77 表示依赖缺失跳过多数 CI 框架会将其解释为 skip。从信任到可证明治理范式转变SKILL.md 用一张对照表总结了接入前后的本质变化接入前接入后相信我Agent 只读了文件密码学可证明每次 Read 都被记录并签名日志显示它发生了回执证明它发生了且任何人都无法编辑你得审计我们的系统任何人都能离线验证每一张回执日志现在可能已经变了Ed25519 签名在签名时刻锁定记录标准与技术栈一览Ed25519—— RFC 8032 数字签名回执签名算法JCS—— RFC 8785 确定性 JSON 规范化签名前对载荷做规范化处理Cedar—— AWS 开源授权策略语言策略求值引擎deny权威IETF draft-farley-acta-signed-receipts—— 签名回执协议的互联网草案定义回执字段规约。配套资源集中在仓库内安装与总览见 plugins/protect-mcp/README.md完整接入指南即本文骨架 skills/protect-mcp-setup/SKILL.md真实钩子配置见 hooks/hooks.json策略编写与审计交给 agents/policy-enforcer.md回执验证与诊断交给 agents/receipt-verifier.md测试体系见 test/README.md。项目本身是一个面向 Claude Code、Codex、Cursor、OpenCode、GitHub Copilot、Google Antigravity 等多载体multi-harness的 Agentic 插件市场protect-mcp是其中负责合规级审计证据能力的一环。【免费下载链接】agentsMulti-harness agentic plugin marketplace for Claude Code, Codex, Cursor, OpenCode, GitHub Copilot, and Google Antigravity项目地址: https://gitcode.com/GitHub_Trending/agents24/agents创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考