
大多数人只知道 Claude Code 有个 settings.json,但背后是一套「配置层次体系」——四层作用域(Managed/User/Project/Local)决定「谁的配置」,优先级链决定「谁覆盖谁」,数组合并规则决定「权限规则如何叠加」,热重载边界决定「什么时候需要重启」。本篇完整拆解这套体系,覆盖 permissions/env/apiKeyHelper/sandbox 等核心字段、企业 MDM 受控部署、drop-in 目录管理,并附五条可落地的实践建议。
settings.json,但不知道它背后是一套「配置层次体系」——你在哪里写的配置、用什么格式写,决定了这段配置影响谁、能否被覆盖、以及改完是否需要重启。| 作用域 | 文件位置 | 影响范围 | 能否共享团队 |
|---|---|---|---|
| Managed | 系统目录 / MDM / 注册表 | 机器上所有用户 | 由 IT 部署 |
| User | ~/.claude/settings.json | 你的所有项目 | 不共享(个人) |
| Project | .claude/settings.json | 该仓库所有协作者 | 提交 git 后共享 |
| Local | .claude/settings.local.json | 仅你在该仓库中 | 不共享(自动加入 .gitignore) |
settings.json,作用域概念还覆盖 Subagents(agents/)、CLAUDE.md、MCP 服务(.mcp.json)和 Plugins——它们的文件位置与 settings 遵循相同的 User/Project/Local 三层结构1。defaultMode 设成 acceptEdits,Project 层把它设成 default,最终生效的是 Project 的值。defaultMode 设成 acceptEdits,Project 层把它设成 default,最终生效的是 Project 的值。permissions(allow/deny 规则)不走「覆盖」逻辑,而是跨层合并——所有层的 allow 规则汇总在一起生效,deny 规则同理。这意味着 Managed 层定的 deny 规则无法被 Project 层的 allow 规则撤销1。sandbox.filesystem.allowWrite、permissions.allow)同样是拼接去重而非替换——低优先级层可以往里追加条目,但无法删掉高优先级层已经设的条目。/status,Status 标签下的 Setting sources 行会列出当前 session 加载了哪些来源(User settings / Project local settings / Enterprise managed settings (remote) 等)。来源列表里只显示「至少有一个键」的层,空文件不会出现1。settings.json 就能在 VS Code 和 Cursor 里得到自动补全1:
settings.json,加上 $schema 后可直接获得字段自动补全。{
"$schema": "https://json.schemastore.org/claude-code-settings.json"
}{
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)",
"Read(~/.zshrc)"
],
"deny": [
"Bash(curl *)",
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
]
}
}工具名 或 工具名(修饰符)。评估顺序是 deny 先于 ask 先于 allow,第一条匹配即生效——这与 #12 讲过的五步评估链一致。permissions.defaultMode 可以设成 acceptEdits、plan、auto、dontAsk 等,但有一个重要限制:auto 模式若设在项目级或本地设置(.claude/settings.json 或 settings.local.json)里,从 v2.1.142 起会被忽略——防止某个仓库给自己授权 auto 模式1。{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp"
}
}env 里的变量会应用到每个 session 以及 Claude Code 启动的所有子进程。一个实用的技巧:把 DISABLE_AUTOUPDATER=1 放在这里,就能关闭自动更新;把 ANTHROPIC_MODEL=claude-haiku-3 放在 User 层,就能为所有项目设置默认模型1。{
"model": "claude-sonnet-4-6",
"autoUpdatesChannel": "stable",
"minimumVersion": "2.1.100"
}model:覆盖默认模型,但 --model 命令行参数和 ANTHROPIC_MODEL 环境变量优先级更高,只影响单次 sessionautoUpdatesChannel:"latest"(默认)跟踪最新版,"stable" 跟踪约滞后一周的稳定版,后者跳过有重大回退的版本minimumVersion:防止自动更新把版本降到某个基线以下;requiredMinimumVersion 是更强的版本:低于该版本时 Claude Code 直接拒绝启动{
"apiKeyHelper": "/bin/generate_temp_api_key.sh"
}/bin/sh 执行,输出值会以 X-Api-Key 和 Authorization: Bearer 头发送1。刷新间隔通过 env 里的 CLAUDE_CODE_API_KEY_HELPER_TTL_MS 配置。model:可用 /model 命令在 session 内切换,不需要改配置文件outputStyle:属于 System Prompt 的一部分,需要 /clear 或重启后重新构建ConfigChange Hook,可以借此做自动化响应(比如通知 CI 流水线配置已变更)。/Library/Application Support/ClaudeCode/managed-settings.json/etc/claude-code/managed-settings.jsonC:\Program Files\ClaudeCode\managed-settings.json.plist 配置 profileHKLM\SOFTWARE\Policies\ClaudeCodemanaged-settings.d/):多团队可以各自维护独立的配置片段文件,以字母顺序合并,不需要协调编辑同一个文件。惯例上用数字前缀控制合并顺序,例如 10-telemetry.json、20-security.json。| 字段 | 用途 |
|---|---|
allowManagedPermissionRulesOnly | 禁止 User/Project 层定义自己的 allow/deny 规则 |
forceLoginMethod | 强制只允许 claudeai 或 console 账号登录 |
forceLoginOrgUUID | 强制登录账号必须属于指定的组织 UUID |
requiredMinimumVersion | 低于该版本拒绝启动 |
requiredMaximumVersion | 高于该版本拒绝启动(控制版本上限) |
claudeMd | 向所有用户注入组织级 CLAUDE.md 指令 |
disableBypassPermissionsMode | 禁止任何人开启 bypassPermissions 模式 |
forceRemoteSettingsRefresh: true 是一个「fail-closed」字段:启动时必须从服务器拉到最新托管配置,拉取失败则直接退出,不以缓存或本地配置启动——适合对合规要求严格的场景1。
{
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": true,
"excludedCommands": ["docker *"],
"filesystem": {
"allowWrite": ["/tmp/build", "~/.kube"],
"denyRead": ["~/.aws/credentials"]
},
"network": {
"allowedDomains": ["github.com", "*.npmjs.org"],
"deniedDomains": ["uploads.github.com"],
"allowLocalBinding": true
}
}
}permissions 里的 Read/Edit/WebFetch 规则是互补关系——两套规则都会被合并到最终的沙箱边界里1。/ 开头是绝对路径,~/ 开头相对 home 目录,./ 或无前缀相对项目根目录(在 project settings 里)或 ~/.claude(在 user settings 里)。$schema 再开始填字段"$schema": "https://json.schemastore.org/claude-code-settings.json" 加在所有 settings.json 的第一行,编辑器自动补全和校验开箱即用。Schema 更新可能滞后于 CLI 发布,校验报警不一定代表字段无效。permissions.deny(禁止读 .env、禁止执行 curl *)、hooks、enabledMcpjsonServers 放进 .claude/settings.json(提交到 git);把自己的 editorMode: "vim"、preferredNotifChannel: "iterm2" 放进 ~/.claude/settings.json。Local 文件 settings.local.json 留给临时实验,改完再决定要不要提交。/status 而不是猜测/status 查看 Setting sources 行——它列出了当前 session 加载了哪些层,比手动检查文件路径更可靠。apiKeyHelper 是动态鉴权的正确姿势settings.json。用 apiKeyHelper 指向一个动态生成脚本,配合 CLAUDE_CODE_API_KEY_HELPER_TTL_MS 设置刷新间隔。这个字段支持热重载,更新脚本不需要重启 session。managed-settings.json。用 managed-settings.d/ 目录,每个团队维护自己的 10-team-a.json、20-team-b.json,按字母顺序自动合并,标量值后来者覆盖,数组拼接去重,互不干扰。docs.anthropic.com
This story was produced automatically by a channel. One sentence is all it takes for Neodrop to keep producing for you.