MCP 工具调用治理实战:基于 Cedar 策略与 Ed25519 签名的 GovernanceReceipt 审计方案
【免费下载链接】agent-governance-toolkitAI Agent Governance Toolkit — Policy enforcement, zero-trust identity, execution sandboxing, and reliability engineering for autonomous AI agents. Covers 10/10 OWASP Agentic Top 10.项目地址: https://gitcode.com/GitHub_Trending/ag/agent-governance-toolkit
本篇指南以 Agent Governance Toolkit 仓库中的examples/mcp-receipt-governed示例为核心,讲解如何为 MCP(Model Context Protocol)工具调用接入完整的治理链路:每次工具调用先经过 Cedar 策略引擎的 permit/forbid 判定,再生成绑定策略决策的GovernanceReceipt收据,用 Ed25519 私钥签名实现不可抵赖,最后落入可离线校验的审计链。读完本文,你将掌握mcp-receipt-governed集成包的安装、Demo 运行、Cedar 策略编写,以及收据哈希链与签名的底层校验原理,可直接复用到自己的 Agent 工具治理场景。
一、为什么 MCP 工具调用需要"收据"
MCP 把 Agent 的能力暴露为一系列可远程调用的工具(Tool),一旦 Agent 被注入恶意指令或配置失误,DeleteFile、DropTable、SendEmail这类高破坏力工具就可能被无差别触发。仅靠"调用前拦一下"还不够——审计人员需要事后能回答三个问题:这个调用当时是否经过了策略判定?判定结论是什么?有没有被事后篡改?
mcp-receipt-governed示例给出的答案是为每次调用生成一条"治理收据",原文档将其拆解为四个环节:
- Policy-checked:每次 MCP 工具调用先交给 Cedar 策略评估,得到 permit(允许)/ forbid(拒绝)结论;
- Receipted:生成一条
GovernanceReceipt,把策略决策与具体工具调用绑定在一起; - Signed:用 Ed25519 私钥签名,提供不可抵赖(non-repudiation)证据;
- Stored:收据存入审计轨迹,供后续验证。
四个环节共同构成一条"决策 → 记录 → 签名 → 归档"的完整链路,对应 OWASP Agentic Top 10 中关于不当工具使用与不可审计性的治理要求。
二、安装与运行示例
2.1 安装集成包
示例依赖mcp-receipt-governed集成包,该包位于仓库的agent-governance-python/agentmesh-integrations/mcp-receipt-governed/目录。包名在 pyproject.toml 中定义为agentmesh_mcp_receipts,Python 版本要求>=3.11,且基础依赖为空(dependencies = [])——即不使用 Ed25519 签名时仅靠标准库即可运行。
从仓库根目录安装:
# 基础安装(无签名能力,收据不签名) pip install -e agent-governance-python/agentmesh-integrations/mcp-receipt-governed # 带 Ed25519 签名支持(推荐) pip install -e "agent-governance-python/agentmesh-integrations/mcp-receipt-governed[crypto]"[crypto]可选依赖对应 requirements.txt 中的cryptography>=46.0.7(pyproject 中约束为cryptography>=46.0.7,<48.0),用于 Ed25519 密钥生成、签名与验签。
2.2 运行 Demo
安装完成后直接运行:
python examples/mcp-receipt-governed/demo.pyDemo 会模拟两个 Agent(researcher、analyst)发起 7 次工具调用,每次调用都走完整的"策略评估 → 生成收据 → Ed25519 签名 → 入审计库"流程。预期输出如下(摘自原文档):
🛡️ MCP Receipt Governed — Demo Cedar policy loaded from: policies/mcp-tools.cedar Signing: Ed25519 ──────────────────────────────────────────────────────────── Agent Tool Decision Signed Verified ──────────────────────────────────────────────────────────── ✅ researcher ReadData allow yes True ✅ researcher ListFiles allow yes True ✅ researcher SearchData allow yes True ✅ analyst ReadData allow yes True 🚫 analyst DeleteFile deny yes True 🚫 analyst DropTable deny yes True 🚫 researcher SendEmail deny yes True 📊 Audit Summary: Total receipts: 7 Allowed: 4 Denied: 3 Unique agents: 2 Unique tools: 5输出表的每一行对应一条收据:Decision来自 Cedar 评估结果;Signed表示是否带有 Ed25519 签名;Verified是调用verify_receipt(receipt)现场验签的结果。末尾的Audit Summary统计了收据总数、放行/拒绝数量以及涉及的 Agent 与工具去重数。
注意:如果未安装cryptography,Demo 会打印警告并降级为不收签名模式(signing_key = None),此时Signed列为no、Verified为n/a——这正是"无签名能力"的降级表现,生产环境务必安装[crypto]。
三、Cedar 策略:定义工具访问边界
示例的策略文件位于 examples/mcp-receipt-governed/policies/mcp-tools.cedar,其治理思路是:读取向操作显式放行,破坏性操作显式禁止。原文档给出的决策矩阵如下:
| Action | Decision |
|---|---|
| ReadData | ✅ permit |
| ListFiles | ✅ permit |
| SearchData | ✅ permit |
| DeleteFile | 🚫 forbid |
| DropTable | 🚫 forbid |
| SendEmail | 🚫 forbid |
对应到 Cedar 语法,策略文件由六条规则组成:
// Allow agents to read data permit( principal, action == Action::"ReadData", resource ); // Allow agents to list files and directories permit( principal, action == Action::"ListFiles", resource ); // Allow agents to search across datasets permit( principal, action == Action::"SearchData", resource ); // Deny file deletion forbid( principal, action == Action::"DeleteFile", resource ); // Deny database drops forbid( principal, action == Action::"DropTable", resource ); // Deny sending external communications forbid( principal, action == Action::"SendEmail", resource );每条规则都是permit/forbid(principal, action == Action::"X", resource)的三元组结构:principal对应调用工具的 Agent,action对应当前工具名,resource对应工具操作的资源。规则未显式声明的工具行为遵循默认决策(不匹配任何 permit 即视为不授予权限),因此"新增工具默认不开放、需要显式写 permit"是最安全的演进方式。
四、源码级原理:一条收据是如何诞生的
demo.py的核心只有三行:加载策略文本 → 构造McpReceiptAdapter→ 循环调用adapter.govern_tool_call(...)。其底层实现在 adapter.py 与 receipt.py 中。
4.1 McpReceiptAdapter:包装一次工具调用
McpReceiptAdapter 的构造函数接收四个关键参数:
| 参数 | 含义 | 说明 |
|---|---|---|
cedar_policy | Cedar 策略文本 | 可传入字符串形式的策略内容 |
cedar_policy_id | 策略标识 | 如policy:mcp-tools:v1,会写入收据,便于追溯"用的是哪版策略" |
signing_key_hex | Ed25519 私钥种子(32 字节 hex) | 生产环境应从密钥保险库(vault)持久化获取,而非每次随机生成 |
store | 收据存储 | 默认使用内存版ReceiptStore |
每次调用的入口是govern_tool_call(agent_did, tool_name, tool_args, resource),其流程为:
- 用
CedarPolicyEvaluator对工具名做策略评估,得到 allow/deny; - 取当前审计链最后一条收据的
payload_hash()作为parent_receipt_hash; - 构造
GovernanceReceipt,写入工具名、Agent DID、策略 ID、决策、参数哈希、会话 ID、父收据哈希; - 若配置了签名密钥,调用
sign_receipt签名,签名失败直接抛出ReceiptSigningError(fail-closed,宁可拒绝也不留未签名记录); - 收据入
ReceiptStore,返回给调用方。
4.2 CedarPolicyEvaluator:内置评估器与内联回退
CedarPolicyEvaluator 优先尝试从agentmesh.governance.cedar导入CedarEvaluator(mode="builtin")做完整评估;若该依赖不存在,则回退到内联正则解析:先扫描所有forbid(...Action::"X"...)规则(命中即拒绝),再扫描permit(...Action::"X"...)规则(命中即放行),最后检测是否存在permit(principal, action, resource)的兜底全放行规则。这一设计使包在零依赖情况下也能跑通策略逻辑。
4.3 GovernanceReceipt:可验证的决策证据
GovernanceReceipt 是一个 dataclass,核心字段包括:
| 字段 | 含义 |
|---|---|
receipt_id | 收据唯一 ID(UUID4) |
tool_name/agent_did | 工具名与调用方 Agent 的 DID |
cedar_policy_id/cedar_decision | 策略版本标识与决策结论(allow/deny) |
args_hash | 工具参数的 SHA-256 哈希 |
timestamp/session_id | 时间戳与会话 ID |
parent_receipt_hash | 上一条收据的负载哈希(哈希链) |
signature/signer_public_key | Ed25519 签名与签名者公钥 |
其可验证性建立在三层机制上:
1. 确定性序列化(RFC 8785 JCS):canonical_payload()使用sort_keys=True、separators=(",", ":")、ensure_ascii=False生成规范 JSON——ensure_ascii=False正是 RFC 8785 §3.2.2.2 要求的原始 UTF-8 输出,签名字段本身被排除在负载之外(负载是签名覆盖的对象)。
2. SHA-256 负载哈希:payload_hash()对规范 JSON 计算 SHA-256。hash_tool_args()则对工具参数做同样的规范序列化后取哈希,None或空参数视为{}的哈希。参数不落明文、只落哈希,避免敏感参数进入审计日志。
3. Ed25519 签名:sign_receipt()用 32 字节 hex 种子恢复私钥,对规范负载签名;verify_receipt()用收据自带的公钥验签,未签名或签名非法均返回False。Demo 中每行输出的Verified=True正是现场验签的结果。
4.4 哈希链:防插入、防删除
govern_tool_call在构造收据时把上一条收据的payload_hash写入parent_receipt_hash,形成一条单向哈希链。离线校验时用 verify_receipt_chain 逐条检查:
- 第一条收据不得携带
parent_receipt_hash; - 每条收据的
parent_receipt_hash必须等于前一条的payload_hash(断裂即报Hash chain broken); - 不允许出现重复
receipt_id(防重放攻击); - 每条收据的 Ed25519 签名必须有效;
- 若提供
trusted_keys,签名者公钥必须在可信集合内,否则拒绝该收据。
由此,审计人员无需重放整个会话日志,就能检测出工具调用记录被插入或删除。这也与仓库 ADR-0017 Merkle Chain for Audit Tamper Evidence 中"审计防篡改证据"的设计理念一脉相承。
4.5 ReceiptStore:线程安全的内存审计库
ReceiptStore 提供:
add(receipt):重复receipt_id直接抛ValueError(防重放);query(agent_did, tool_name, cedar_decision):按 Agent、工具、决策三条件过滤;export():导出为 JSON 字典列表,供离线验证或持久化;get_stats():产出 Demo 末尾的审计摘要(total/allowed/denied/unique_agents/unique_tools)。
内部用threading.Lock保护,可被多线程 Agent 运行时安全共享。
五、govern_and_execute:策略决策与工具执行的联动
除了"只记录决策",adapter 还提供 govern_and_execute:先govern_tool_call生成收据,仅在决策为 allow 时才调用真实工具函数,若工具执行抛异常则把错误写入收据的error字段并返回。这样"决策记录"与"实际执行"被绑定在同一条收据上,可用于事后核对"是否按决策执行"。
六、离线验证:导出后无需网络的收据核验
配合仓库提供的 scripts/verify_receipts.py 脚本,可以从ReceiptStore.export()导出的 JSON 文件离线验证整条收据链:
# 从集成包目录运行 python scripts/verify_receipts.py receipts.json # 结构化 JSON 输出,便于接入 CI/CD python scripts/verify_receipts.py receipts.json --json脚本会逐条输出:哈希链是否连续(Hash chain contiguous)、负载哈希是否与导出值一致(Payload hash verified)、Ed25519 签名是否有效(Ed25519 signature valid);存在任何错误时进程以非零退出码结束(0=通过,1=链错误,2=加载错误),--json模式可把结果直接交给 CI 流水线判定。这正好落实了原文档 Next Steps 中"导出收据并离线验签"的验证路径。
此外,GovernanceReceipt还提供to_slsa_provenance(),可将每条收据转换为 SLSA v1.0 / in-toto Statement 形式的 provenance 谓词(以args_hash作为 subject digest、以cedar_decision等作为 externalParameters),为把 MCP 工具调用纳入软件供应链证明体系提供了衔接点。
七、在生产环境中使用:参数与注意事项
Demo 中的签名密钥是运行时随机生成的(见 demo.py 的注释),这会导致重启后无法复验历史签名。生产环境应遵循:
- 持久化密钥:将 Ed25519 种子存入密钥保险库(vault),以固定 hex 传入
signing_key_hex,公钥随收据落库; - 策略版本化:每次策略变更都更新
cedar_policy_id(如policy:mcp-tools:v2),收据中保留版本号以便回溯"哪次调用用了哪版策略"; - fail-closed:
sign_receipt失败会抛ReceiptSigningError而非静默降级,审计完整性优先于调用可用性; - 持久化存储:默认
ReceiptStore是内存实现,生产环境应定期export()落盘或接入外部审计事件管道(仓库另见 ADR-0021 CloudEvents Envelope for Mesh Audit 与 ADR-0019 OTEL BatchSpanProcessor Pattern 的扩展思路)。
八、进一步探索
- 与信任代理组合:将
mcp-receipt-governed与agent-governance-python/agentmesh-integrations/mcp-trust-proxy/组合,可在策略判定之外叠加 DID 身份与信任分(trust score)门槛; - 自定义策略:参考 policies/mcp-tools.cedar 的语法,为自己的工具集编写
permit/forbid规则; - 源码与测试:完整实现见 mcp_receipt_governed/adapter.py 与 mcp_receipt_governed/receipt.py,配套测试位于 tests/test_adapter.py 与 tests/test_receipt.py,可用
pytest tests/ -v在集成包目录内运行; - 更多治理示例:仓库中还有 examples/mcp-trust-verified-server/README.md、examples/mcp-receipt-governed 同级的 pipeline-governance 等示例,覆盖信任验证、流水线治理等相邻场景。
最终效果正如 Demo 收尾所展示:每一次 MCP 工具调用都携带一条已签名的治理收据,策略决策、调用事实与密码学签名三者合一,为自主 Agent 的每一次工具操作留下可验证、不可抵赖、不可篡改的审计证据。
License:MIT(见 LICENSE)。
【免费下载链接】agent-governance-toolkitAI Agent Governance Toolkit — Policy enforcement, zero-trust identity, execution sandboxing, and reliability engineering for autonomous AI agents. Covers 10/10 OWASP Agentic Top 10.项目地址: https://gitcode.com/GitHub_Trending/ag/agent-governance-toolkit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考