Skip to content

Claude Agent SDK 提供了两层权限控制:声明式规则(allowed_tools / disallowed_tools)和权限模式(default、dontAsk、acceptEdits、bypassPermissions、plan)。规则在模式之前评估,但 bypassPermissions 模式会无视 allowed_tools 的约束——此时只能靠 disallowed_tools 和 hooks 阻止特定工具。dontAsk 模式则直接拒绝未被 allowed_tools 或规则预批准的调用,不触发 canUseTool。子代理会继承父级的 bypassPermissions、acceptEdits 或 auto 模式,且不可覆盖。

Claude Code Agent SDK 权限模式与允许/拒绝规则配置

控制代理使用工具的权限:权限模式、钩子、声明式允许/拒绝规则。

Claude Agent SDK 提供权限控制来管理 Claude 如何使用工具。使用权限模式和规则定义哪些操作可以自动执行,并通过 canUseTool 回调 在运行时处理其他情况。

本页介绍权限模式和规则。如需构建运行时让用户批准或拒绝工具请求的交互式审批流程,请见处理批准与用户输入

权限评估顺序

当 Claude 请求使用某个工具时,SDK 按以下顺序检查权限:

  1. 首先运行钩子。钩子可以直接拒绝调用,或放行。钩子返回 allow 并不会跳过下面的拒绝和允许规则——那些规则仍会被评估。

  2. 检查 deny 规则(来自 disallowed_toolssettings.json)。如果有拒绝规则匹配,工具会被阻止,即使在 bypassPermissions 模式下也是如此。裸名称的拒绝规则(如 Bash)会在评估开始前就把工具定义从 Claude 的上下文中移除,因此在这一步只检查带作用域的规则(如 Bash(rm *))。

  3. 应用当前的权限模式bypassPermissions 会通过所有到达这一步的调用。acceptEdits 会批准文件操作。其他模式继续往下。

  4. 检查 allow 规则(来自 allowed_tools 和 settings.json)。如果有规则匹配,工具被批准。

  5. 如果以上都没有解决,调用你的 canUseTool 回调 做决定。在 dontAsk 模式下,这一步跳过,工具被拒绝。

权限评估流程示意图

本页重点介绍允许和拒绝规则以及权限模式。其他步骤:

允许与拒绝规则

allowed_toolsdisallowed_tools(TypeScript 中为 allowedTools / disallowedTools)向评估流程中的允许规则列表和拒绝规则列表添加条目。允许规则只影响批准:未列在 allowed_tools 中的工具对 Claude 仍然可用,会继续走权限模式。拒绝规则的行为取决于它是命名了一个工具还是限定了工具内的模式。

选项效果
allowed_tools=["Read", "Grep"]ReadGrep 被自动批准。未列出的工具仍然存在,会继续到权限模式和 canUseTool
disallowed_tools=["Bash"]Bash 工具定义从请求中移除。Claude 看不到这个工具,也无法尝试调用。
disallowed_tools=["Bash(rm *)"]Bash 仍然可用。匹配 rm * 的调用在所有权限模式下都被拒绝(包括 bypassPermissions)。其他 Bash 调用继续到权限模式。

对于锁定式代理,可将 allowedToolspermissionMode: "dontAsk" 配合使用。列出的工具被批准;其他任何工具直接被拒绝,不会触发提示:

typescript
const options = {
  allowedTools: ["Read", "Glob", "Grep"],
  permissionMode: "dontAsk"
};

allowed_tools 不约束 bypassPermissions allowed_tools 只是预批准你列出的工具。未列出的工具不会被任何允许规则匹配,会继续到权限模式,而在 bypassPermissions 模式下它们全部被批准。如果在设置 allowed_tools=["Read"] 的同时使用了 permission_mode="bypassPermissions",那么包括 BashWriteEdit 在内的所有工具都会被批准。如果你需要 bypassPermissions 但希望阻止特定工具,请使用 disallowed_tools

你也可以在 .claude/settings.json 中声明式地配置 allow、deny 和 ask 规则。当启用 project 设置源时(默认 query() 选项中已启用),这些规则会被读取。如果你显式设置了 setting_sources(TypeScript 中为 settingSources),需要包含 "project" 才能使它们生效。规则语法详见权限设置

权限模式

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

可用模式

SDK 支持以下权限模式:

模式描述工具行为
default标准权限行为无自动批准;未匹配的工具触发 canUseTool 回调
dontAsk拒绝而不是提示任何未被 allowed_tools 或规则预批准的工具都被拒绝;canUseTool 永远不会被调用
acceptEdits自动接受文件编辑文件编辑和文件系统操作(mkdirrmmv 等)自动批准
bypassPermissions绕过所有权限检查所有工具无需权限提示即可运行(小心使用)
plan规划模式只读工具运行;Claude 分析并规划,不修改源文件
auto(仅 TypeScript)模型分类批准模型分类器批准或拒绝每个工具调用。可用性见自动模式

子代理继承: 当父代理使用 bypassPermissionsacceptEditsauto 时,所有子代理继承该模式且无法为单个子代理覆盖。子代理的系统提示和约束行为可能比主代理更宽松,因此继承 bypassPermissions 会赋予它们完全自主的系统访问权限,而不需要任何批准提示。

设置权限模式

既可以在启动查询时一次性设置权限模式,也可以在会话激活期间动态更改。

  • 在创建查询时传递 permission_mode(Python)或 permissionMode(TypeScript)。该模式适用于整个会话,除非动态更改。

    python
    import asyncio
    from claude_agent_sdk import query, ClaudeAgentOptions
    
    async def main():
        async for message in query(
            prompt="Help me refactor this code",
            options=ClaudeAgentOptions(
                permission_mode="default",  # 在这里设置模式
            ),
        ):
            if hasattr(message, "result"):
                print(message.result)
    
    asyncio.run(main())
    typescript
    import { query } from "@anthropic-ai/claude-agent-sdk";
    
    async function main() {
      for await (const message of query({
        prompt: "Help me refactor this code",
        options: {
          permissionMode: "default" // 在这里设置模式
        }
      })) {
        if ("result" in message) {
          console.log(message.result);
        }
      }
    }
    
    main();
  • 调用 set_permission_mode()(Python)或 setPermissionMode()(TypeScript)动态更改模式。新模式立即对所有后续工具请求生效。这样可以从严格权限开始,随着信任建立逐步放宽——例如在审核完 Claude 的初步方案后切换到 acceptEdits

    python
    import asyncio
    from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
    
    async def main():
        async with ClaudeSDKClient(
            options=ClaudeAgentOptions(
                permission_mode="default",  # 从默认模式开始
            )
        ) as client:
            await client.query("Help me refactor this code")
    
            # 在会话中动态更改模式
            await client.set_permission_mode("acceptEdits")
    
            # 使用新的权限模式处理消息
            async for message in client.receive_response():
                if hasattr(message, "result"):
                    print(message.result)
    
    asyncio.run(main())
    typescript
    import { query } from "@anthropic-ai/claude-agent-sdk";
    
    async function main() {
      const q = query({
        prompt: "Help me refactor this code",
        options: {
          permissionMode: "default" // 从默认模式开始
        }
      });
    
      // 在会话中动态更改模式
      await q.setPermissionMode("acceptEdits");
    
      // 使用新的权限模式处理消息
      for await (const message of q) {
        if ("result" in message) {
          console.log(message.result);
        }
      }
    }
    
    main();

模式详情

接受编辑模式(acceptEdits

自动批准文件操作,让 Claude 无需提示即可编辑代码。其他工具(如非文件系统操作的 Bash 命令)仍需要正常权限。

自动批准的操作:

  • 文件编辑(Edit、Write 工具)
  • 文件系统命令:mkdirtouchrmrmdirmvcpsed

上述操作仅适用于工作目录或 additionalDirectories 内的路径。超出范围的路径以及写入受保护路径的操作仍会提示。

适用场景: 你信任 Claude 的编辑并希望加快迭代速度,例如在原型开发或在隔离目录中工作时。

无需询问模式(dontAsk

将所有权限提示转换为拒绝。由 allowed_toolssettings.json 的 allow 规则或钩子预批准的工具正常运行。其他所有工具被拒绝,canUseTool 不会被调用。

适用场景: 你希望为无头代理提供一个固定、显式的工具表面,并且倾向于硬拒绝而非依赖 canUseTool 的缺失。

绕过权限模式(bypassPermissions

自动批准所有工具使用,无需提示。钩子仍会执行,可以在需要时阻止操作。

谨慎使用。 在此模式下 Claude 拥有完全的系统访问权限。仅在受控环境中使用,且信任所有可能的操作。

allowed_tools 不约束此模式。所有工具都被批准,而不仅仅是你列出的那些。拒绝规则(disallowed_tools)、显式的 ask 规则以及钩子会在模式检查之前评估,仍然可以阻止某个工具。

规划模式(plan

将 Claude 限制为只读工具。Claude 可以读取文件并运行只读 shell 命令来探索代码库,但不会修改你的源文件。Claude 可能会使用 AskUserQuestion 来澄清需求,然后再最终确定计划。处理这些提示请见处理批准与用户输入

适用场景: 你希望 Claude 提出修改方案但不执行,例如在代码审查期间或需要先批准修改再执行时。

相关资源

权限评估流程的其他步骤:

常见问题

allowed_tools 配合 bypassPermissions 为什么不生效?

bypassPermissions 会无条件批准所有到达该步骤的工具。allowed_tools 只在模式检查之前预批准工具,未列出的工具不会被拒绝,而是继续到模式检查中被批量通过。要同时使用 bypassPermissions 并阻止某些工具,必须用 disallowed_tools 或钩子。

dontAsk 模式下工具被拒绝后还会触发回调吗?

不会。dontAsk 模式下,任何未被 allowed_toolssettings.json 的 allow 规则或钩子预批准的工具都会被直接拒绝,完全不调用 canUseTool 回调。这意味着用户不会有任何交互提示。

子代理能覆盖父代理的权限模式吗?

不能。当父代理使用 bypassPermissionsacceptEditsauto 时,所有子代理强制继承该模式,且无法为单个子代理覆盖。如果父代理使用 defaultdontAsk,子代理可以使用不同的模式。注意继承 bypassPermissions 会给予子代理完全的系统访问权限。