Mindket
Claude Code 进阶课第 1 节,共 4 节

Claude Code settings.json:作用域、优先级和权限规则

黑色横幅,标题是“Claude Code 进阶”,下面一行是“设置、无头运行、CI 与 Agent SDK”。

Claude Code 从四个地方读取设置:托管策略、你自己的 ~/.claude/settings.json、提交进仓库的 .claude/settings.json,以及不入库的 .claude/settings.local.json。--settings 参数只在单次会话里多加一层。优先级依次是托管、参数、本地、项目、用户。permissions.allow 这类列表会合并,deny 规则先于 ask,ask 又先于 allow。

本节内容

  • 同一个键出现在多个文件里,按同一套顺序决出胜负:托管,然后是 --settings,再到本地、项目和用户。permissions.allow 这类列表键是合并,不是覆盖。
  • 规则先查 deny,再查 ask,最后查 allow,第一个命中的说了算。再窄的 allow 也没法在宽泛的 deny 里挖出例外。
  • 提交进仓库的 allow 规则,要等每位队友信任这个文件夹之后才生效。deny 和 ask 规则立刻生效。
  • Bash 规则匹配的是 Claude 写出来的命令文本,只能约束习惯,不是安全边界。要配合沙箱或 hook 一起用。
全部课程
本页目录
  1. 开始之前
  2. 搭一个团队文件和一个个人覆盖文件
  3. 文件之间冲突时听谁的
  4. 先 deny,再 ask,最后 allow
  5. 路径规则和它的锚点
  6. deny 规则拦不住什么
  7. 和团队共享文件:信任,以及永远传不过去的键
  8. Claude Code 的作者怎样和团队共享权限规则
  9. 常见错误
  10. 动手试试
  11. 下一课:无头运行
  12. 自测一下
  13. 常见问题
  14. 资料来源

开始之前

这一课写给已经每天都在用 Claude Code 的人。如果还没有,先学入门课。你需要一个 git 仓库,用来试共享文件和本地文件。

Anthropic 的文档把好几处行为和具体版本绑在了一起。本地设置文件自 v2.1.211 起放在仓库根目录,而 bypassPermissions 自 v2.1.257 起不再从项目文件里生效。如果下面的内容和你的安装对不上,先运行 claude --version。以下事实来自设置指南和权限页面,两页在本课更新时都重新核对过。

Claude Code 差不多每天发一个版本,设置相关的改动来得比别处更勤。下面四个版本改变了设置文件能做的事,日期取自 GitHub 和更新日志。

近期 Claude Code 版本里和设置有关的改动
  1. v2.1.211:批准存到仓库根目录

    “总是允许”的规则写进根目录的本地文件,在 git worktree 里开的会话也能沿用。

    来源:Claude Code release v2.1.211 on GitHub (2026年11月5日 查阅)

  2. v2.1.257:绕过模式不再从项目文件生效

    项目或本地文件里的 defaultMode: "bypassPermissions" 会被忽略,和此前的 auto 一样。

    来源:Claude Code release v2.1.257 on GitHub (2026年11月5日 查阅)

  3. v2.1.314:禁止写到项目之外

    permissions.blockWritesOutsideWorkingDirectories 让 Write、Edit 和 NotebookEdit 在任何模式下都拒绝工作目录之外的路径。

    来源:Claude Code changelog (2026年11月5日 查阅)

  4. 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/**)"
    ]
  }
}
  1. 把这段保存为仓库顶层的 .claude/settings.json 并提交。Claude Code 从会话的主工作目录读取共享文件,所以要在仓库根目录启动 claude。
  2. 新建 .claude/settings.local.json,放你自己的例外。Claude Code 自己写出的这个文件会被它排除在 git 之外。如果是你手工新建的,就自己把它加进 .gitignore。
  3. 在本地文件里设置一个团队文件也设了的键。本地层高于共享项目层,所以只有你自己的会话会变。{"spinnerTipsEnabled": false} 只会替你关掉旋转图标下面的提示。
  4. 运行 /status。Setting sources 这一行列出 Claude Code 加载的每个文件,比如 User settings 或 Project local settings。它只说明读了哪些文件,不说明某个键来自哪个文件。
  5. 运行 /permissions,列出每条规则和它所在的文件。运行 claude doctor,列出 Claude Code 拒收的条目。
  6. 会话运行时改一条规则。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 里的同名变量。

设置的优先级,从高到低,来自 Anthropic 的设置指南
层级来源作用范围
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 执行,而不是由模型执行。

Anthropic, Claude Code 官方文档(此处为中文译文) · Claude Code 文档:配置权限 (2026年11月4日 查阅)
{
  "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 规则之前就拦下调用。

deny 或 ask 里的规则,以及绕得过它们的写法,来自权限页面
规则拦得住拦不住
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 maingit -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,让团队也一起受益。

Boris Cherny, Claude Code 的作者,就职于 Anthropic,引文为译文 · X (2026年11月5日 查阅)
Boris Cherny(@bcherny)2026 年 2 月 11 日在 X 上发的第 12 条技巧:Claude Code 开箱就好用;要自定义的话,就把 settings.json 提交进 git,让团队一起受益;可以按代码库、子文件夹、只对自己或在全企业范围配置
Boris Cherny 在 X 上,2026 年 2 月 11 日

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 文件,设置替代不了它。

自测一下

  1. 你的用户设置 deny 了 Bash(npm run deploy *),提交的项目文件 allow 了 Bash(npm run *)。npm run deploy prod 会怎样?

    查看答案

    B. 会被拦下,因为任何作用域里的 deny 都压过 allow Claude Code 跨所有作用域先查 deny,再查 ask,最后查 allow,第一个命中的说了算。

  2. 哪个文件放你自己在一个项目里的覆盖设置,并且不进 git?

    查看答案

    C. .claude/settings.local.json 项目本地设置只对你自己在一个项目里生效,在优先级顺序里高于共享的项目文件。

  3. 你把 "defaultMode": "auto" 提交进了 .claude/settings.json。队友们会得到什么?

    查看答案

    A. 什么也没有,因为 auto 不会从项目或本地设置里生效 auto 和 bypassPermissions 这两个值只从用户或托管设置里生效,或者单次会话用 --permission-mode。

  4. 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 里看到这份策略。

资料来源

  1. Claude Code docs: Settings files and precedence (2026年11月5日 查阅)https://code.claude.com/docs/en/settings
  2. Claude Code docs: Configure permissions (2026年11月5日 查阅)https://code.claude.com/docs/en/permissions
  3. Claude Code docs: Example settings files (2026年11月4日 查阅)https://code.claude.com/docs/en/settings-example
  4. Claude Code docs: Settings reference (2026年11月4日 查阅)https://code.claude.com/docs/en/settings-reference
  5. Claude Code release v2.1.211 on GitHub (2026年11月5日 查阅)https://github.com/anthropics/claude-code/releases/tag/v2.1.211
  6. Claude Code release v2.1.257 on GitHub (2026年11月5日 查阅)https://github.com/anthropics/claude-code/releases/tag/v2.1.257
  7. Claude Code changelog (2026年11月5日 查阅)https://code.claude.com/docs/en/changelog
  8. Boris Cherny on X: pre-approve common permissions (2026年11月5日 查阅)https://x.com/bcherny/status/2021700332292911228
  9. Boris Cherny on X: customize all the things (2026年11月5日 查阅)https://x.com/bcherny/status/2021701636075458648

分享本节课

为 Claude Code 做的工具包

Mindket 的工具包是一个由纯文本文件组成的压缩包,解压进项目就能用。来看看为 Claude Code 做的那些。

浏览工具包

本节课的 Markdown 版本 · Claude Code 进阶课 · 全部课程