本教程面向已经完成 Claude Code 安装、能跑通首个项目,但每次操作都被反复弹窗"Allow / Deny"困扰的开发者。你将系统掌握 Claude Code 的权限判定机制、settings.json 四层作用域、allow / ask / deny 规则语法、六种权限模式,以及如何用一条"白名单 + 兜底拒绝"策略把日常开发中的确认弹窗降到接近零,同时把 rm -rf、git push、.env 泄露等高危操作牢牢锁死。学完即可为团队产出一份可直接提交到 Git 的安全配置文件。
cd、ls、git)。Claude Code 的权限并非"一刀切开关",而是按工具类型分级处理,这是理解整个体系的基石:
| 工具类型 | 示例 | 是否需要审批 | "Yes, don't ask again" 的生效范围 |
|---|---|---|---|
| 只读工具 | 文件读取、Grep、Glob | 否 | 不适用 |
| Bash 命令 | npm run build、git commit |
是 | 按"项目目录 + 命令前缀"永久记住 |
| 文件修改 | Edit / Write | 是 | 仅在当前会话内有效 |
这条分级规则解释了一个常见困惑:为什么 cat、ls 从来不弹窗,而 npm install 每次都要确认。原因是 Claude Code 内置了一批"只读命令白名单",包括 ls、cat、echo、pwd、head、tail、grep、find、wc、which、diff、stat、du、cd,以及 git 的只读形态(如 git status、git log)。这套只读集合不可配置——如果你想强制让 cat 也弹窗,必须显式写一条 ask 或 deny 规则。
操作说明:在练习目录中启动 Claude Code,依次输入"看一下当前目录结构""读一下 package.json"等指令,观察这些只读操作零弹窗;再输入"运行 npm install",观察弹出审批框。
预期结果:只读操作直接执行;写操作弹出审批,点击 "Yes, don't ask again" 后,该命令前缀在本目录内不再询问。
常见问题:有用户误以为"只读命令白名单"可以被关掉来提升安全。事实上它只是省略了交互确认,底层仍是受控的只读行为;真正的安全闸门在于 deny 规则与权限模式,而非禁用只读集合。
settings.json 的四层作用域Claude Code 用"作用域(scope)"机制决定配置在哪里生效、与谁共享。从高到低优先级依次是:
| 作用域 | 文件位置 | 影响范围 | 是否随 Git 共享 |
|---|---|---|---|
| Managed(托管) | 服务端下发 / 系统级 managed-settings.json |
本机所有用户 | 由 IT 统一部署 |
| User(用户) | ~/.claude/settings.json |
你自己的所有项目 | 否 |
| Project(项目) | <repo>/.claude/settings.json |
本仓库所有协作者 | 是(提交到 Git) |
| Local(本地) | <repo>/.claude/settings.local.json |
仅你在本仓库 | 否(自动 gitignore) |
需要特别记住一条反直觉规则:普通配置项按"高优先级覆盖低优先级"合并(Managed 最高、User 最低),但权限规则是跨作用域"合并"而非"覆盖"。也就是说,User 作用域里允许的 Bash(npm run *),在 Project 作用域里依然有效,二者叠加生效。
操作说明:用 /config 命令打开设置面板,可以一览当前生效的所有配置及其来源作用域;用 /permissions 命令则专门查看权限规则列表,并标注每条规则来自哪个 settings.json。
何时用哪个作用域: - 团队共享的权限策略、Hooks、MCP 服务器 → 写进 Project 作用域并提交 Git。 - 个人偏好(主题、编辑器、个人 API Key)→ 写进 User 作用域。 - 临时试验、机器相关路径 → 写进 Local 作用域,避免污染团队仓库。 - 安全合规、不可被覆盖的强制策略 → 由 IT 写进 Managed 作用域。
常见问题:很多人手写 .claude/settings.local.json 后忘记加 .gitignore,把本地绝对路径误提交。最佳实践是让 Claude Code 自己创建该文件(创建时会自动配置 gitignore),或手动补上忽略规则。
allow / ask / deny 规则语法权限规则的格式非常简洁:Tool 或 Tool(specifier)。三类规则的核心差异在于评估顺序:
deny → ask → allow,按此顺序逐一匹配,第一条命中即决定结果,规则的"具体程度"不会改变这个顺序。
这意味着一条匹配的 ask 规则即使面对更具体的 allow 规则,也照样会弹窗确认。理解这一点,才能避免"我明明写了 allow 为什么还问我"的困惑。
deny 规则还有两种截然不同的形态,这是新手最容易踩的坑:
- 裸工具名 Bash:直接把整个工具从 Claude 的上下文中移除,Claude 根本"看不见"这个工具。
- 带限定符 Bash(rm *):工具仍然可用,但当 Claude 尝试执行匹配到的命令时予以拦截。
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git commit *)",
"Read(./.env.example)"
],
"deny": [
"Bash(git push *)",
"Read(./.env)"
],
"ask": [
"Bash(docker *)"
]
}
}
上面的配置含义是:放行所有 npm run 子命令和 git commit;永久拦截 git push;读取示例环境变量文件允许、读取真实 .env 拒绝;遇到 docker 命令每次确认。
常见问题:误把"想禁止的命令"写进 deny 的裸工具名形态(如直接写 "Bash"),结果整个 Bash 工具消失,Claude 连 ls 都不会主动用了。如果你只想拦某类命令,务必用 Bash(命令 *) 的带限定符形态。
Bash 规则支持 * 通配符,可出现在命令的任意位置,但有两处细节决定规则是否生效:
陷阱一:* 前的空格决定词边界。
- Bash(ls *)(带空格):只匹配 ls -la,不匹配 lsof。因为空格强制要求前缀后必须跟空格或字符串结尾。
- Bash(ls*)(无空格):同时匹配 ls -la 和 lsof,因为缺少词边界约束。
陷阱二:尾通配符的两种等价写法。
- Bash(ls *) 与 Bash(ls:*) 等价,都匹配以 ls 开头的命令。
- 但 :* 只在结尾被识别为通配。若写成 Bash(git:* push),冒号会被当成字面字符,无法匹配 git 命令——这是新手常犯的拼写错误。
陷阱三:复合命令必须逐段匹配。
Claude Code 能识别 shell 分隔符 &&、||、;、|、|&、& 以及换行。一条 Bash(safe-cmd *) 规则不会授权 safe-cmd && rm -rf 这种复合命令——系统会要求复合命令的每一段都独立命中规则。当你对复合命令点击"Yes, don't ask again"时,Claude Code 会为每段需要授权的子命令分别保存一条规则,单条复合命令最多保存 5 条。
陷阱四:进程包装器的剥离是有限的。
匹配 Bash 规则前,Claude Code 会先剥离一批固定的进程包装器:timeout、time、nice、nohup、stdbuf,以及不带参数的 xargs。所以 Bash(npm test *) 也能匹配 timeout 30 npm test。但这套剥离列表不可配置,且 direnv exec、devbox run、mise exec、npx、docker exec 等环境运行器不在列表内。Bash(devbox run *) 会匹配 devbox run rm -rf,因此对环境运行器必须写成精确到内部命令的规则,如 Bash(devbox run npm test)。同理,watch、setsid、find -exec 等执行型包装器永远弹窗,无法被前缀规则放行。
常见问题:试图用 Bash(curl http://github.com/ *) 限制 curl 只访问 GitHub,这种做法极其脆弱——curl -X GET、https:// 协议、重定向、变量展开、多余空格等任意一种变体都能绕过。正确做法是组合三招:用 deny 屏蔽 curl/wget,改用 WebFetch 工具并配 WebFetch(domain:github.com),再用 PreToolUse Hook 校验 URL。
权限模式决定了工具调用"默认怎么批",在 settings.json 里通过 defaultMode 字段设置。六种模式一览:
| 模式 | 行为 | 适用场景 |
|---|---|---|
default |
首次使用某工具时弹窗 | 日常交互开发 |
acceptEdits |
自动接受文件编辑与常见文件系统命令(mkdir/touch/mv/cp) |
大量连续改文件时 |
plan |
计划模式:只读探索,不改源码 | 调研、生成方案 |
auto |
自动批准,并做背景安全校验(研究预览) | 受信任的快速迭代 |
dontAsk |
除已预批准的工具外,全部自动拒绝 | CI 中只允许白名单操作 |
bypassPermissions |
跳过所有权限提示(高危) | 容器 / VM 等隔离环境 |
{
"defaultMode": "acceptEdits"
}
安全闸门:bypassPermissions 和 auto 模式风险较高。组织管理员可在 Managed 作用域里把 permissions.disableBypassPermissionsMode 或 permissions.disableAutoMode 设为 "disable",从根上禁掉这两种模式,且不可被下级作用域覆盖。
此外,即便是 bypassPermissions,也有两道"硬熔断"不可关闭:
1. 显式 ask 规则仍会强制弹窗。
2. 针对文件系统根目录或家目录的删除(如 rm -rf /、rm -rf ~)始终弹窗,作为对抗模型错误的最后一道防线。
bypassPermissions 还会跳过对 .git、.config/git、.claude、.vscode、.idea、.husky、.cargo、.devcontainer、.yarn、.mvn 等敏感目录写入的提示——务必仅在隔离环境使用。
常见问题:在 CI 流水线里,最推荐的是 dontAsk 模式 + 一份精简的 allow 白名单。这样任何未列入白名单的工具调用都会被自动拒绝,既不卡流水线,又不会因意外操作破坏环境。
/permissions 与 /config 实时管理交互式 REPL 提供了两个核心管理命令:
- /permissions:列出当前所有权限规则,并标注来源 settings.json。在这里可以直接新增、删除规则,所见即所得。
- /config:打开分页式设置面板,查看状态信息、修改配置项、切换权限模式。
操作说明:在 REPL 中输入 /permissions,观察刚才手写的规则是否被正确加载;再输入 /config,在 "Permissions" 分页里把 defaultMode 切到 plan,然后让 Claude 尝试修改一个文件,验证它是否被拒绝。
预期结果:/permissions 列出的规则与 settings.json 完全一致;切换到 plan 模式后,写操作被礼貌拒绝,Claude 转而只给出方案。
常见问题:有时 /permissions 里看到的规则比预期多——这是因为你对复合命令选过 "Yes, don't ask again",系统为每段子命令分别存了规则。可用 /permissions 的删除功能清理冗余条目。
additionalDirectories 与沙箱默认情况下,Claude Code 只能读写"当前工作目录"。如果项目依赖仓库外的共享代码或资源目录,需要在 settings.json 里用 additionalDirectories 显式授予访问权:
{
"additionalDirectories": [
"/home/user/shared-libs",
"/home/user/docs"
]
}
关键概念:additionalDirectories 授予的是文件访问权,而非配置作用域——它只决定"哪些路径可被读写",不改变任何权限规则或模式。
在 macOS 上,Claude Code 还支持沙箱(Sandbox)环境,把 Bash 命令限制在受控边界内执行,与权限规则配合形成纵深防御。沙箱路径前缀等设置可在 settings.json 的 sandbox 段配置。
常见问题:有人把仓库外目录加进 additionalDirectories 后,发现仍无法执行其中的脚本。原因是文件访问权只是第一步,执行 Bash 命令仍受 Bash 权限规则约束,需要同时配 allow 规则。
把上述知识落地为四条铁律:
deny 列表至少包含 Bash(rm -rf *)、Bash(git push *)、Bash(git push -f *)、Bash(sudo *)。deny 掉 Read(./.env)、Read(./.env.*)、Read(./**/secrets/**),防止密钥进入上下文。deny 掉 Bash(curl *)、Bash(wget *),改用 WebFetch(domain:...) 做域名级放行。bypassPermissions 仅在容器/VM 内使用,本机开发永远留在 default 或 acceptEdits。下面是一份可直接提交到团队仓库的 .claude/settings.json,综合运用本教程全部要点。场景:一个使用 npm + git + Docker 的 Node.js 服务,团队希望把开发弹窗降到最低,同时锁死危险操作。
{
"defaultMode": "acceptEdits",
"additionalDirectories": [
"../shared-types"
],
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(npm test*)",
"Bash(npm install)",
"Bash(npx prettier *)",
"Bash(npx eslint *)",
"Bash(git status)",
"Bash(git diff*)",
"Bash(git log*)",
"Bash(git add *)",
"Bash(git commit *)",
"Bash(* --version)",
"Bash(* --help)",
"Read(./.env.example)",
"WebFetch(domain:github.com)"
],
"ask": [
"Bash(docker *)",
"Bash(npm publish)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(rm -rf /*)",
"Bash(git push *)",
"Bash(git push -f *)",
"Bash(sudo *)",
"Bash(curl *)",
"Bash(wget *)",
"Read(./.env)",
"Read(./.env.*)",
"mcp__*"
]
}
}
这份配置的设计逻辑:
- defaultMode: acceptEdits 让连续改文件不被打断,提升开发流畅度。
- allow 覆盖日常高频命令(构建、测试、lint、只读 git),并放行 --version/--help 这类无害查询。
- ask 对 docker、npm publish 这类"影响面大但偶尔需要"的命令保留人工确认。
- deny 兜底所有高危项:递归删除、强制推送、提权、裸网络请求、密钥文件;最后用 mcp__* 一刀切拒绝所有 MCP 工具的默认访问(需要时再逐个 allow)。
验证步骤:
1. 把文件存为 <repo>/.claude/settings.json 并提交。
2. 启动 Claude Code,运行 /permissions 确认规则已加载。
3. 让 Claude 执行 npm run build——应零弹窗通过。
4. 让 Claude 尝试 git push——应被直接拒绝。
5. 让 Claude 尝试读取 .env——应被拒绝。
6. 让 Claude 执行 docker ps——应弹出确认框。
若每步行为符合预期,说明安全基线已生效。
下图展示了一次工具调用从发起到落地,Claude Code 权限系统的完整判定流程:
flowchart TD
A[Claude 发起工具调用] --> B{是否只读命令<br/>内置白名单?}
B -- 是 --> Z[直接执行 零弹窗]
B -- 否 --> C[剥离进程包装器<br/>timeout/time/nice...]
C --> D{deny 规则命中?<br/>裸名移除工具 / 带名拦命令}
D -- 是 --> Y[拒绝执行]
D -- 否 --> E{ask 规则命中?}
E -- 是 --> F[弹窗人工确认]
E -- 否 --> G{allow 规则命中?}
G -- 是 --> Z
G -- 否 --> H{defaultMode?}
H -- default/acceptEdits --> F
H -- plan --> P[计划模式 拒绝写操作]
H -- dontAsk --> Y
H -- bypassPermissions --> S{硬熔断?<br/>rm -rf / 或 rm -rf ~}
S -- 是 --> F
S -- 否 --> Z
F -->|批准并记忆| Z
F -->|拒绝| Y
读懂这张图,就掌握了 Claude Code 权限判定的全部逻辑分支:从只读白名单、包装器剥离,到 deny→ask→allow 的固定顺序,再到 defaultMode 兜底与硬熔断保护。
com.anthropic.claudecode 配置描述文件)和 Windows(HKLM\SOFTWARE\Policies\ClaudeCode 注册表)上做企业级集中管控。本文由「51学通信」原创整理,站长爱卫生(微信:gprshome201101)。关注获取更多 AI 编程工具与工程化实战教程。
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
