SDK 权限

Claude Agent SDK 提供强大的权限控制功能,允许您管理 Claude 在应用程序中如何使用工具。 本指南涵盖如何使用 canUseTool 回调、钩子和 settings.json 权限规则来实现权限系统。有关完整的 API 文档,请参阅 TypeScript SDK 参考

概述

Claude Agent SDK 提供四种互补的方式来控制工具使用:
  1. 权限模式 - 影响所有工具的全局权限行为设置
  2. canUseTool 回调 - 用于其他规则未涵盖情况的运行时权限处理程序
  3. 钩子 - 通过自定义逻辑对每个工具执行进行细粒度控制
  4. 权限规则 (settings.json) - 具有集成 bash 命令解析的声明式允许/拒绝规则
每种方法的用例:
  • 权限模式 - 设置整体权限行为(规划、自动接受编辑、绕过检查)
  • canUseTool - 对未涵盖情况的动态批准,提示用户获取权限
  • 钩子 - 对所有工具执行的程序化控制
  • 权限规则 - 具有智能 bash 命令解析的静态策略

权限流程图

处理顺序: PreToolUse 钩子 → 询问规则 → 拒绝规则 → 权限模式检查 → 允许规则 → canUseTool 回调 → PostToolUse 钩子

权限模式

权限模式提供对 Claude 如何使用工具的全局控制。您可以在调用 query() 时设置权限模式,或在流式会话期间动态更改它。

可用模式

SDK 支持四种权限模式,每种都有不同的行为:
模式描述工具行为
default标准权限行为应用正常权限检查
plan规划模式 - 无执行Claude 只能使用只读工具;在执行前呈现计划 (SDK 中当前不支持)
acceptEdits自动接受文件编辑文件编辑和文件系统操作自动批准
bypassPermissions绕过所有权限检查所有工具无需权限提示即可运行(谨慎使用)

设置权限模式

您可以通过两种方式设置权限模式:

1. 初始配置

创建查询时设置模式:
import { query } from "@anthropic-ai/claude-agent-sdk";

const result = await query({
  prompt: "帮我重构这段代码",
  options: {
    permissionMode: 'default'  // 标准权限模式
  }
});

2. 动态模式更改(仅限流式)

在流式会话期间更改模式:
import { query } from "@anthropic-ai/claude-agent-sdk";

// 为流式输入创建异步生成器
async function* streamInput() {
  yield { 
    type: 'user',
    message: { 
      role: 'user', 
      content: "让我们从默认权限开始" 
    }
  };
  
  // 稍后在对话中...
  yield {
    type: 'user',
    message: {
      role: 'user',
      content: "现在让我们加快开发速度"
    }
  };
}

const q = query({
  prompt: streamInput(),
  options: {
    permissionMode: 'default'  // 以默认模式开始
  }
});

// 动态更改模式
await q.setPermissionMode('acceptEdits');

// 处理消息
for await (const message of q) {
  console.log(message);
}

模式特定行为

接受编辑模式 (acceptEdits)

在接受编辑模式下:
  • 所有文件编辑都自动批准
  • 文件系统操作(mkdir、touch、rm 等)自动批准
  • 其他工具仍需要正常权限
  • 当您信任 Claude 的编辑时加快开发速度
  • 适用于快速原型制作和迭代
自动批准的操作:
  • 文件编辑(Edit、MultiEdit、Write 工具)
  • Bash 文件系统命令(mkdir、touch、rm、mv、cp)
  • 文件创建和删除

绕过权限模式 (bypassPermissions)

在绕过权限模式下:
  • 所有工具使用都自动批准
  • 不出现权限提示
  • 钩子仍然执行(仍可阻止操作)
  • 极其谨慎使用 - Claude 拥有完整系统访问权限
  • 仅建议在受控环境中使用

权限流程中的模式优先级

权限模式在权限流程的特定点进行评估:
  1. 钩子首先执行 - 可以覆盖任何模式
  2. 检查拒绝规则 - 无论模式如何都阻止工具
  3. bypassPermissions 模式 - 如果激活,允许所有剩余工具
  4. 检查允许规则
  5. 其他模式 影响特定工具行为
  6. canUseTool 回调 - 处理剩余情况
这意味着:
  • 钩子始终可以阻止工具使用,即使在 bypassPermissions 模式下
  • 显式拒绝规则覆盖所有权限模式
  • bypassPermissions 模式覆盖允许规则和 canUseTool

最佳实践

  1. 使用默认模式 进行带有正常权限检查的受控执行
  2. 使用 acceptEdits 模式 处理隔离文件或目录时
  3. 避免在生产环境或敏感数据系统上使用 bypassPermissions
  4. 将模式与钩子结合 进行细粒度控制
  5. 根据任务进度和信心动态切换模式
模式进展示例:
// 以默认模式开始进行受控执行
permissionMode: 'default'

// 切换到 acceptEdits 进行快速迭代
await q.setPermissionMode('acceptEdits')

canUseTool

canUseTool 回调作为选项在调用 query 函数时传递。它接收工具名称和输入参数,必须返回决定 - 允许或拒绝。 当 Claude Code 会向用户显示权限提示时,canUseTool 会触发,例如钩子和权限规则不涵盖它且不在自动接受模式下。 以下是显示如何实现交互式工具批准的完整示例:
import { query } from "@anthropic-ai/claude-agent-sdk";

async function promptForToolApproval(toolName: string, input: any) {
  console.log("\n🔧 工具请求:");
  console.log(`   工具: ${toolName}`);
  
  // 显示工具参数
  if (input && Object.keys(input).length > 0) {
    console.log("   参数:");
    for (const [key, value] of Object.entries(input)) {
      let displayValue = value;
      if (typeof value === 'string' && value.length > 100) {
        displayValue = value.substring(0, 100) + "...";
      } else if (typeof value === 'object') {
        displayValue = JSON.stringify(value, null, 2);
      }
      console.log(`     ${key}: ${displayValue}`);
    }
  }
  
  // 获取用户批准(用您的 UI 逻辑替换)
  const approved = await getUserApproval();
  
  if (approved) {
    console.log("   ✅ 已批准\n");
    return {
      behavior: "allow",
      updatedInput: input
    };
  } else {
    console.log("   ❌ 已拒绝\n");
    return {
      behavior: "deny",
      message: "用户拒绝了此工具的权限"
    };
  }
}

// 使用权限回调
const result = await query({
  prompt: "帮我分析这个代码库",
  options: {
    canUseTool: async (toolName, input) => {
      return promptForToolApproval(toolName, input);
    }
  }
});

使用钩子进行工具控制

钩子在各个阶段提供对工具执行的程序化控制。钩子对每个工具使用都会被调用,为您提供对权限管道的完全控制。

钩子实现

import { query } from "@anthropic-ai/claude-agent-sdk";

const result = await query({
  prompt: "帮我重构这段代码",
  options: {
    hooks: {
      PreToolUse: [{
        hooks: [async (input, toolUseId, { signal }) => {
          console.log(`工具请求: ${input.tool_name}`);
          
          // 自己解析和验证工具输入
          if (input.tool_name === "Bash") {
            const command = input.tool_input.command;
            if (command.startsWith("rm -rf")) {
              return {
                decision: "block",
                reason: "危险命令已阻止"
              };
            }
          }
          
          return { continue: true };
        }]
      }],
      PostToolUse: [{
        hooks: [async (input, toolUseId, { signal }) => {
          console.log(`工具完成: ${input.tool_name}`);
          // 记录或审计工具结果
          return { continue: true };
        }]
      }]
    }
  }
});

与 canUseTool 的主要区别

  • 范围:钩子对所有工具使用都会被调用;canUseTool 处理权限规则未涵盖的情况
  • 控制:钩子需要您自己解析和验证输入
  • 事件:钩子支持多个事件(PreToolUse、PostToolUse 等)用于不同阶段

使用权限规则 (settings.json)

settings.json 中的权限规则提供具有内置 bash 命令解析的声明式控制。这些规则在调用 canUseTool 之前进行评估。有关设置配置的更多详细信息,请参阅 Claude Code 设置文档

配置结构

{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test:*)",
      "Read(~/.zshrc)"
    ],
    "deny": [
      "Bash(curl:*)",
      "Read(./.env)",
      "Read(./secrets/**)",
      "WebFetch"
    ],
    "ask": [
      "Bash(git push:*)",
      "Write(./production/**)"
    ]
  }
}

规则语法

权限规则遵循模式:ToolName(pattern)
  • Bash 规则:使用前缀匹配(非正则表达式)。示例:Bash(npm:*) 匹配任何以 “npm” 开头的命令
  • 文件规则:支持 glob 模式。示例:Read(./src/**/*.ts) 匹配 src 中的 TypeScript 文件
  • 仅工具规则:省略括号来控制整个工具。示例:WebFetch 阻止所有网络获取
有关配置权限的更多信息,请参阅 配置权限

在 SDK 中使用

虽然规则在 SDK 中还不能以编程方式设置,但它们将从 SDK 加载路径中的 settings.json 文件中读取。

权限评估顺序

  1. 首先检查拒绝规则 - 如果匹配,工具使用被阻止
  2. 接下来检查允许规则 - 如果匹配,工具使用被允许
  3. 检查询问规则 - 如果匹配,提示用户
  4. 对任何剩余情况调用 canUseTool 回调

Bash 命令解析

SDK 包含一个集成的 bash 解析器,理解命令结构:
  • 处理管道、重定向和命令替换
  • 识别危险模式如 rm -rfcurl | sh
  • 支持通配符和前缀匹配
bash 模式工作原理示例:
  • Bash(git:*) - 匹配任何 git 命令
  • Bash(npm run test) - 匹配确切命令
  • Bash(npm run test:*) - 匹配以 npm run test 开头的 Bash 命令,如 npm run test anyFile.test.ts
有关配置权限的更多信息,请参阅 配置权限

最佳实践

  1. 从默认模式开始 进行标准权限检查
  2. 使用权限规则 进行静态策略,特别是 bash 命令(参见 权限设置
  3. 使用钩子 记录、审计或转换所有工具使用(参见 钩子类型
  4. 使用 canUseTool 对未涵盖情况进行动态决策(参见 CanUseTool 类型
  5. 分层防御 通过结合模式、规则、钩子和回调来保护关键应用程序