读完这篇你能:分清「货架上有哪些工具」和「哪些工具能被放行」这两层,并知道每个参数管哪一层。
前置:工具调用过程。约 25 分钟。
需求:权限这个东西说重要也不重要,在学习阶段几乎用不到什么
权限配置
claude agent sdk 与权限相关的配置,涉及到如下几个参数
allowedTools allowDangerouslySkipPermissions canUseTool disallowedTools permissionMode skills tools
先分清两层:货架 vs 放行
这 7 个参数不是同一件事,叠在一起才构成权限:
| 层 | 参数 | 管什么 |
|---|---|---|
| 货架(能不能看见) | tools、disallowedTools(裸名)、skills |
工具/技能是否进入模型上下文 |
| 放行(看见了能不能跑) | allowedTools、permissionMode、allowDangerouslySkipPermissions、canUseTool |
一次具体调用是自动过、问你、还是拒 |
disallowedTools 两边都沾:裸名 Bash 会从货架拿走;带范围的 Bash(rm *) 留在货架上,匹配到的调用一律拒。
tools:货架有哪些内置工具
作用: 规定主会话能看见的内置工具集合,不是白名单放行。
| 写法 | 效果 |
|---|---|
| 省略 | 全部默认 Claude Code 工具都在货架上 |
['Read', 'Grep', 'Glob'] |
只挂这几个 |
[] |
关掉全部内置工具 |
{ type: 'preset', preset: 'claude_code' } |
显式用完整默认套件 |
常见内置工具包括:Read / Edit / Write、Glob / Grep、Bash、WebSearch / WebFetch、Skill、AskUserQuestion、Agent 等。
和 allowedTools 的差别:tools 决定「有没有这个工具」;allowedTools 决定「有了之后要不要自动批准」。要收窄能力,先收 tools,再配放行规则。
allowedTools:预批准,不是收货架
作用: 把列出的工具(或带范围的规则)加入 allow 列表,匹配到的调用自动过,不进 canUseTool。
没列上的工具还在,只是落到后面的 permissionMode / canUseTool。
allowedTools: [‘Read’, ‘Glob’, ‘Grep’, ‘Bash(ls *)’]
含义:
Read/Glob/Grep:整工具自动过Bash(ls *):只有匹配的 Bash 自动过,其它 Bash 继续往后走- 没写
Write/Edit:模型仍能申请,只是不会因为这条规则自动过
注意:
- 不能靠
allowedTools: ['*']全放行,这类条目会被忽略 - MCP 允许规则必须带
mcp__<server>__前缀,例如mcp__github__get_* - 约束不了
bypassPermissions:模式会先放行未匹配 allow 的调用。那个模式下要禁某工具,用disallowedTools
本例没写 → 没有任何 SDK 侧预批准(磁盘上的 settings.json 仍可能生效)。
disallowedTools:最硬的否决
作用: 加入 deny 列表。匹配到就拒,包括 bypassPermissions。
| 写法 | 效果 |
|---|---|
['Bash'] |
从请求里拿掉 Bash,模型看不见、也调不了 |
['Bash(rm *)'] |
Bash 还在,匹配 rm * 的调用一律拒 |
['*'] |
拿掉全部工具定义 |
['mcp__*'] |
拿掉所有 MCP 工具 |
路径规则:Edit(path) 管所有写文件工具(含 Write、NotebookEdit)。//secrets/** 是磁盘绝对路径;/secrets/** 对 SDK 传入的规则来说锚在会话 cwd。
permissionMode:没被规则接住时怎么办
作用: 全局策略。本例省略,等价 'default'。
| 模式 | 行为 | 适合 |
|---|---|---|
default |
没被 allow 接住的调用走 canUseTool;没回调就拒 |
交互审批 |
dontAsk |
不提示;没预批准的一律拒;不调 canUseTool |
无头、固定工具面 |
acceptEdits |
自动过工作区内的 Edit/Write 和常见文件命令(mkdir/mv/cp 等);其它 Bash 仍走规则 |
信任改文件、还要挡危险命令 |
plan |
只探索和出方案;写文件/改文件的 shell 不会因 allow 自动过,一律问 canUseTool |
先看方案再动手 |
auto |
用分类模型决定批/拒 | 要自治又要护栏 |
bypassPermissions |
到达这一步的调用几乎全过(须配合下一节的安全开关) | CI / 容器 / 隔离环境 |
例外(任何模式都不自动过):
- settings 里的显式
ask规则 AskUserQuestion、带「必须交互」标记的 MCP- 组织规定必须审批的 connector
- 针对关键路径的
rm/rmdir
子代理默认继承主会话模式。父级是 bypassPermissions / acceptEdits / auto 时,子代理定义里的 permissionMode 改不掉。
allowDangerouslySkipPermissions:绕过模式的双确认
TypeScript 里设 permissionMode: 'bypassPermissions' 必须同时:
permissionMode: ‘bypassPermissions’,
allowDangerouslySkipPermissions: true,
这是防误开的安全闩。Unix 下以 root 跑也不能用这个模式。
即使开了,下面这些仍然有效:
disallowedTools/ deny 规则- 显式
ask规则 PreToolUsehook 拒绝- 必须交互的工具、关键路径删除
allowedTools 限制不了这个模式。 只写 allowedTools: ['Read'] 再开 bypass,Bash / Write 一样会过。要禁工具,用 disallowedTools。
本例没开。同仓库的 subagent.ts 开了,所以子代理示例是「几乎全自动执行」。
canUseTool:运行时最后一闸
类型是:(toolName, input, options) => Promise<PermissionResult | null>。
返回:
{ behavior: ‘allow’ } // 放行
{ behavior: ‘allow’, updatedInput: { … } } // 改参数再放行
{ behavior: ‘allow’, updatedPermissions: suggestions } // 同时写入「以后都允许」
{ behavior: ‘deny’, message: ‘原因’ } // 拒,原因回给模型
{ behavior: ‘deny’, message: ‘…’, interrupt: true } // 拒并打断本轮
null // 表示你已在带外回了 control_response;误返回会让工具一直挂起
options 里常见字段:title / displayName / description(优先用现成文案)、toolUseID、blockedPath、decisionReason、suggestions(「始终允许」时应原样回传)、agentID、signal。
前面任何一步已经批准,都不会进这个回调。 想每次调用都检查,用 PreToolUse hook,不要依赖 canUseTool。
本例没传回调,又是 default 模式 → 需要询问的调用会直接拒,模型收到拒绝后再改口或只回文本。这就是「看起来只能聊天」的真正原因:不是没工具,是没审批面。
若同时配了会被前面步骤短路的 canUseTool(例如 bypass,或裸名 allowedTools: ['Read']),SDK 会打一次进程警告 CLAUDE_SDK_CAN_USE_TOOL_SHADOWED。
skills:开哪些技能,并自动放行 Skill 工具
| 写法 | 效果 |
|---|---|
| 省略(本例) | SDK 不额外改;不是关技能,CLI 自己的默认仍在 |
'all' |
启用发现到的全部技能 |
['pdf', 'docx'] |
只开这些(也可 plugin:skill) |
[] |
明确不让 SDK 注入技能(subagent.ts 就是这样) |
设了 skills 后不必再把 'Skill' 写进 allowedTools。
这是上下文过滤,不是沙箱:没列出的技能不会出现在列表里,Skill 工具也会拒,但文件还在磁盘上,Read / Bash 仍可能读到。不要把密钥放进 skill 文件。
省略时实际在跑什么
| 参数 | 本例 | 实际效果 |
|---|---|---|
tools |
省略 | 完整默认工具货架 |
allowedTools |
省略 | 无 SDK 预批准 |
disallowedTools |
省略 | 无 SDK deny |
permissionMode |
省略 | default |
allowDangerouslySkipPermissions |
省略 | 不能开 bypass |
canUseTool |
省略 | 需要询问的调用被拒 |
skills |
省略 | 不关技能,跟 CLI 默认 |
下一篇:权限审批——canUseTool 那一闸单独展开。