1. 权限系统概述
权限系统是Claude Code的重要组成部分,确保工具使用的安全性,防止恶意或危险操作。通过多层次的权限检查和安全机制,Claude Code实现了既安全又灵活的工具使用环境。
核心价值
- 安全保护:防止恶意或危险操作
- 用户控制:让用户掌握工具使用的决定权
- 灵活性:支持不同场景的权限配置
- 可审计性:记录权限决策,便于审计和追溯
- 最小权限:遵循最小权限原则,只授予必要的权限
系统架构
TOOL CALL REQUEST
│
▼
┌─ validateInput() ──────────────────────────────────┐
│ reject invalid inputs before any permission check │
└────────────────────┬───────────────────────────────┘
│
▼
┌─ PreToolUse Hooks ─────────────────────────────────┐
│ user-defined shell commands (settings.json hooks) │
│ can: approve, deny, or modify input │
└────────────────────┬───────────────────────────────┘
│
▼
┌─ Permission Rules ─────────────────────────────────┐
│ alwaysAllowRules: match tool name/pattern → auto │
│ alwaysDenyRules: match tool name/pattern → deny │
│ alwaysAskRules: match tool name/pattern → ask │
│ Sources: settings, CLI args, session decisions │
└────────────────────┬───────────────────────────────┘
│
no rule match?
│
▼
┌─ Interactive Prompt ───────────────────────────────┐
│ User sees tool name + input │
│ Options: Allow Once / Allow Always / Deny │
└────────────────────┬───────────────────────────────┘
│
▼
┌─ checkPermissions() ───────────────────────────────┐
│ Tool-specific logic (e.g. path sandboxing) │
└────────────────────┬───────────────────────────────┘
│
APPROVED → tool.call()
2. 权限检查流程
权限检查是一个多层次的过程,确保工具使用的安全性和合规性。
检查步骤
- 输入验证:在权限检查之前,先验证输入参数的有效性
- 预工具使用钩子:执行用户定义的shell命令,可用于审批、拒绝或修改输入
- 权限规则检查:检查权限规则,确定是否自动允许、拒绝或询问
- 交互式提示:如果没有匹配的规则,显示交互式提示,让用户决定
- 工具特定权限检查:调用工具的
checkPermissions方法,进行工具特定的权限检查
权限决策来源
- 用户配置:在settings.json中定义的权限规则
- 命令行参数:通过CLI参数指定的权限设置
- 会话决策:用户在会话中做出的权限决策
- 工具默认设置:工具自身的权限设置
3. 权限规则系统
权限规则系统是权限系统的核心,定义了工具使用的权限策略。
规则类型
- alwaysAllowRules:匹配工具名称/模式 → 自动允许
- alwaysDenyRules:匹配工具名称/模式 → 自动拒绝
- alwaysAskRules:匹配工具名称/模式 → 始终询问
规则格式
{
"toolPermissionContext": {
"alwaysAllowRules": [
"FileReadTool",
"GrepTool"
],
"alwaysDenyRules": [
"BashTool"
],
"alwaysAskRules": [
"FileWriteTool",
"FileEditTool"
]
}
}
规则匹配
- 精确匹配:完全匹配工具名称
- 模式匹配:使用通配符匹配工具名称
- 优先级:规则按优先级顺序匹配,先匹配到的规则生效
4. 安全边界与保护措施
Claude Code实现了多种安全边界和保护措施,确保系统的安全性。
路径沙箱
- 工作目录限制:限制文件操作的路径范围,默认只允许访问当前工作目录及其子目录
- 路径验证:验证文件路径,防止路径遍历攻击
- 符号链接处理:安全处理符号链接,防止越权访问
命令限制
- 危险命令检测:检测和限制危险的命令执行
- 命令白名单:可配置允许执行的命令白名单
- 命令参数检查:检查命令参数,防止注入攻击
网络限制
- 网络请求验证:验证网络请求的目标和参数
- URL白名单:可配置允许访问的URL白名单
- 请求大小限制:限制网络请求的大小
资源限制
- CPU限制:限制工具使用的CPU资源
- 内存限制:限制工具使用的内存资源
- 执行时间限制:限制工具的执行时间
5. 交互式权限提示
交互式权限提示是权限系统的重要组成部分,让用户能够直接参与权限决策。
提示流程
- 显示工具信息:显示工具名称和输入参数
- 提供选项:提供Allow Once、Allow Always、Deny等选项
- 记录决策:记录用户的权限决策,用于后续的权限规则
- 执行操作:根据用户的决策执行相应的操作
提示样式
⚠️ Tool Permission Required
Tool: BashTool
Input: {"command": "rm -rf /", "cwd": "/tmp"}
This tool could make changes to your system.
[1] Allow Once
[2] Allow Always
[3] Deny
Enter your choice:
6. 权限管理与配置
权限管理与配置是权限系统的重要组成部分,允许用户和管理员配置权限策略。
配置文件
权限配置主要通过settings.json文件进行管理:
{
"toolPermissionContext": {
"mode": "default",
"additionalWorkingDirectories": [
"/path/to/allowed/directory"
],
"alwaysAllowRules": [],
"alwaysDenyRules": [],
"alwaysAskRules": [],
"isBypassPermissionsModeAvailable": false
}
}
命令行参数
通过命令行参数可以临时覆盖权限设置:
--always-allow-tools:始终允许指定的工具--always-deny-tools:始终拒绝指定的工具--always-ask-tools:始终询问指定的工具--bypass-permissions:绕过权限检查(需要特殊权限)
权限模式
- default:默认模式,遵循权限规则和交互式提示
- plan:规划模式,只允许只读工具,不允许修改操作
- auto:自动模式,根据规则自动决策,不显示交互式提示
7. 安全最佳实践
对于用户
- 最小权限原则:只授予必要的权限
- 谨慎使用bypass-permissions:避免使用绕过权限检查的模式
- 定期审查权限规则:定期审查和更新权限规则
- 使用计划模式:在不熟悉的环境中使用计划模式
对于开发者
- 实现权限检查:在自定义工具中实现适当的权限检查
- 遵循安全边界:遵守系统的安全边界和限制
- 提供清晰的权限提示:为工具提供清晰的权限提示和说明
- 测试权限场景:测试各种权限场景,确保安全性
8. 代码分析
核心文件
src/utils/permissions/:权限规则引擎和权限检查逻辑src/hooks/useCanUseTool.tsx:权限检查钩子src/components/permissions/:权限相关的UI组件src/state/AppState.tsx:权限状态管理
关键代码片段
权限检查
async function canUseTool(
tool: Tool,
input: unknown,
context: ToolContext
): Promise<PermissionResult> {
// 1. 输入验证
const validatedInput = await tool.validateInput(input);
// 2. 预工具使用钩子
const hookResult = await runPreToolUseHooks(tool, validatedInput, context);
if (hookResult.denied) {
return { allowed: false, reason: hookResult.reason };
}
// 3. 权限规则检查
const ruleResult = checkPermissionRules(tool.name, validatedInput, context);
if (ruleResult !== null) {
return ruleResult;
}
// 4. 交互式提示
if (context.permissionMode !== 'auto') {
const userResult = await promptUserForPermission(tool, validatedInput, context);
if (userResult.denied) {
return { allowed: false, reason: 'User denied permission' };
}
// 记录用户决策
recordPermissionDecision(tool.name, userResult.alwaysAllow);
}
// 5. 工具特定权限检查
return await tool.checkPermissions(validatedInput, context);
}
权限规则检查
function checkPermissionRules(
toolName: string,
input: unknown,
context: ToolContext
): PermissionResult | null {
const { alwaysAllowRules, alwaysDenyRules, alwaysAskRules } = context.permissions;
// 检查始终拒绝规则
for (const rule of alwaysDenyRules) {
if (matchesPattern(toolName, rule)) {
return { allowed: false, reason: `Matched alwaysDenyRule: ${rule}` };
}
}
// 检查始终允许规则
for (const rule of alwaysAllowRules) {
if (matchesPattern(toolName, rule)) {
return { allowed: true, reason: `Matched alwaysAllowRule: ${rule}` };
}
}
// 检查始终询问规则
for (const rule of alwaysAskRules) {
if (matchesPattern(toolName, rule)) {
return { allowed: false, reason: `Matched alwaysAskRule: ${rule}`, needsPrompt: true };
}
}
return null; // 没有匹配的规则
}
9. 小结
权限系统与安全机制是Claude Code的重要组成部分,确保了工具使用的安全性和合规性。通过多层次的权限检查、灵活的权限规则和交互式提示,Claude Code实现了既安全又用户友好的权限系统。
理解权限系统的设计与实现,对于使用和扩展Claude Code都具有重要意义。下一节我们将深入探讨子代理与多代理架构的实现。