开始之前
这一课写给已经每天都在用 Claude Code 的人。如果还没有,先学入门课。你需要一个 git 仓库,用来试共享文件和本地文件。
Anthropic 的文档把好几处行为和具体版本绑在了一起。本地设置文件自 v2.1.211 起放在仓库根目录,而 bypassPermissions 自 v2.1.257 起不再从项目文件里生效。如果下面的内容和你的安装对不上,先运行 claude --version。以下事实来自设置指南和权限页面,两页在本课更新时都重新核对过。
Claude Code 差不多每天发一个版本,设置相关的改动来得比别处更勤。下面四个版本改变了设置文件能做的事,日期取自 GitHub 和更新日志。
v2.1.211:批准存到仓库根目录
“总是允许”的规则写进根目录的本地文件,在 git worktree 里开的会话也能沿用。
来源:Claude Code release v2.1.211 on GitHub (2026年11月5日 查阅)
v2.1.257:绕过模式不再从项目文件生效
项目或本地文件里的
defaultMode: "bypassPermissions"会被忽略,和此前的auto一样。来源:Claude Code release v2.1.257 on GitHub (2026年11月5日 查阅)
v2.1.314:禁止写到项目之外
permissions.blockWritesOutsideWorkingDirectories让 Write、Edit 和 NotebookEdit 在任何模式下都拒绝工作目录之外的路径。来源:Claude Code changelog (2026年11月5日 查阅)
v2.1.318:/permissions 统一用标准对话框
规则详情和删除确认都在标准对话框里打开,在那里连按两次 Ctrl+C 是返回,而不是退出。
来源:Claude Code changelog (2026年11月5日 查阅)
搭一个团队文件和一个个人覆盖文件
一个提交进仓库的团队文件,加一个只属于你的不入库文件,能覆盖大多数项目。下面这段是 Anthropic 示例团队文件里的 permissions 部分,外加一行 schema,让编辑器有自动补全和校验。
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(npm run *)"
],
"ask": [
"Bash(git push *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
]
}
}- 把这段保存为仓库顶层的
.claude/settings.json并提交。Claude Code 从会话的主工作目录读取共享文件,所以要在仓库根目录启动claude。 - 新建
.claude/settings.local.json,放你自己的例外。Claude Code 自己写出的这个文件会被它排除在 git 之外。如果是你手工新建的,就自己把它加进.gitignore。 - 在本地文件里设置一个团队文件也设了的键。本地层高于共享项目层,所以只有你自己的会话会变。
{"spinnerTipsEnabled": false}只会替你关掉旋转图标下面的提示。 - 运行
/status。Setting sources这一行列出 Claude Code 加载的每个文件,比如User settings或Project local settings。它只说明读了哪些文件,不说明某个键来自哪个文件。 - 运行
/permissions,列出每条规则和它所在的文件。运行claude doctor,列出 Claude Code 拒收的条目。 - 会话运行时改一条规则。Claude Code 会监视这些文件,大多数改动包括
permissions和hooks不用重启就会生效。
文件之间冲突时听谁的
Claude Code 取设置了这个键的最高一层的值。托管设置在最上面,连 --settings 都压不过它,你自己的文件里没有任何东西能覆盖托管的键。
列表是“赢家通吃”的例外。permissions.allow 出现在多个文件里时,Claude Code 把它们合并,每个文件只会添加条目,不会删掉别的文件的条目。四个和模型有关的键有自己的规则:fallbackModel、modelPicker、availableModels 和 modelSettings。
环境变量不算一层。某个行为既有环境变量又有设置键时,由这一对自己决定。你在 shell 里导出的 ANTHROPIC_MODEL 压过任何文件里的 model 键,而 ANTHROPIC_DEFAULT_MODEL 只有在没有文件设置 model 时才起作用。设置文件里的 env 块是普通的键,按下表的顺序决胜负,它里面的值会覆盖 shell 里的同名变量。
| 层级 | 来源 | 作用范围 |
|---|---|---|
| 1 | 托管:managed-settings.json、MDM 策略或服务器托管设置 | 你的组织部署到的所有人 |
| 2 | 命令行:--settings,后面跟内联 JSON 或文件路径 | 单次会话,不会写入磁盘 |
| 3 | 项目本地:.claude/settings.local.json | 你自己,在一个项目里 |
| 4 | 共享项目:.claude/settings.json | 克隆这个仓库的所有人 |
| 5 | 用户:~/.claude/settings.json | 你自己,在这台机器的所有项目里 |
先 deny,再 ask,最后 allow
Claude Code 先检查 deny 规则,再检查 ask,最后检查 allow。第一个命中的就是结果,更窄的规则不会因为更窄而胜出。Bash(aws *) 放在 deny 里,就算有一条 allow 规则点名放行 aws s3 ls,这条命令照样被拦下。任何一个作用域里的 deny,都压过其他作用域里的 allow,不分方向。
下面的配置让 npm 脚本和提交不用询问,同时拒绝 git push。规则也不只管 Bash。mcp__puppeteer__* 匹配某个 MCP 服务器的所有工具,把 Agent(Explore) 放进 deny,就能关掉一个子智能体。
权限规则由 Claude Code 执行,而不是由模型执行。
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git commit *)"
],
"deny": [
"Bash(git push *)"
]
}
}*要放在子命令后面。Bash(git log *)只放行git log命令,而Bash(git *)放行所有 git 命令。如果 allow 规则在子命令前面就有*,比如Bash(git * main),Claude Code 启动时会发出警告。- 末尾带空格的
*也能匹配光秃秃的命令本身,所以Bash(ls *)能匹配ls。空格很重要:Bash(ls*)连lsof也会匹配。 - 复合命令要求每一段都被放行。
Bash(safe-cmd *)不会批准safe-cmd && other-cmd,而只要有一段命中,deny 或 ask 规则就会触发。 - Claude Code 匹配之前会剥掉一组固定的包装命令,比如
timeout、time、nice和nohup。npx、docker exec、devbox run这类运行器不在其中,所以devbox run *这条规则会放行run后面的任何内容。
路径规则和它的锚点
Read 和 Edit 规则用的是 gitignore 语法,开头的斜杠最容易绊倒人。单个斜杠不是绝对路径。以 / 开头的规则锚定在设置来源上,所以你用户设置里的 /secrets 规则拦的是 ~/.claude 下面的 secrets 文件夹,项目里的那个反而没管。下面的代码块列出四种锚点,例子都是 Anthropic 给的。
匹配深度还取决于规则类型。像 src 这样只有一段的目录写法,作为 allow 规则只覆盖当前目录下的 src 文件夹,作为 deny 或 ask 规则则匹配任意深度里同名的文件夹。想让 allow 匹配任意深度的某个名字,就让模式以双星号开头,就像代码块最后一行那样。
//path Read(//Users/alice/secrets/**) absolute path from the filesystem root
~/path Read(~/Documents/*.pdf) from your home directory
/path Edit(/src/**/*.ts) under the primary working directory, in project settings
path Read(*.env) relative to the current directory
allow Edit(src/**) only the src folder under the current directory
deny Read(secrets/**) a secrets folder at any depth
any Edit(**/src/**) a src folder at any depth给 Write、NotebookEdit 或 Glob 写的路径规则会被接受,但永远匹配不上。请用 Edit 规则代替 Write,用 Read 规则代替 Glob。
deny 规则拦不住什么
Bash 规则匹配的是 Claude 写出的命令文本,而且是在 Claude Code 拆开复合命令、剥掉包装命令之后。同一个程序换一种调用方式,就是另一个字符串,所以规则只管常见的写法,别的一概不管。Anthropic 的表格给了三个例子。
文件也有同样的缺口。Read(./.env) 拦得住 cat .env 和文件工具,却拦不住在目录上运行的 grep -r,也拦不住自己打开文件的脚本。需要限制真正生效时,权限页面指向两样东西。沙箱在操作系统层面执行文件系统和网络限制,PreToolUse hook 则能检查完整的命令,做法见 hooks 一课。退出码为 2 的 hook 会在读取任何 allow 规则之前就拦下调用。
| 规则 | 拦得住 | 拦不住 |
|---|---|---|
Bash(curl *) | curl https://example.com | /usr/bin/curl https://example.com 和 sh -c 'curl https://example.com' |
Bash(rm *) | rm -rf build/ | /bin/rm -rf build/ 和 bash -c 'rm -rf build/' |
Bash(git push *) | git push origin main | git -C . push origin main 和 git 'push' origin main |
和团队共享文件:信任,以及永远传不过去的键
提交进仓库的文件自己没法授予能力。.claude/settings.json 里的 permissions.allow 和 permissions.additionalDirectories,要等每位队友接受该文件夹的工作区信任对话框之后才生效。deny 和 ask 规则立刻生效,因为它们只做限制。我们会先往提交的文件里写保护机密文件的 deny,再写图方便的 allow,因为 deny 从第一次会话起就在保护你。
非交互式运行会跳过这个对话框。claude -p 和 SDK 会话从不显示它,所以项目里的 allow 规则不会被使用,Claude Code 还会向 stderr 打印一条 this workspace has not been trusted 警告。仓库里的 hook 和 env 块照样会运行。在一个不是你写的仓库里运行 claude -p 之前,先传 --setting-sources user,或者用 --bare 启动,下一课会讲它。
还有一些键,无论如何都不会从仓库文件里生效。
permissions.defaultMode设为auto或bypassPermissions。请把它放进用户设置,或者单次会话传--permission-mode。env块里的 OpenTelemetry 导出器变量,只有少数用来关闭遥测的值例外。请放进托管设置或用户设置。- 设置参考里 Scope 一栏写着
User、User or managed、User, local, or managed、Managed或Global config的任何键。
Claude Code 的作者怎样和团队共享权限规则
Boris Cherny 是 Claude Code 的作者,在 Anthropic 做 Claude。他在 X 上发过一串自定义技巧。
第 5 条从默认值讲起:Claude Code 开箱只预先放行一小组安全命令,想放行更多就用 /permissions 加进去,再把这些规则写进团队的 settings.json。他举的例子是一条放行 bun run 的 Bash 规则和一条针对 docs 文件夹的 Edit 规则,用的都是这一课的通配写法。那条 Edit 规则以斜杠开头,写在团队文件里就锚定在项目上,贴进你的用户文件则会指向 ~/.claude/docs。
五分钟后,第 12 条把同样的话推广到所有设置。他当天数出 37 个设置项和 84 个环境变量,还建议用 env 字段代替包装脚本。这两个数字只是 2 月的快照,今天的完整列表请看设置参考。
每次选“Yes, and don't ask again”,都会往 .claude/settings.local.json 里多写一条规则,你自己的批准就这样越积越多。用上一周后打开 /permissions,把全队都会批准的那几条挪进共享文件,再提交。
要自定义的话,就把你的 settings.json 提交进 git,让团队也一起受益。
X 官方嵌入卡片的截图,拍摄于 2026 年 11 月 5 日,时间为 UTC。X 用“Show more”截断了这条帖子。点击截图可到 X 上打开原帖。
常见错误
- 设置文件里多了结尾逗号,或者写了
//注释。这些文件是严格的 JSON,下次启动时 Claude Code 会显示 Settings Error。-p运行不显示对话框,直接跳过损坏的文件,所以某次运行忽略了设置后,要运行claude doctor。 - 想在 deny 里挖出一个例外。allow 规则没法重新打开 deny 拦住的东西。要改的是把 deny 写窄。
- 把
/status当成每个键的溯源工具。它列的是已加载的文件,不是每个值背后的文件。要看规则来自哪里,用/permissions。 - 照 Windows 的习惯写路径。Claude Code 匹配前会把
C:\Users\alice规范成/c/Users/alice,所以针对那个盘的规则要以//c/开头。 - 以为“Yes, and don't ask again”能压过项目规则。这个选项把一条 allow 规则存进你的本地文件,而那里的 allow 压不过项目或托管文件里的 ask 规则。
动手试试
- 把
Read(./.env)加进项目文件的 deny 列表,让 Claude 去读.env,然后打开/permissions,找到这条规则所在的文件。 - 在团队文件的 ask 里放
Bash(git push *),在你本地文件的 allow 里放同一条规则。先预测 Claude Code 会不会询问,再让它去 push 并核对。 - 在你的用户文件里把
spinnerTipsEnabled设为false,然后用claude --settings '{"spinnerTipsEnabled": true}'启动一次会话。提示只在这一次会话里回来。 - 先运行
/status,再运行claude doctor,写下每一个能告诉你、另一个却不能告诉你的信息。
下一课:无头运行
设置决定一次会话能做什么。下一课无头运行里,claude -p 在没有人回答提示的情况下运行,这一课的规则就成了全部的安全模型。
前面一课讲过的 hooks,会在会话的固定节点运行你自己的命令。长期有效的说明仍然应该放进 CLAUDE.md 文件,设置替代不了它。
自测一下
你的用户设置 deny 了 Bash(npm run deploy *),提交的项目文件 allow 了 Bash(npm run *)。npm run deploy prod 会怎样?
查看答案
B. 会被拦下,因为任何作用域里的 deny 都压过 allow Claude Code 跨所有作用域先查 deny,再查 ask,最后查 allow,第一个命中的说了算。
哪个文件放你自己在一个项目里的覆盖设置,并且不进 git?
查看答案
C. .claude/settings.local.json 项目本地设置只对你自己在一个项目里生效,在优先级顺序里高于共享的项目文件。
你把 "defaultMode": "auto" 提交进了 .claude/settings.json。队友们会得到什么?
查看答案
A. 什么也没有,因为 auto 不会从项目或本地设置里生效 auto 和 bypassPermissions 这两个值只从用户或托管设置里生效,或者单次会话用 --permission-mode。
Claude 运行的是 /usr/bin/curl 而不是 curl 时,哪一种保护仍然有效?
查看答案
C. 沙箱的网络允许名单 Bash 规则匹配的是命令的字面文本,而沙箱在操作系统层面限制网络访问,不管命令长什么样。
常见问题
Claude Code 的 settings.json 在哪里?
有四个来源:~/.claude/settings.json 对你自己在所有项目里生效,.claude/settings.json 随项目提交,.claude/settings.local.json 只对你自己在一个项目里生效,另外还有你的组织部署的托管文件或策略。安装 Claude Code 时一个都不会创建。在 Windows 上,~/.claude 指的是 %USERPROFILE%\.claude。
点了“Yes, and don't ask again”,我的选择保存在哪里?
保存在 .claude/settings.local.json 里,以 allow 规则的形式。这个批准只属于你自己,优先级高于共享文件。这个文件由 Claude Code 创建时,会被排除在 git 之外。
怎样阻止 Claude Code 读取我的 .env 文件?
把 Read(./.env) 和 Read(./.env.*) 加进 permissions.deny。Claude Code 随后会把匹配的文件排除在文件发现和搜索之外,并拦下这些路径上的 Edit 和 Write。不点名文件的命令,比如在文件夹上运行的 grep -r,仍然能读到,所以文件必须保持不可读时,要开启沙箱。
为什么我的权限规则被忽略了?
先运行 /status。常见原因有:更高一层设置了同一个键,项目里的 allow 规则还在等工作区信任,项目文件里写了 auto 或 bypassPermissions,某个无效条目被 Claude Code 跳过了,以及 Write 或 Glob 的路径规则永远匹配不上。claude doctor 会列出它拒收的内容。
改了设置之后需要重启 Claude Code 吗?
通常不需要。用户、项目、本地和托管文件一有改动,Claude Code 就会重新加载,包括 permissions、hooks 和凭据助手。少数键只在会话启动时加载一次。会话中途删掉 permissions.blockReadsOutsideWorkingDirectories 后,拦截仍然保留,要重启每个会话才会解除。
能给整个项目设定权限模式吗?
default、acceptEdits、plan 和 dontAsk 可以,写在 .claude/settings.json 的 permissions.defaultMode 里。auto 和 bypassPermissions 只从用户或托管设置里生效,或者单次会话用 --permission-mode。
管理员能不能不让开发者改这些设置?
能。托管设置高于所有其他层级,allowManagedPermissionRulesOnly 会让它成为权限规则的唯一来源。把 permissions.disableBypassPermissionsMode 设为 "disable" 可以取消绕过模式,开发者可以在 /status 里看到这份策略。
资料来源
- Claude Code docs: Settings files and precedence https://code.claude.com/docs/en/settings
- Claude Code docs: Configure permissions https://code.claude.com/docs/en/permissions
- Claude Code docs: Example settings files https://code.claude.com/docs/en/settings-example
- Claude Code docs: Settings reference https://code.claude.com/docs/en/settings-reference
- Claude Code release v2.1.211 on GitHub https://github.com/anthropics/claude-code/releases/tag/v2.1.211
- Claude Code release v2.1.257 on GitHub https://github.com/anthropics/claude-code/releases/tag/v2.1.257
- Claude Code changelog https://code.claude.com/docs/en/changelog
- Boris Cherny on X: pre-approve common permissions https://x.com/bcherny/status/2021700332292911228
- Boris Cherny on X: customize all the things https://x.com/bcherny/status/2021701636075458648

