60 秒看懂 Claude Code 权限
- Bash、Edit、WebFetch、Write 这些工具执行前会弹权限确认;Read、Glob、Grep、LS 只读不问,直接执行。
- 选「Yes, and don't ask again」会把 Bash(git add:*) 这类规则自动写进 .claude/settings.local.json——只属于你、自动排除在 git 之外的私人规则库。
- 规则按 deny → ask → allow 的顺序求值:任何配置文件里的 deny 都优先命中,allow 规则永远无法在 deny 里开口子。
- 权限模式决定信任程度:改代码多就用 acceptEdits(alt+m),只读调研用 plan,CI 无人值守用 --permission-mode bypassPermissions——注意 defaultMode 里的 auto 和 bypassPermissions 只有写在用户级或托管配置里才生效。
Claude Code Tutorial #4 - Tools & Permissions
频道:The Net Ninja4:55
Permission Modes Head to Head
频道:ttywood6:20
Permissions — Claude Code documentation
文档:code.claude.com
Settings files — Claude Code documentation
文档:code.claude.com
全部截图取自 Net Ninja 的录屏——纯屏幕录制,无摄像头、无叠加字幕。ttywood 那期对比各权限模式的视频仅用作模式与配方章节的交叉参考,没有贡献任何截图(其画面带烧录字幕)。规则语法、求值顺序、模式行为与配置文件优先级均已对照两页官方文档核实。
视频版权归 The Net Ninja 与 ttywood 所有,此处仅作链接引用。文档版权归 Anthropic 所有。截图仅为本指南的评论性引用。
一步一步配好 Claude Code 权限
Claude Code 动手前会先问什么
- 1
先搞清楚哪些工具会触发权限确认
Claude Code 会自己挑工具——读文件用 Read、改文件用 Edit、跑命令用 Bash。Anthropic 官方设置文档给每个工具标了 Permission Required 列:Bash、Edit、WebFetch、Write 会停下来问你;Read、Glob、Grep、LS 则直接执行。你从不需要手写工具名,提前知道哪些动作会暂停等你确认就够了。

Claude Code 官方设置文档的工具表,每个工具都标了是否需要权限。跳到 1:05 观看 - 2
让它改个文件,观察它先读后改
视频里的需求很小:给 src/app/globals.css 加一个淡黄色的 --highlight 变量。Claude Code 先读取文件——Read 永远不需要权限——直到要动手改文件时才停下来。这一幕就是整个权限模型的缩影:看不要钱,动手指令要过审。

在 VS Code 的 Claude Code 输入框里敲下加高亮变量的需求。跳到 1:45 观看 - 3
回答之前,先读懂弹窗的三个选项
每次编辑确认都有三个答案:1. Yes 只批准这一处修改;2. Yes, and don't ask again this session 本次会话内后续修改不再询问(视频版本里按 alt+m);3. No, and tell Claude what to do differently(esc)拒绝修改并给出你的指示。选 3 不是失败——而是在代码落地前纠偏的正确姿势。

globals.css 的编辑确认弹窗,三个权限选项完整可见。跳到 2:17 观看
只确认一次:把规则写进配置
- 4
每次修改都会单独确认,不是一个任务问一次
批准不会延续到下一处改动。演示里同一个文件改了三处,就得连按三次 Yes,下一处改动照样弹窗。事事确认当然能用,但只要任务超过两行就会烦人——allow 规则和权限模式正是为此而生的。

第一处刚批准,globals.css 的第二处修改紧接着又弹确认。跳到 2:32 观看 - 5
Bash 命令有自己单独的确认关卡
Shell 命令另设一道闸。演示里让 Claude 提交代码时,Bash(git add src/app/globals.css) 处于 Waiting 状态等你裁决。批准了一条命令不等于批准下一条——后面的 git commit 还会按它自己的名义再问你一次。

git add 命令挂起等待批准,上方是已执行完的 git 输出。跳到 3:16 观看 - 6
让「不再询问」替你把规则写好
选择 Yes, and don't ask again for git add commands 一箭双雕:既放行当前命令,又保存一条规则。它创建的文件是仓库根目录下的 .claude/settings.local.json,里面是一个 permissions 对象:allow 数组——本例为 "Bash(git add:*)"——外加空的 deny 和 ask 数组。从此这个项目里所有 git add 都不再弹窗。

资源管理器里的 .claude 目录与新建的 settings.local.json,allow 规则已写入。跳到 3:40 观看 - 7
弹窗搞不定的规则,直接手改配置文件
allow 数组就是普通 JSON,可以自己动手加规则。单条命令用精确写法——Bash(npm run test);前缀相同的命令用尾通配 :*——Bash(npm run test:*)。官方文档确认 :* 就是尾通配的等价简写。记住这个文件是私人的:Claude Code 会自动把 settings.local.json 加进全局 git 排除,视频里也是同样建议——它属于你的工作流,不属于仓库。

手动编辑配置文件,permissions.allow 里的规则处于选中状态。跳到 4:22 观看
用权限模式调节放权程度
- 8
集中改代码时,切到 accept edits 模式
alt+m(新版也可用 shift+tab 循环切换)把会话角标切成 accept edits on。此后文件修改直接落地不再弹窗,官方文档还补充:mkdir、touch、mv、cp 这类常见文件系统命令也会自动放行。这份豁免只在当前会话有效——新开会话又回到逐次确认,直到你重新开启。

底部显示 accept edits on,已放行的 git 命令顺势完成提交。跳到 4:35 观看 - 9
切换之前,先认全整个模式阶梯
权限模式决定一个会话的默认姿态:default 每个工具首次使用时弹窗;plan 只读调研、不改一行代码;acceptEdits 自动接受文件修改;dontAsk 把本该弹窗的调用一律自动拒绝;auto 带后台安全检查自动放行;bypassPermissions 跳过确认弹窗,仅少数任何模式都不得自动批准的操作除外。单次会话用 --permission-mode 指定,长期生效写进 permissions.defaultMode。
- 10
defaultMode 要写在正确的配置文件里
官方设置文档写得明明白白:defaultMode 的 auto 和 bypassPermissions 两个值写在项目级或本地级配置里不生效——要么放进用户级(~/.claude/settings.json)或托管配置,要么单次会话传 --permission-mode。配置优先级从高到低:managed settings → CLI --settings → .claude/settings.local.json → .claude/settings.json → 用户级配置,而且任何一层出现 deny 都压过下面所有 allow。
真实项目的即抄配方
- 11
配方一:放开跑测试,锁死 rm 和 .env
在团队共享的 .claude/settings.json 里:"permissions.allow": ["Bash(npm run test:*)"],再用 "permissions.deny": ["Bash(rm -rf *)", "Read(./.env)"] 把危险删除和密钥读取堵死。网页调研同理可以按域名放行:"WebFetch(domain:example.com)" 放行单个域名,"WebFetch(domain:*.example.com)" 放行整个子域。因为 deny 先求值,任何 allow 都无法在它身上开口子。
- 12
配方二:CI 里安全地跳过全部确认
无人值守的运行需要刻意的姿态,而不是随手一关:CI 任务里传 --permission-mode bypassPermissions,或者把 defaultMode 写进用户级/托管配置——项目级配置文件无权授予。想让这道护栏不可逾越,就在托管配置里把 permissions.disableBypassPermissionsMode 设为 "disable";再用 /permissions 随时审计某台机器上生效的每条规则及其来源文件。
deny → ask → allow:规则到底按什么顺序生效
官方权限文档的原话:规则按 deny、ask、allow 的顺序求值,第一条命中的规则决定结果,规则写得多具体都改变不了这个顺序。无论你的 allow 写得多精准,都不可能在 deny 里挖出例外。
deny 的效力还横跨所有配置文件:用户级配置放行的命令,只要项目级配置 deny 了就会被拦下——因为任何作用域的 deny 都先于 allow 求值,而托管配置里的 deny 连命令行参数都覆盖不了。deny 一个裸工具名(比如 "Bash")更彻底:文档明确说这会把该工具从 Claude 的上下文里整个移除。
实际结论:把安全规则——禁 rm、禁读 .env、禁强推——放进随仓库分发的项目级 .claude/settings.json;allow 列表当成锦上添花的便利设施叠在上面。allow 列表跨作用域是合并而非覆盖,所以你私人的 settings.local.json 可以随意加豁免,而不会削弱任何人的 deny。
三个值得直接抄的配方
每个配方都标注了该写进哪个文件。贯穿所有配方的一条铁律:deny 永远、处处优先。
放开跑测试,锁死 rm 和 .env
写进 .claude/settings.json:"permissions.allow": ["Bash(npm run test:*)"](按你的技术栈换成 "Bash(npx vitest:*)" 或 "Bash(uv run pytest:*)"),"permissions.deny": ["Bash(rm -rf *)", "Read(./.env)"]。测试随取随跑不用守着;危险删除和密钥读取则在求值到达 allow 之前就被拦下。
把联网调研钉在信任的域名上
查文档多的项目:allow 里加 "WebFetch(domain:developer.mozilla.org)"、"WebFetch(domain:claude.com)",或用 "WebFetch(domain:*.example.com)" 覆盖整个子域。反过来 deny 裸工具名 "WebFetch" 则彻底关闭网页阅读——适合必须只依赖本地上下文、追求可复现的运行。
CI 无人值守,但不至于脱缰
让 CI 任务传 --permission-mode bypassPermissions,或把 "permissions.defaultMode": "bypassPermissions" 写进用户级/托管配置——项目级和本地级配置给不了这个值。要整个组织禁用该模式,在托管配置里设 "permissions.disableBypassPermissionsMode": "disable",任何仓库、任何参数都翻不过这道墙。即便放开了,bypassPermissions 仍会拦下少数任何模式都不得自动批准的操作。
规则不生效?按这四条排查
大多数「allow 规则被无视」的问题,根源都在规则落错了文件,或者被别的文件压住了。
- 1规则没错,文件错了。会话里点「不再询问」写入的是 .claude/settings.local.json;团队规则应放 .claude/settings.json;整机规则放 ~/.claude/settings.json。跑一下 /permissions——它列出每条生效规则和各自来源的配置文件。
- 2被更高层级的 deny 压住。配置值按层级向下覆盖,但任何层级的 deny 都先于 allow 求值——用户级的 allow 救不回项目级的 deny,托管配置更是连命令行参数都压得住。
- 3allow 规则在等信任确认。deny 和 ask 即刻生效,但随仓库提交的项目级文件里的 allow 规则,要等你信任该工作区目录之后才生效——这是给 clone 来的仓库预留的一道闸。
- 4模式写进了错误的文件。defaultMode 的 auto 和 bypassPermissions 写在项目级、本地级配置里会被直接无视(文档注明此行为自 v2.1.257 起生效——之前 bypassPermissions 在任何文件里都生效)。把它们移到用户级或托管配置,或者单次会话用 --permission-mode。
