目录
Claude Code 的权限规则让你能在 settings.json 中编写 allow / ask / deny 条目,从而精细地指定哪些工具、命令、文件和域名可以无需询问直接运行、每次都要确认,或者被完全禁止。这些规则可以在团队间共享,因此你既能可靠地拦住危险操作,又能让安全的日常工作不被打断地顺畅运行。
本文将介绍什么是权限规则(以及它与权限模式的区别)、allow/ask/deny 的优先级、规则语法、settings.json 的层级,以及实用配置示例——全部基于官方规范。
用 allow / ask / deny 实现精细控制
按 deny → ask → allow 评估(先匹配者胜)
deny
禁止(优先级高于一切)
ask
每次都询问
allow
无需询问直接运行
1. 什么是权限规则(与模式的区别)
Claude Code 采用分层权限系统。读取操作(查看文件、Grep 等)无需批准;Bash 命令和文件编辑则需要——而在这个基线之上,规则让你能指定精细的例外(来源:Claude Code 官方文档「Configure permissions」)。
规则很容易与权限模式混淆。模式是「询问频率」的宽泛基线(default/acceptEdits/auto 等);规则则是针对每个工具、每条命令的具体指定。二者协同工作——模式设定基线,规则用「始终允许这个」或「绝不允许那个」来覆盖它。
💡 规则由 Claude Code 强制执行,而非模型。你的提示词或 CLAUDE.md 会影响 Claude 尝试去做什么,但不会决定什么是被允许的。请通过 /permissions、规则、模式或 PreToolUse 钩子来授予或撤销访问权限。
2. allow / ask / deny 与优先级
共有三种规则类型。/permissions 命令可以列出并编辑它们(并显示每条规则来自哪个 settings.json)。
无需询问直接运行
指定的工具/命令无需手动批准即可运行。
每次都询问
每次使用都请求确认。即使有更宽泛的 allow 也匹配,匹配到的 ask 仍会触发询问。
禁止(最高优先级)
阻止该工具。压过任何 allow,且任何层级的 deny 都始终获胜。
规则按 deny → ask → allow 评估。第一个匹配项决定结果,而规则的具体程度不会改变这个顺序。宽泛的 Bash(aws *) deny 会压过更具体的 Bash(aws s3 ls) allow。关键在于:deny 无法携带白名单例外。
⚠️ 两种 deny 写法行为不同:像 Bash 这样仅写工具名会把该工具从 Claude 的上下文中完全移除(Claude 根本看不到它)。而像 Bash(rm *) 这样限定范围的规则会保留该工具可用,仅阻止匹配的调用。
3. 规则语法(Tool(specifier))
格式为 Tool(全部)或 Tool(specifier)(特定)。每个工具都有自己的指定符风格。
| 工具 | 示例 | 含义 |
|---|---|---|
| Bash | Bash(npm run *) | 以 npm run 开头的命令(末尾的 * = 单词边界) |
| Read / Edit | Read(./.env) | 读取当前目录下的 .env(gitignore 风格路径) |
| WebFetch | WebFetch(domain:example.com) | 抓取到 example.com |
| MCP | mcp__github__get_* | github 服务器的 get_ 系列工具 |
| Agent | Agent(Explore) | Explore 子代理 |
Bash 通配符可以出现在任何位置。Bash(ls *)(空格 + *)能匹配 ls -la,但不匹配 lsof(单词边界);Bash(ls*)(无空格)则两者都匹配。末尾的 :* 等同于 *。
// 允许安全命令,禁止 git push
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git commit *)"
],
"deny": [
"Bash(git push *)"
]
}
}
注意复合命令。Claude Code 能识别 && || ; | 等分隔符,并且每个子命令都必须各自独立匹配。Bash(safe-cmd *) 并不会允许 safe-cmd && rm -rf .。需要注意的是,只读命令(ls/cat/grep/find/pwd 等)在任何模式下都会无询问运行,而像 timeout/nice/nohup 这样的包装器会在匹配前被剥离。
Read/Edit 路径遵循 gitignore 语义,有四种锚点:
| 写法 | 锚点 | 示例 |
|---|---|---|
//path | 文件系统绝对路径 | Read(//tmp/x) |
~/path | 主目录 | Read(~/.ssh/**) |
/path | 项目根目录 | Edit(/src/**) |
path / ./path | 当前目录 | Read(.env) |
※ /Users/... 并非绝对路径——它是相对于项目根目录的。绝对路径请使用 //Users/...(双斜杠)。Read(.env) 等同于 Read(**/.env),会匹配其下的每一个 .env。
4. settings.json 的层级与优先级
规则存放在 settings.json 中。它有多个文件,且层级越高越强。关键规则是:任何层级的 deny 都始终压过其他任何层级的 allow。
| 优先级 | 位置 | 用途 |
|---|---|---|
| 1(最强) | 托管设置(Managed settings) | 组织策略。无法被用户/CLI 覆盖 |
| 2 | 命令行参数 | 临时的会话级覆盖 |
| 3 | .claude/settings.local.json | 个人项目设置(已 gitignore) |
| 4 | .claude/settings.json | 共享项目设置(已提交) |
| 5 | ~/.claude/settings.json | 跨所有项目的用户设置 |
// .claude/settings.json(团队共享)
{
"permissions": {
"defaultMode": "acceptEdits",
"allow": ["Bash(npm run *)", "WebFetch(domain:docs.example.com)"],
"deny": ["Read(.env)", "Read(**/secrets/**)", "Bash(git push *)"],
"additionalDirectories": ["../shared-lib"]
}
}
默认权限模式也在这里设置,即 defaultMode(模式详情)。要读取/编辑工作目录之外的内容,请把路径添加到 additionalDirectories。
5. 实用配置示例
常见的组合。基本思路是:可靠地禁止危险操作,允许安全的日常操作以实现自动化。
🔒 保护密钥文件
deny: ["Read(.env)", "Read(**/secrets/**)", "Read(~/.ssh/**)"]。直接阻止这些读取。
🚀 高风险操作始终确认
ask: ["Bash(git push *)", "Bash(rm *)"]。即使在 auto 模式下也会强制询问。
⚡ 自动化日常工作
allow: ["Bash(npm run *)", "Bash(git commit *)"]。测试/构建/提交不被打断地运行。
通过 Bash 参数模式来限制 URL 是脆弱的(curl http://github.com/ * 很容易被 -X GET 或变量展开绕过)。应改为 deny curl/wget,并用 WebFetch(domain:...) 允许特定域名。如需更严格的控制,可在 PreToolUse 钩子中校验 URL。
6. 易错点与常见混淆
- deny 由 Claude Code 强制执行,而非模型。在提示词或 CLAUDE.md 中写「别读这个」,如果没有规则是拦不住的。
- Read/Edit 的 deny 无法阻止间接访问。它适用于内置文件工具以及
cat/head/sed,但不适用于自行打开文件的 Python 或 Node 脚本。要做到操作系统层面的强制约束,还需结合沙箱(sandboxing)。 - 留意环境运行器。
devbox run *、npx和docker exec会把它们的参数当作命令来运行,所以Bash(devbox run *)也会允许devbox run rm -rf .。请编写包含内层命令的规则。 - 钩子无法覆盖规则。PreToolUse 钩子可以扩展权限,但无论钩子返回什么,deny/ask 都会照常评估(deny 优先的原则不变)。
※ 本文行为依据 Claude Code 官方文档(Configure permissions / Settings),截至 2026 年 6 月。该行为可能变更,请以官方文档的最新内容为准。
总结
关于 Claude Code 权限规则的三个要点。
- 它是什么:在
settings.json中用 allow/ask/deny 针对每个工具、命令、文件和域名进行授予/询问/禁止。模式设定基线;规则处理具体细节。 - 优先级:deny → ask → allow(先匹配者胜;具体程度无关紧要)。任何层级的 deny 都始终获胜。层级:托管 > CLI > 本地 > 项目 > 用户。
- 语法:
Tool(specifier)。Bash 使用通配符(空格 + * 是单词边界),Read/Edit 使用 gitignore 风格路径,WebFetch 使用 domain:。复合命令需要每个子命令都匹配。
「可靠地禁止危险操作,自动化安全的日常操作」是规则设计的核心。将它与权限模式、钩子以及 effort 设置结合,就能安全又顺畅地运行 Claude Code。
FAQ
Q. 权限规则和模式有什么不同?
A. 模式是宽泛的确认基线(default/acceptEdits/auto 等);规则是针对每个工具、每条命令的具体指定。二者协同工作,规则会覆盖模式(例如在 auto 模式下,ask/deny 规则仍然生效)。
Q. 我已经 allow 了——为什么还是会询问?
A. 因为评估顺序是 deny → ask → allow。如果有另一条 ask(或 deny)也匹配这次调用,它就会获胜,即使存在更具体的 allow 也一样。具体程度不会改变这个顺序。
Q. settings.json 应该放在哪里?
A. 团队共享:.claude/settings.json(已提交)。个人:.claude/settings.local.json(已 gitignore)。跨所有项目:~/.claude/settings.json。如需组织范围的强制约束,请使用托管设置(无法被覆盖)。
Q. 如何确保 .env 永远不会被读取?
A. 设置 deny: ["Read(.env)", "Read(**/secrets/**)"]。注意这适用于内置文件工具和 cat 类命令,但不适用于通过脚本进行的间接读取。要做到操作系统层面的强制约束,还需同时启用沙箱。
Q. 可以通过 Bash 参数来限制 URL 或文件吗?
A. 不可靠。curl http://github.com/ * 很容易被选项或变量展开绕过。要限制 URL,请 deny curl/wget 并使用 WebFetch(domain:...),或在 PreToolUse 钩子中校验。