Python ToolPermissionContext
Python 端的权限系统以 ToolPermissionContext 数据类为核心,它携带两个用于阻止工具的字段:
deny_names 是一个 frozenset,包含应被阻止的确切工具名称。deny_prefixes 是一个字符串前缀的 tuple——名称以列出的前缀开头的任何工具都会被阻止。两个字段都通过 from_iterables 类方法构建,该方法将所有条目转换为小写以确保不区分大小写的匹配。
阻止检查在 blocks() 方法中实现:
该方法首先检查与 deny_names 的精确匹配,然后检查小写化的工具名称是否以 deny_prefixes 中的任何条目开头。这种两阶段检查非常高效:frozenset 查找是 O(1),前缀扫描是 O(n),且前缀列表通常很小。
Rust 权限模型
Rust 层实现了一个更丰富的权限模型,包含三种不同的模式:
Prompt 模式是与 Python 层的关键区别。Rust 权限系统不是做二元的允许/拒绝决策,而是可以暂停执行并询问用户是否允许特定的工具调用。这通过 PermissionPrompter trait 来协调:
PermissionRequest 包含工具名称和完整的输入字符串,因此用户可以做出关于是否允许特定操作的知情决策。PermissionPromptDecision 枚举在拒绝时包含一个可选的 reason,该原因会反馈给模型,使其理解为什么工具使用被拒绝。
PermissionPolicy
PermissionPolicy 结构体将所有内容串联在一起。它定义了 default_mode(应用于没有特定覆盖的任何工具)和 tool_modes 映射(BTreeMap<String, PermissionMode>)用于逐工具覆盖:
策略通过 new(default_mode) 构建,并通过 with_tool_mode(tool_name, mode) 为各个工具定制。mode_for(tool_name) 方法查找工具的特定模式,如果没有覆盖则回退到默认值。
authorize(tool_name, input, prompter) 方法执行完整的授权流程:
- 通过
mode_for查找工具的模式 - 如果是
Allow,立即返回PermissionOutcome::Allow - 如果是
Deny,返回带有静态原因的PermissionOutcome::Deny - 如果是
Prompt,构建PermissionRequest并调用prompter.decide() - 将提示器的决策映射到
PermissionOutcome
PermissionOutcome 枚举镜像了决策类型:Allow 或 Deny{reason}。策略(应用什么模式)和提示(如何询问用户)之间的分离使系统可测试——在测试中,提示器可以是一个始终允许或始终拒绝的 mock。
CLI 权限模式
CLI 通过 args.rs 提供三种预设权限模式,为常见用例提供便捷的默认值:
- ReadOnly——智能体可以读取文件和搜索,但不能写入、执行命令或修改任何内容。这是探索性会话最安全的模式。
- WorkspaceWrite(默认)——智能体可以在工作区内读写文件、执行沙箱化命令并使用大多数工具。这是开发工作的标准模式。
- DangerFullAccess——绕过所有权限检查。智能体可以执行任意命令、写入任何路径并无需提示即可使用所有工具。此模式仅适用于受信任的自动化管道。
默认模式
WorkspaceWrite 作为默认值是有原因的——它提供足够的能力来完成实际开发工作,同时保持沙箱边界完好。ReadOnly 适用于代码审查和探索。DangerFullAccess 仅应在智能体受信任的受控环境中使用。
工具过滤
权限过滤在工具到达智能体的上下文窗口之前进行。get_tools 函数接受 permission_context 参数并调用 filter_tools_by_permission_context 从列表中移除任何被阻止的工具。这确保被拒绝的工具永远不会出现在系统提示中——智能体根本不知道它们的存在。
这种设计比事后强制执行更安全。如果被阻止的工具出现在提示中但在执行时被拒绝,智能体会浪费回合尝试使用它,并可能试图绕过限制。通过在提示级别过滤,智能体的决策被限制在它实际可以使用的工具范围内。
简单模式
简单模式是最严格的工具配置。启用后,工具池被缩减为恰好三个工具:
BashTool——Shell 命令执行FileReadTool——文件读取FileEditTool——文件编辑
所有其他工具——Web 访问、子智能体、搜索、笔记本、任务管理——都被移除。这为完整的 19 个工具套件过于庞大的受限环境提供了最小的、可预测的攻击面。
运行时权限推断
运行时层通过 _infer_permission_denials 添加最终的权限检查。此函数根据活动的 CLI 权限模式来控制类似 bash 的工具(任何可以执行任意命令的工具)。即使工具通过了 ToolPermissionContext 过滤器,运行时推断层仍然可以基于更广泛的会话权限来阻止它。
这种分层方法——Python 拒绝列表过滤、Rust 策略引擎、CLI 模式预设和运行时推断——创建了纵深防御。每一层都能捕获其他层可能遗漏的情况,确保 Claw Code 权限系统对配置错误和边缘情况具有鲁棒性。
安全模型总结
Claw Code 权限系统通过四层提供逐工具粒度:Python 拒绝列表(快速过滤)、Rust 权限策略(带提示的细粒度控制)、CLI 模式预设(便捷默认值)和运行时推断(最终控制)。在任何层被阻止的工具永远不会到达智能体。