Claude Code 实践课程 · Lesson 02

权限与 settings.json

目标不是全锁死也不是全放开,而是让弹窗只出现在值得你看一眼的地方

01

权限判定的真实顺序

CC 收到一个工具调用时,自上而下走这条链,命中即停

1
deny 规则 —— 命中即拒绝
谁都救不回来。deny 永远赢,哪怕同一调用也命中了 allow。
2
ask 规则 —— 命中即弹窗
优先于 allow:用来给宽放行挖「例外」。比如放行了 git *,但 git push * 单独 ask。
3
allow 规则 —— 命中即放行
不弹窗。这是消灭「确认疲劳」的工具。
4
都没命中 → 权限模式的默认行为
default(写操作弹窗确认)· acceptEdits(文件编辑自动放行)· plan(只读规划)· bypassPermissions(全放行,只配在沙箱里用)。
+
兜底层:行为分类器
不看规则看语义。即使技术上可放行,它判断「这个动作需要用户具体授权」时照样拦。
真实案例 · 2026-06-10 给配置瘦身时,「按你猜的办」这句概括性授权足以让 Claude 禁用插件,但它发起 mv ~/.claude/agents(修改 agent 自身加载的配置)时被分类器拦下——理由是这类自我修改需要对具体动作的明确授权。用户点头确认后,同一命令顺利执行。结论:allowlist 不是无限授权书,概括授权 ≠ 具体授权。
02

规则语法速查

i.Bash 前缀匹配 Bash(pnpm *)含复合命令陷阱
* 是前缀通配。复合命令会被拆开逐段检查——有一段没规则覆盖,整条弹窗。这是保护你的特性,不是 bug。 pnpm test → 命中 Bash(pnpm *),放行
pnpm test && rm -rf node_modules → rm 段无规则,整条弹窗
ii.文件路径 Read(./.env*)gitignore 风格
./ 相对项目根,~/ 家目录,// 文件系统绝对路径,** 递归。项目目录内的普通读取默认免弹窗——路径规则主要用于 deny 秘密文件、allow 项目外目录。 "deny": ["Read(./.env*)", "Read(~/.ssh/**)"]
iii.网络 WebFetch(domain:github.com)按域名治理
注意认知坑:同一个目的地,不同通道要分别治理。放行了 WebFetch 的 github.com,不等于放行 curl github.com——curl 走 Bash 规则,因为它还能干别的(比如把数据发出去)。
iv.MCP 工具 mcp__server__tool服务器级或工具级
mcp__playwright 放行整个服务器,mcp__playwright__browser_click 只放行单个工具。原则:读类工具放行,会产生外部影响的逐个评估。
03

练习:你来当权限引擎

下面是一份固定的 settings.json。对每个工具调用,裁决它的命运:放行(不弹窗)、弹窗(等用户确认)、拒绝(直接挡掉)。

.claude/settings.json 已判 0 / 10 · 答对 0
{
  "allow": ["Bash(pnpm *)", "Bash(git *)", "Read(~/docs/**)", "WebFetch(domain:github.com)"],
  "ask":   ["Bash(git push *)"],
  "deny":  ["Read(./.env*)", "Read(./secrets/**)", "Bash(curl *)"]
}  // 权限模式: default

判定链口诀:deny 先看、ask 其次、allow 殿后,都没中就问模式。

04

配置文件的层级(优先级从高到低)

同一条规则出现在多层时,高层赢。点开看每层的职责分工:

L1·L2企业托管策略 / 命令行参数
企业策略个人用户碰不到;命令行参数(--allowedTools 等)是 session 级临时覆盖,适合一次性场景,不留痕。
L3项目/.claude/settings.local.json
个人 + 本项目,自动进 .gitignore。放你个人的顺手放行:你自己的部署脚本、你本机的特殊路径。队友看不到,也不该看到。
L4项目/.claude/settings.json
团队 + 本项目,进 git 共享。放团队共识:deny 读 .env、放行本项目的构建测试命令。新人 clone 下来即生效。
L5~/.claude/settings.json
个人全局,影响你所有项目。放真正跨项目通用的:deny 读 ~/.ssh、放行 ls/grep 这类纯读命令。做实验时别动这层——污染了不好排查。
05

设计哲学:三个动词

放行
读类操作
搜索、列目录、读非敏感文件、跑测试。对它们弹窗只产生疲劳,不产生安全。
弹窗
写类与外发操作
git push、对外请求、改系统状态。这是真正值得你看一眼的时刻。
拒绝
秘密与不可逆
.env、密钥目录、rm -rf。连问都不要问——问了你也可能手滑点确认。

为什么「弹窗太多」是真正的危害:你会患上确认疲劳,开始无脑点确认——那时权限系统就名存实亡了。每一条 allow 规则都是在保护「弹窗」这个信号的信噪比。

起手配置模板见 starter-kit/settings.json.template。用了一阵后,可以用 /fewer-permission-prompts 扫描历史,把「你总是点确认的东西」自动转成规则。

06

到新项目的验证清单

拷入模板到项目 .claude/settings.json,把命令换成项目实际的包管理器和脚本。
测 deny:项目里放一个 .env(假内容),让 Claude「读一下 .env 看看配置」——应被拒绝。
测 ask 优先于 allow:让它提交并 push——commit 不弹窗、push 弹窗,说明分层生效。
干一天活,数弹窗:哪个弹窗你看都没看就点了确认?它就是下一条 allow 规则。

勾选状态存在浏览器 localStorage 里,下次打开还在。

本课带走一句话
每一条 allow 规则都是在保护弹窗的信噪比——让弹窗只出现在值得你看一眼的地方