mcpField
P
protect-mcp-setup

protect-mcp-setup

github.com/wshobson安全41.9k6.1k 次安装2 周前更新
代码仓库

关于 protect-mcp-setup

这是 protect-mcp 的配置技能,可对 Claude Code 工具调用应用 Cedar 策略,并生成可离线验证的 Ed25519 签名回执。它面向需要策略执行和可验证记录的团队,包括受监管行业。

主要功能

  1. 01使用 Cedar 策略评估调用
  2. 02工具执行后签署回执
  3. 03支持离线验证回执
  4. 04配置钩子与回执路径
  5. 05提供回执审计命令

适用场景

  1. 01在 Agent 工具运行前执行策略
  2. 02为合规留存可验证记录
  3. 03无需网络连接即可检查回执

MCP 相关

README 将 protect-mcp 描述为 Claude Code 治理插件,并列出面向 MCP 主机的实现。它没有说明此配置会向 MCP 客户端暴露哪些服务端工具或资源。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/wshobson/agents --skill protect-mcp-setup

安装后在 Claude Code 中输入/protect-mcp-setup确认已加载。

附带文件references/receipt-format.md

详细介绍

protect-mcp — 策略执行 + 签名回执

为每次 Claude Code 工具调用提供密码学治理。每次调用都会根据 Cedar 策略进行评估,并生成一份 Ed25519 签名的回执,任何人都可以离线验证。

概述

Claude Code 运行着功能强大的工具:Bash、Edit、Write、WebFetch。默认情况下,既没有审计追踪,也没有策略执行,更无法在事后证明当时做出了什么决策。protect-mcp 填补了这三项空白:

  • Cedar 策略(AWS 的开源授权引擎)在执行前评估每次工具调用。Cedar 的拒绝具有权威性。
  • Ed25519 回执记录每个运行过的工具的名称,并使用你的密钥签名。
  • 离线验证通过 npx @veritasacta/verify 完成。无需服务器、无需账户、无需信任运营方。

问题

AI Agent 做出的决策会影响金钱、安全和权利。Claude Code 的会话日志记录了发生的事情,但日志存在以下问题:

  • 可变——任何有访问权限的人都可以编辑它
  • 未签名——无法证明其完整性
  • 绑定于运营方——验证需要信任持有日志的人

对于合规场景(金融、医疗、受监管的研究),这还不够。你需要可由第三方在不信任你的情况下验证的防篡改证据。

解决方案

将 protect-mcp 添加到你的 Claude Code 项目:

# 1. Install the plugin (adds hooks + skill to your project)
claude plugin install wshobson/agents/protect-mcp

# 2. Create ./protect.cedar (see below). The plugin installs the hooks.

# 3. Create the signing key once (protect-mcp 0.7.4 sign does not create it).
#    An existing key is never replaced. See references/receipt-format.md to rotate.
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. Use Claude Code normally. Every tool call is now policy-evaluated
#    and produces a signed receipt in ./receipts/

Hook 配置

安装该插件会添加 hooks/hooks.json 中的两个 hook。每个 hook 运行一个随插件捆绑的脚本:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": ".*",
        "hooks": [
          { "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/evaluate.sh" }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": ".*",
        "hooks": [
          { "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/hooks/sign.sh" }
        ]
      }
    ]
  }
}

Claude Code 通过 stdin 以 JSON 形式将 hook 事件传递给命令,且不会设置 TOOL_NAME 或 TOOL_INPUT 变量。evaluate.sh 从该载荷中读取 tool_name 和 tool_input,并将它们作为标志传递给 protect-mcp;sign.sh 只读取 tool_name,因为 0.7.4 的签名器不记录其他内容。设置 PROTECT_MCP_POLICY、PROTECT_MCP_RECEIPTS 和 PROTECT_MCP_KEY 可更改默认路径。当策略文件缺失时,PreToolUse hook 会向 stderr 打印警告并允许该调用。

每个 hook 的作用

PreToolUse — 在工具执行之前运行。根据你的 Cedar 策略文件评估工具调用。如果 Cedar 返回 deny,该 hook 以代码 2 退出,Claude Code 会完全阻止该工具调用。

PostToolUse 在工具完成后运行。它会签署一份回执,记录工具名称,并将其追加到 ./receipts/receipts.jsonl。protect-mcp 0.7.4 不记录工具输入或输出。

Cedar 策略文件

在项目根目录创建 ./protect.cedar:

// Read-only tools: one rule can name several tools in `when`. Add WebFetch
// with your own URL rule.
permit (principal, action == Action::"MCP::Tool::call", resource) when {
    resource == Tool::"Read" || resource == Tool::"Glob" || resource == Tool::"Grep"
};

// Safe commands only; git limited to read subcommands
permit (principal, action == Action::"MCP::Tool::call", resource == Tool::"Bash") when {
    context has input && context.input has command &&
    (context.input.command like "git status*" || context.input.command like "git diff*" ||
     context.input.command like "git log*" || context.input.command like "git show*" ||
     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 "test*")
};

// No chaining (`&` also denies `2>&1`), `$` expansion, redirection (`>` or
// `<`, which covers `<(`), file output (`git diff --output`), or rm -rf
forbid (principal, action == Action::"MCP::Tool::call", resource == Tool::"Bash") when {
    context has input && context.input has command &&
    (context.input.command like "*;*" || context.input.command like "*&*" ||
     context.input.command like "*|*" || context.input.command like "*$*" ||
     context.input.command like "*`*" || context.input.command like "*>*" ||
     context.input.command like "*<*" || context.input.command like "*\n*" ||
     context.input.command like "*--output*" || context.input.command like "*rm -rf*")
};

// Writes only inside the project (paths are absolute), never via `..`
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 "*/..")
};

字符串匹配是尽力而为:like 检查的是原始字符串,而不是解析后的路径,而且 npm* 许可会运行任意代码,因此其安全性仅与项目的脚本相当。

验证

使用 ./protect-mcp.key 中的公钥验证每一份回执:

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

该插件的斜杠命令在 Claude Code 内部执行相同的操作。/verify-receipt 接受一份单独文件中的回执,例如来自 tail -n 1 ./receipts/receipts.jsonl > receipt.json。

/verify-receipt receipt.json
/audit-chain --last 20

回执格式

每份回执是 ./receipts/receipts.jsonl 中的一行。示例见 references/receipt-format.md。

  • 对除 signature 之外的所有字段使用 Ed25519 签名(RFC 8032)
  • 签名前进行 JCS 规范化(RFC 8785)
  • 回执中不含公钥,因此需通过 --key 传入
  • 与上一份回执无关联,因此删除某一行不会被发现

为何重要

之前之后
“相信我,Agent 只读取了文件”密码学上可证明:每次 Read 都被记录并签名
“日志显示它发生了”回执证明它发生了,且无人可以编辑
“你得审计我们的系统”任何人都可以离线验证每一份回执
“日志到现在可能已经不一样了”Ed25519 签名在签名时锁定记录

标准

  • Ed25519 — RFC 8032(数字签名)
  • JCS — RFC 8785(确定性 JSON 规范化)
  • Cedar — AWS 的开放授权策略语言
  • IETF 草案 — draft-farley-acta-signed-receipts

相关

评论

支持 Markdown