news 2026/9/10 1:31:04

基于 Cedar 策略的 Claude Code 工具调用治理:protect-mcp policy-enforcer 实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于 Cedar 策略的 Claude Code 工具调用治理:protect-mcp policy-enforcer 实战指南

基于 Cedar 策略的 Claude Code 工具调用治理:protect-mcp policy-enforcer 实战指南

【免费下载链接】agentsMulti-harness agentic plugin marketplace for Claude Code, Codex, Cursor, OpenCode, GitHub Copilot, and Google Antigravity项目地址: https://gitcode.com/GitHub_Trending/agents24/agents

本文以 plugins/protect-mcp/agents/policy-enforcer.md 为绝对主体,深入讲解如何在 Claude Code 项目中以 AWS 开源授权引擎 Cedar 编写、审计并验证 AI Agent 工具调用的访问控制策略。你将掌握 permit/forbid 的语义差异、context 属性的实战用法、三档风险画像的策略模板(只读研究项目 / 常规开发项目 / 生产部署项目),以及结合 protect-mcp 插件(PreToolUse 钩子 + Ed25519 签名回执)形成"策略执行 + 密码学审计"完整闭环的可落地方案。

一、Policy Enforcer 在 protect-mcp 中的定位

在 protect-mcp 插件体系中,policy-enforcer 是一个面向 Claude Code 的 Cedar 策略编写与审计 Agent。它与同目录下的 receipt-verifier(负责 Ed25519 签名回执与哈希链的离线验证)构成"先授权、后留痕"的两段式治理链路:

  • policy-enforcer(本文主角):负责产出声明式、可形式化验证的 Cedar 策略,回答"这个 Agent 在项目里能做什么、不能做什么";
  • receipt-verifier:负责验证每一次决策产生的签名回执,回答"当时到底发生了什么、有没有被篡改"。

protect-mcp 的核心机制是:每次工具调用前,PreToolUse 钩子调用 Cedar 求值器对调用做授权判定;每次工具调用后,PostToolUse 钩子为本次决策生成 Ed25519 签名回执,回执按parent_receipt_id形成哈希链,可离线验证。

二、Cedar 授权模型的核心知识

policy-enforcer 的"知识底座"是对 Cedar(AWS 开源授权引擎)的深入理解,这四块构成任何一条好策略的理论前提:

1. 语法核心:permit / forbid + 四元组

每条规则围绕四个维度展开:principal(主体,即 Agent)、action(动作,即工具)、resource(资源,即目标对象)、context(上下文,即求值时可用的动态属性)。

permit ( principal, action == Action::"Bash", resource ) when { context.command_pattern in ["git", "npm", "ls"] };

2. 类型系统

Cedar 具备实体类型(entity types)、记录(records)、集合(sets)与扩展(extensions)。策略中通过Action::"..."Tool::"..."等命名空间引用实体,通过context.xxx访问上下文属性。

3. 求值语义(最关键的一条)

  • deny 是权威的:只要有任何一条forbid规则匹配,无论存在多少条匹配的permit,最终结果都是拒绝;
  • permit 必须全部匹配:一个动作只有在某条 permit 规则的条件下匹配,且没有任何 forbid 规则拦截时,才被允许。

这意味着策略编写应以"最小权限"为默认值,显式放行,显式拦截高危操作。

4. Schema 定义与校验

如果项目配有 Cedar schema,策略应通过cedar validate做类型检查,确保context属性、实体引用与 schema 声明一致,再部署生效。

三、Claude Code 工具面与 protect-mcp 的集成方式

policy-enforcer 需要同时理解三层内容:工具本身、工具入参形状、以及求值期可用的上下文。

Claude Code 工具面

核心工具包括:BashEditWriteReadGlobGrepWebFetchWebSearch。每条工具的输入形状各不相同——命令字符串(Bash)、文件路径(Edit/Write/Read)、URL(WebFetch)、通配模式(Glob/Grep)。

求值期上下文

Cedar 策略通过context检查工具输入:Bashcontext.command_pattern匹配命令族(git、npm、docker、rm 等);Edit/Writecontext.path_starts_with限定文件系统范围。

protect-mcp 的运行时行为

从 hooks/hooks.json 可以看到插件的真实钩子配置:

{ "hooks": { "PreToolUse": [ { "matcher": ".*", "hooks": [ { "type": "command", "command": "npx protect-mcp@0.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-mcp@0.7.4 sign --tool \"$TOOL_NAME\" --input \"$TOOL_INPUT\" --output \"$TOOL_OUTPUT\" --receipts \"${PROTECT_MCP_RECEIPTS:-./receipts/}\" --key \"${PROTECT_MCP_KEY:-./protect-mcp.key}\"" } ] } ] } }

三个关键机制:

  • PreToolUse 钩子在每次工具调用前触发,对$TOOL_NAME$TOOL_INPUT执行 Cedar 求值。matcher: ".*"表示对所有工具生效;
  • Cedardeny使钩子以退出码 2 结束,Claude Code 据此整体拦截该工具调用;permit则放行工具执行;
  • PostToolUse 钩子为每次决策生成回执,包含工具名、输入哈希、输出哈希、决策结果、策略 ID 与策略摘要、父回执 ID(链式链接)、公钥与签名,写入./receipts/<timestamp>.json(路径可通过PROTECT_MCP_RECEIPTS环境变量覆盖,签名密钥通过PROTECT_MCP_KEY覆盖,策略文件通过PROTECT_MCP_POLICY覆盖,默认均为项目根目录下./开头的相对路径)。

四、策略编写工作流:六步法

policy-enforcer 在收到"编写一条 Cedar 策略"的请求时,遵循以下六步方法论,这也是任何项目落地策略时应复制的流程:

  1. 先问清项目的风险画像。这是只读即可安全的研究项目?还是命令会改动生产的部署流水线?还是存在审计要求的受监管环境(金融、医疗、受监管研究)?合适的策略完全取决于上下文;
  2. 从安全默认值出发。优先 allow-list(白名单)而非 deny-list(黑名单);先给出完成任务所需的最少工具集合,随着需求被证明再逐步增加;
  3. 善用 context 属性。策略通过context检视工具输入——Bashcontext.command_pattern匹配命令族,Edit/Writecontext.path_starts_with限定文件系统范围;
  4. 为高风险操作写配对规则。对危险动作同时写一条带具体条件的permit和一条覆盖明显坏例的forbid——因为 Cedar 的forbid一旦匹配即为权威;
  5. 逐条解释每条规则。Cedar 策略是安全关键资产,每条规则都需要注释说明其意图与所对抗的威胁模型;
  6. 对照 schema 校验。若项目有 Cedar schema,确保策略通过类型检查,部署前运行cedar validate

五、三档风险画像的完整策略模板

policy-enforcer 提供了三种场景的完整示例,下面全量继承并逐条批注,可直接复制改造。

5.1 研究项目(只读、安全)

// Allow all read-oriented tools permit ( principal, action in [Action::"Read", Action::"Glob", Action::"Grep"], resource ); // Web searches are fine, no fetch permit ( principal, action == Action::"WebSearch", resource ); // No writes, no shell forbid ( principal, action in [Action::"Write", Action::"Edit", Action::"Bash", Action::"WebFetch"], resource );

设计要点:读类工具(Read/Glob/Grep)整体放行;WebSearch单独放行但WebFetch被禁用(搜索可以、抓取不行);末尾一条兜底forbid封死写入与 Shell,与文档开头"研究项目只读安全"的风险画像一致。

5.2 开发项目(限定写入、禁止破坏性命令)

// Reads are free permit ( principal, action in [Action::"Read", Action::"Glob", Action::"Grep"], resource ); // Writes only within the project directory permit ( principal, action in [Action::"Write", Action::"Edit"], resource ) when { context.path_starts_with == "./" }; // Safe shell commands only permit ( principal, action == Action::"Bash", resource ) when { context.command_pattern in [ "git", "npm", "pnpm", "yarn", "ls", "cat", "pwd", "echo", "test", "node", "python", "make" ] }; // Never destructive forbid ( principal, action == Action::"Bash", resource ) when { context.command_pattern in ["rm -rf", "dd", "mkfs", "shred"] };

设计要点:写入被when { context.path_starts_with == "./" }限定在项目目录内;Shell 采用命令族白名单(git/npm/pnpm/yarn/ls/cat/pwd/echo/test/node/python/make);对rm -rfddmkfsshred等破坏性命令显式forbid。注意这里"配对规则"的体现:Bash既被 permit 白名单约束,又被 forbid 黑名单兜底,双重保险。

5.3 生产部署(严格、逐动作显式放行)

// Reads require evidenced trust tier permit ( principal, action in [Action::"Read", Action::"Grep"], resource ) when { context.trust_tier == "evidenced" }; // Writes only to approved paths permit ( principal, action == Action::"Write", resource ) when { context.trust_tier == "institutional" && context.path_starts_with in ["./deployments/", "./config/"] }; // Shell only for explicit deployment commands permit ( principal, action == Action::"Bash", resource ) when { context.trust_tier == "institutional" && context.command_pattern in ["kubectl apply", "terraform plan", "terraform apply"] }; // Block everything else forbid ( principal, action, resource ) unless { context.trust_tier in ["evidenced", "institutional"] };

设计要点:引入context.trust_tier信任层级(evidenced/institutional)作为放行前提——读取需evidenced,写入仅限./deployments/./config/且需institutional,Shell 仅放行kubectl applyterraform planterraform apply等显式部署命令;最后一条forbid ... unless是"默认拒绝"的兜底闸门,凡 trust_tier 不在此列者一律拦截。这是三类模板中约束最严的一种,适合受监管环境。

六、从文档到仓库源码:策略的真实求值形状

文档中的示例为了可读性采用Action::"Read"这种抽象写法。而仓库测试夹具揭示了 protect-mcp(≥ 0.7.0)实际求值的实体形状,见 test/fixtures/test-policy.cedar 的头部注释:

protect-mcp >= 0.7.0 实际求值的形状为:principalAgent::"<id>",actionAction::"MCP::Tool::call",resourceTool::"<toolName>",工具输入位于context.input

对应的测试策略片段:

// Allow read-oriented tools. permit ( principal, action == Action::"MCP::Tool::call", resource ) when { resource == Tool::"Read" || resource == Tool::"Glob" || resource == Tool::"Grep" || resource == Tool::"WebSearch" }; // Allow Bash only for safe command prefixes. 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*") };

从源码结构可以推断两条重要实现事实:

  • 动作统一为Action::"MCP::Tool::call",资源才是具体的工具名Tool::"Bash"Tool::"Read"等),这与文档示例的"动作即工具"抽象一一对应;
  • 上下文携带原始工具输入context.input.command是 Bash 的命令字符串,策略用like前缀匹配做安全命令白名单,用*rm -rf*dd **mkfs**shred*等模式做破坏性命令拦截。

测试夹具同时给出了策略求值的端到端证据:

  • pretool-allow-read.json:Read读取./README.md,期望permit(退出码 0);
  • pretool-allow-bash-safe.json:Bash执行git status,期望permit(退出码 0);
  • pretool-deny-bash-destructive.json:Bash执行rm -rf /,期望forbid(退出码 2);
  • pretool-deny-write.json:Write写入./secrets.env,期望forbid(退出码 2)。

七、审计既有策略:五步检查清单

policy-enforcer 在审核用户已写好的策略时,执行如下五步检查,这也是团队代码评审时可以套用的模板:

  1. 检查危险操作是否缺少forbid规则——已知高危动作(递归删除、磁盘格式化、密码擦除等)必须有显式拦截;
  2. 确认 context 属性已对照 schema 校验——context.command_patterncontext.path_starts_withcontext.trust_tier等字段必须在 schema 中有声明,否则求值行为不可预期;
  3. 排查过宽的permit规则——没有when子句的 permit 是典型反模式,等于无条件放行;
  4. 检查逻辑缺口——例如Edit被允许但Write被禁止,会导致绕过写入限制的路径;
  5. 验证策略通过cedar validate——部署前的最后一道类型与语法闸门。

八、策略执行的完整验证闭环

策略生效后的正确性验证,在仓库中由 test/README.md 描述的 8 项端到端测试兜底,覆盖"求值 → 签名 → 验证"全链路:

#场景期望退出码
1PreToolUse作用于Read0(permit)
2PreToolUse作用于Bash git status0(permit)
3PreToolUse作用于Bash rm -rf /2(forbid)
4PreToolUse作用于Write2(forbid)
5PostToolUse签名生成回执文件0(成功)
6生成的回执符合 schema0(有效)
7@veritasacta/verify接受该回执0(有效)
8被篡改的回执被拒绝1(tampered)

第 8 项是关键的回归防线:翻转签名回执中的decision字段必须使 Ed25519 签名失效,验证器必须返回 1 而非 0。而 expected/receipt-schema.json 定义了回执的 JSON Schema,每个回执必须包含receipt_idreceipt_versionissuer_idevent_timetool_nameinput_hashdecisionpolicy_idpolicy_digestparent_receipt_idpublic_keysignature等字段。

离线验证命令(由@veritasacta/verify提供):

# 验证单条回执:退出码 0=有效,1=被篡改,2=格式错误 npx @veritasacta/verify receipts/2026-04-15T10-30-00Z.json # 验证整条哈希链 npx @veritasacta/verify receipts/*.json

在 Claude Code 内还可使用插件自带的斜杠命令:/verify-receipt <path>验证单条回执,/audit-chain [--last N]回溯验证./receipts/中的回执链。完整安装与配置流程(claude plugin install wshobson/agents/protect-mcpnpx protect-mcp@latest serve --enforce启动本地签名服务、.claude/settings.json挂载钩子)见 skills/protect-mcp-setup/SKILL.md。

九、总结:声明式治理 + 密码学留痕

policy-enforcer 的价值在于把"Agent 能做什么"从隐式的模型行为,转变为显式、声明式、可形式化验证的 Cedar 策略,并与 protect-mcp 的 Ed25519 签名回执体系结合,形成"事前授权、事后留痕、随时可证"的完整闭环:

  • 事前:PreToolUse 钩子按 Cedar 策略逐次求值,deny即拦截(退出码 2);
  • 事后:PostToolUse 钩子为每次决策签发 Ed25519 回执(RFC 8032 签名 + RFC 8785 JCS 规范化),经parent_receipt_id哈希链接续成链;
  • 随时:任何第三方可用@veritasacta/verify离线验证单条回执或整条链,无需信任运营商、无需联网。

编写策略时,记住 policy-enforcer 的核心纪律:先问风险画像、从白名单默认值起步、用 context 属性收窄作用域、为高危操作写 permit/forbid 配对规则、逐条注释威胁模型、部署前过cedar validate。这样产出的策略,既是开发期的安全护栏,也是合规审计期可直接呈堂的正式证据。

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 1:30:49

WPF自学手册:从源代码到MVVM的完整学习路线

简介&#xff1a;这份源代码是《葵花宝典 WPF自学手册》随书光盘的完整内容&#xff0c;适合刚开始接触WPF或希望系统梳理桌面开发知识的开发者。包内共有1713个文件&#xff0c;包含655个C#源码、385个XAML界面布局、109个工程文件和105个解决方案&#xff0c;并附带可直接运行…

作者头像 李华
网站建设 2026/9/10 1:30:42

WPF中流畅显示OpenCV图像:高级显示控件2.0实现解析

做机器视觉和工控上位机的朋友&#xff0c;一定对这个问题不陌生&#xff1a;OpenCV把图像处理好了&#xff0c;怎么流畅地显示到WPF界面里&#xff1f;直接用PictureBox塞进WindowsFormsHost&#xff0c;缩放交互又难受&#xff0c;WPF的透明和叠加层还会被“吃掉”&#xff1…

作者头像 李华
网站建设 2026/9/10 1:30:25

基于背对背MMC的电力质量调节系统Simulink仿真建模与控制策略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 1:28:57

RTOS中的C++实践:特性取舍与性能优化指南

1. 实时系统与C的关系&#xff0c;远不是“能用就行”这么简单 很多人一听到“实时操作系统”&#xff0c;第一反应就是“在嵌入式板子上跑个RTOS&#xff0c;定时采集传感器数据、控制电机、刷屏幕”。一旦把C加进来&#xff0c;就有人开始皱眉&#xff1a;C那么重、那么抽象&…

作者头像 李华
网站建设 2026/9/10 1:26:39

电商数据分析工具选型:从BI到数仓与实时流处理的最佳实践

做电商数据分析的朋友&#xff0c;最近被问得最多的一个问题&#xff0c;往往不是某个指标怎么算&#xff0c;而是“我们到底该上什么数据分析工具”。有人刚搭完数据团队&#xff0c;有人已经在几个 BI 里面横跳&#xff0c;还有人花了不少预算把大数据全家桶买齐了&#xff0…

作者头像 李华