前言:为什么 Settings 配置决定了你的 Claude Code 体验上限
很多人装完 Claude Code 就直接开干,遇到权限弹窗就一路点"Yes",直到某天它把 .env 文件内容泄露到对话里,或者在一个团队仓库里执行了 rm -rf 误删了同事的代码。问题不在于 Claude Code 不安全,而在于你没有花十分钟配置 settings.json。
settings.json 是 Claude Code 的控制中枢。它决定三件事:Claude 能做什么(权限管理)、它在什么环境下工作(环境变量)、团队里每个人是否遵循同一套规范(共享配置)。这篇文章会从零开始,带你走完一遍完整的配置流程,所有代码示例都可以直接复制到你的项目中运行。
一、settings.json 完整配置详解
1.1 配置文件存放在哪里?四级作用域速查
Claude Code 使用分层作用域系统,同一配置可以出现在不同位置,优先级从高到低如下:
| 作用域 | 文件位置 | 影响范围 | 是否随 Git 共享 |
|---|---|---|---|
| Managed(企业托管) | managed-settings.json / MDM / 注册表 |
全组织 / 全机器 | 由 IT 部署 |
| Local(本地私有) | .claude/settings.local.json |
当前仓库的你自己 | 否(自动 gitignore) |
| Project(项目共享) | .claude/settings.json |
仓库所有协作者 | 是(提交到 Git) |
| User(用户全局) | ~/.claude/settings.json |
你的所有项目 | 否 |
核心原则:Managed 优先级最高且不可被覆盖;Local 覆盖 Project;Project 覆盖 User。权限规则稍有不同——它们在各作用域间是"合并"而非"覆盖",但 deny 规则一旦在任意层级命中,任何 allow 都无法翻盘。
1.2 一个可直接使用的 settings.json 完整示例
下面是一份项目级 .claude/settings.json 的完整示例,涵盖了权限、环境变量、模型选择等常用配置项:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"model": "claude-sonnet-5",
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)",
"Bash(git commit -m *)",
"Bash(npx prettier *)",
"Bash(npx eslint *)",
"Bash(pnpm install)",
"Bash(pnpm test *)",
"Read(./src/**)",
"Read(./docs/**)",
"WebFetch(domain:docs.anthropic.com)"
],
"ask": [
"Bash(git push *)",
"Bash(npm publish *)",
"Bash(docker *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force *)",
"Read(.env)",
"Read(**/.env)",
"Read(**/.env.*)",
"Read(**/*.pem)",
"Read(**/secrets/**)",
"Read(./.ssh/**)",
"WebFetch(domain:internal.company.com)"
]
},
"env": {
"NODE_ENV": "development",
"CLAUDE_CODE_DISABLE_TELEMETRY": "1",
"MAX_THINKING_TOKENS": "10000"
},
"additionalDirectories": [
"../shared-components"
]
}
1.3 权限管理:allow / ask / deny 三类规则详解
权限是 settings.json 中最核心的部分,规则格式为 Tool 或 Tool(specifier):
- allow:匹配的工具调用自动放行,无需人工确认
- ask:每次使用都弹窗要求确认
- deny:直接阻止,Claude 根本看不到该工具或无法执行匹配的调用
评估顺序是 deny → ask → allow,第一个匹配的规则决定结果。这意味着一条宽泛的 deny 规则(如 Bash(rm *))会覆盖所有更具体的 allow 规则,因此 deny 规则不能带 allow 例外。
规则语法的关键细节:
{
"permissions": {
"allow": [
"Bash(npm run build)", // 精确匹配命令
"Bash(npm run test *)", // 通配符匹配前缀,注意空格:匹配 "npm run test" 但不匹配 "npm-run-test"
"Bash(git *)", // 匹配所有 git 子命令
"Read(./src/**)", // gitignore 风格路径匹配
"Read(~/.config/app/**)", // ~ 代表家目录
"WebFetch(domain:*.anthropic.com)", // 匹配所有子域名
"mcp__github__get_*" // 匹配 github MCP 服务器下所有 get_ 开头的工具
],
"deny": [
"Read(//**/.env)", // // 代表文件系统根,匹配任意位置的 .env
"Bash(curl *)", // 阻止所有 curl 调用
"mcp__*__*delete*" // 阻止所有 MCP 服务器中含 delete 的工具(仅 deny/ask 支持)
]
}
}
路径匹配的四种锚点形式:
| 格式 | 含义 | 示例 |
|---|---|---|
//path |
文件系统绝对路径 | Read(//Users/alice/secrets/**) |
~/path |
家目录相对路径 | Read(~/Documents/*.pdf) |
/path |
相对于配置文件所在目录 | Edit(/src/**/*.ts)(项目级即项目根的 src) |
path 或 ./path |
相对于当前工作目录 | Read(*.env) |
提示:`Read(.env)` 和 `Read(**/.env)` 是等价的,都匹配当前目录及子目录下任意深度的 `.env` 文件。
1.4 env 环境变量配置
env 字段定义的变量会注入到每个会话以及 Claude Code 衍生的子进程中。设置为空字符串 "" 可以覆盖 shell 中已导出的同名变量:
{
"env": {
"NODE_ENV": "development",
"MAX_THINKING_TOKENS": "10000",
"CLAUDE_CODE_DISABLE_TELEMETRY": "1",
"DISABLE_AUTO_COMPACT": "",
"MY_API_BASE": "https://api.staging.example.com"
}
}
常见环境变量速查:
| 变量名 | 作用 |
|---|---|
MAX_THINKING_TOKENS |
控制扩展思考的 token 预算,设为 0 可关闭思考 |
CLAUDE_CODE_DISABLE_TELEMETRY |
设为 1 关闭遥测 |
DISABLE_AUTO_COMPACT |
设为 1 关闭上下文自动压缩 |
ANTHROPIC_MODEL |
覆盖默认模型(单次会话) |
二、自定义命令与 Slash Commands 配置
2.1 Slash Commands 是什么
Slash Command 本质上就是一个 Markdown 文件。文件名变成命令名,文件内容变成注入会话的提示词。没有 DSL,没有编译步骤。两个关键位置:
- 项目命令:
.claude/commands/your-command.md→ 输入/your-command,随 Git 共享给团队 - 个人命令:
~/.claude/commands/your-command.md→ 在所有项目中可用,仅你自己可见
子目录会变成命名空间:.claude/commands/release/notes.md 对应 /release:notes。
2.2 创建你的第一个自定义命令
实操步骤——创建一个生成 PR 描述的命令:
# 第一步:在项目根目录创建 commands 文件夹
mkdir -p .claude/commands
# 第二步:创建命令文件
touch .claude/commands/pr.md
.claude/commands/pr.md 的完整内容:
---
description: 根据当前分支 diff 生成 PR 描述并创建 PR
argument-hint: <可选的 reviewer 用户名>
allowed-tools: Bash(git:*), Bash(gh:*)
model: claude-sonnet-5
---
你正在为当前分支创建 Pull Request。
1. 运行 `git status` 和 `git diff main...HEAD` 了解完整改动。
2. 如果分支尚未推送,用 `-u origin` 推送。
3. 撰写 70 字符以内的祈使句 PR 标题。
4. 撰写 PR 正文,包含三个部分:## 概要(1-3 条要点)、## 动机(一段话说明)、## 测试计划(清单)。
5. 用 `gh pr create` 创建 PR。如果 `$ARGUMENTS` 非空,用 `--reviewer` 添加审阅人。
6. 输出 PR 链接。
不要提交或推送到 main 分支。
在会话中输入 /pr alice,Claude 会把 alice 替换到 $ARGUMENTS 位置,然后执行整套流程。
2.3 Frontmatter 可用字段
| 字段 | 作用 |
|---|---|
description |
命令选择器中显示的说明文字 |
argument-hint |
输入框中显示的参数提示 |
allowed-tools |
命令可调用的工具白名单,免确认 |
model |
为该命令指定模型,如把机械工作路由到 Haiku 省成本 |
安全提醒:永远不要在命令正文中硬编码 API 密钥。`.claude/commands/` 会提交到 Git,密钥应放在环境变量中,在命令内通过 `Bash` 调用引用。
三、团队协作:共享配置与个人配置的最佳实践
3.1 项目级 vs 用户级配置对比
理解两者的分工是团队协作的基础:
// ========== 项目级 .claude/settings.json(提交到 Git,团队共享)==========
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(pnpm install)",
"Bash(pnpm test *)",
"Bash(pnpm run lint *)",
"Bash(git status)",
"Bash(git log *)"
],
"deny": [
"Bash(rm -rf *)",
"Read(.env)",
"Read(**/.env)"
]
},
"env": {
"NODE_ENV": "development"
}
}
// ========== 用户级 ~/.claude/settings.json(不共享,个人偏好)==========
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"theme": "dark",
"editorMode": "vim",
"model": "claude-sonnet-5",
"permissions": {
"allow": [
"Bash(brew *)",
"Bash(code *)"
]
},
"cleanupPeriodDays": 20
}
// ========== 本地级 .claude/settings.local.json(不共享,个人项目级覆盖)==========
{
"permissions": {
"allow": [
"Bash(my-custom-script.sh)"
]
}
}
3.2 最佳实践清单
- 项目级放团队规范:权限规则、hooks、MCP 服务器配置都放
.claude/settings.json,确保每个 clone 仓库的人获得一致的防护。 - 用户级放个人偏好:主题、编辑器模式、跨项目通用的工具白名单放
~/.claude/settings.json。 - 本地级放试验性配置:正在测试但还没准备好分享给团队的配置放
.claude/settings.local.json,它会被自动 gitignore。 - CLAUDE.md 配合使用:把团队编码规范写在仓库根目录的
CLAUDE.md里,它会被加载到系统提示中,配合权限规则形成"行为+约束"双保险。 - 敏感数据绝不入仓:
.claude/settings.local.json中也不要存密钥,用apiKeyHelper指向一个本地脚本动态生成。
四、安全设置:API 密钥管理与敏感数据防护
4.1 用 apiKeyHelper 动态生成密钥
直接在环境变量里写死 API Key 是高风险操作。Claude Code 支持 apiKeyHelper,指向一个脚本,每次请求时动态生成认证值:
{
"apiKeyHelper": "/usr/local/bin/generate-claude-key.sh",
"env": {
"CLAUDE_CODE_API_KEY_HELPER_TTL_MS": "300000"
}
}
generate-claude-key.sh 示例(从公司密钥管理系统获取临时令牌):
#!/bin/bash
# 从内部密钥管理系统获取短期有效的 API Key
# 输出到 stdout,Claude Code 会将其作为 X-Api-Key 和 Authorization: Bearer 头部
TOKEN=$(curl -s -H "X-Vault-Token: $VAULT_TOKEN" \
https://vault.internal.company.com/v1/claude/key \
| jq -r '.data.api_key')
echo "$TOKEN"
别忘了给脚本执行权限:
chmod +x /usr/local/bin/generate-claude-key.sh
4.2 敏感文件防护清单
在项目级 .claude/settings.json 中加入这些 deny 规则,构建数据防护网:
{
"permissions": {
"deny": [
"Read(.env)",
"Read(**/.env)",
"Read(**/.env.*)",
"Read(**/*.pem)",
"Read(**/*.key)",
"Read(**/id_rsa)",
"Read(**/id_ed25519)",
"Read(**/secrets/**)",
"Read(**/.ssh/**)",
"Read(**/credentials.json)",
"Read(**/serviceAccountKey.json)",
"Read(//**/.env)"
]
}
}
关键点说明:
Read的 deny 规则同时会阻止Edit工具在同路径上操作(包括创建新文件),形成读写双重封锁。//**/.env使用双斜杠锚定文件系统根,匹配磁盘上任意位置的.env,防止 Claude 通过路径穿越绕过项目目录限制。- 当 Claude 访问符号链接时,deny 规则会同时检查链接路径和目标路径,任一匹配即阻止。
4.3 禁止危险操作
{
"permissions": {
"deny": [
"Bash(rm -rf *)",
"Bash(rm -rf /)",
"Bash(git push --force *)",
"Bash(git push -f *)",
"Bash(sudo *)",
"Bash(chmod 777 *)",
"Bash(curl * | bash)",
"Bash(curl * | sh)",
"Bash(wget * | bash)"
],
"ask": [
"Bash(git push *)",
"Bash(npm publish *)",
"Bash(docker *)",
"Bash(kubectl *)"
]
}
}
五、实战案例:一个完整的团队级 Claude Code 配置方案
假设你的团队是一个使用 Node.js + TypeScript 的 Web 服务团队,需要为所有开发者建立统一的 Claude Code 配置。以下是完整的落地步骤。
步骤 1:创建项目配置目录
mkdir -p .claude/commands
mkdir -p .claude/agents
touch .claude/settings.json
touch CLAUDE.md
步骤 2:编写团队共享配置
.claude/settings.json:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"model": "claude-sonnet-5",
"permissions": {
"allow": [
"Bash(pnpm install)",
"Bash(pnpm test *)",
"Bash(pnpm run lint *)",
"Bash(pnpm run typecheck *)",
"Bash(pnpm run build)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)",
"Bash(git branch *)",
"Bash(git add *)",
"Bash(git commit -m *)",
"Bash(git checkout -b *)",
"Read(./src/**)",
"Read(./tests/**)",
"Read(./docs/**)",
"Read(./package.json)",
"Read(./tsconfig.json)",
"WebFetch(domain:docs.anthropic.com)",
"WebFetch(domain:developer.mozilla.org)"
],
"ask": [
"Bash(git push *)",
"Bash(git merge *)",
"Bash(git rebase *)",
"Bash(pnpm run deploy *)",
"Bash(docker *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force *)",
"Bash(git push -f *)",
"Bash(sudo *)",
"Read(.env)",
"Read(**/.env)",
"Read(**/.env.*)",
"Read(**/*.pem)",
"Read(**/.ssh/**)",
"Read(**/secrets/**)"
]
},
"env": {
"NODE_ENV": "development",
"CLAUDE_CODE_DISABLE_TELEMETRY": "1"
},
"cleanupPeriodDays": 20
}
步骤 3:创建团队标准命令
.claude/commands/test-pr.md——运行测试并生成 PR:
---
description: 运行完整测试套件,通过后创建 PR
argument-hint: <分支描述>
allowed-tools: Bash(pnpm:*), Bash(git:*), Bash(gh:*)
---
请完成以下步骤:
1. 运行 `pnpm run typecheck` 确保类型正确。
2. 运行 `pnpm run lint` 检查代码风格。
3. 运行 `pnpm test` 执行完整测试套件。
4. 如果以上任一步骤失败,分析失败原因并给出修复建议,然后停止。
5. 如果全部通过,检查 `git status`,将改动整理为一个语义化提交。
6. 用 `gh pr create` 创建 PR,标题基于 $ARGUMENTS(如果提供),正文包含改动概要和测试结果。
不要推送到 main 分支。
步骤 4:编写团队规范记忆
CLAUDE.md:
# 项目规范
## 技术栈
- 运行时:Node.js 20+
- 语言:TypeScript(strict 模式)
- 包管理:pnpm
- 测试:Vitest
## 代码规范
- 使用 ESM 导入,禁止 require
- 函数命名使用 camelCase,类型/接口使用 PascalCase
- 所有公共函数必须有 JSDoc 注释
- 提交信息遵循 Conventional Commits(feat:, fix:, docs:, refactor:)
## 禁止事项
- 不要直接修改 dist/ 目录下的构建产物
- 不要在 src/ 中引入测试文件
- 不要使用 any 类型,用 unknown 替代
步骤 5:提交配置到 Git
git add .claude/settings.json .claude/commands/ CLAUDE.md
git commit -m "feat: 添加团队级 Claude Code 配置与规范"
git push
团队成员 clone 仓库后,首次在项目中启动 Claude Code 会看到工作区信任对话框,确认后即自动加载全部团队配置。
六、常见问题 FAQ
Q1:我修改了 settings.json 但配置没生效,怎么办?
Claude Code 会监视配置文件的变化并自动热重载,包括 permissions、hooks、apiKeyHelper 等大部分字段,无需重启。但有两个例外需要重启或切换才能生效:model(用 /model 命令在会话中切换)和 outputStyle(在 /clear 或重启后生效)。如果改动后确实没反应,运行 /doctor 检查配置解析状态,它会列出所有被剥离的无效条目及其来源文件。
Q2:项目级的 allow 规则为什么没自动放行,还弹了信任对话框?
这是工作区信任(Workspace Trust)机制。.claude/settings.json 中的 allow 规则会授予 Claude 能力,因此 Claude Code 在首次使用前会弹出信任对话框让你审查这些规则。只有你选择"Yes, I trust this folder"后,allow 规则才生效。deny 和 ask 规则不受此限制,因为它们只会增加限制而非授予能力。.claude/settings.local.json 是你自己的文件,通常不需要信任检查。
Q3:deny 规则能被 allow 规则覆盖吗?
不能。权限评估顺序固定为 deny → ask → allow,第一个匹配的规则决定结果。如果一条 deny 规则匹配了某个工具调用,即使存在更具体的 allow 规则,deny 仍然生效。这意味着你不能写一条"允许 git push 但禁止 git push --force"的规则组合——Bash(git push --force *) 的 deny 会覆盖 Bash(git push *) 的 allow。正确做法是把 git push 放在 ask 列表中,让每次推送都需确认。
Q4:团队成员用的是不同操作系统,路径配置会冲突吗?
不会有问题。Claude Code 在匹配权限路径前会将 Windows 路径标准化为 POSIX 形式(C:\Users\alice 变成 /c/Users/alice)。因此你可以在配置中使用统一的 POSIX 风格路径。匹配 .env 文件在所有系统上用 Read(.env) 或 Read(/.env) 即可。如果需要匹配 Windows 上某盘符的文件,使用 Read(//c//.env) 这种双斜杠加盘符的形式。
Q5:如何在 CI/CD 环境中安全地使用 Claude Code?
CI 环境通常是非交互式的(headless 模式),使用 -p 参数运行。几个关键配置建议:第一,用 apiKeyHelper 指向 CI 密钥管理系统动态获取令牌,不要在环境变量中硬编码;第二,在 .claude/settings.json 中设置严格的 deny 规则保护敏感文件;第三,CI 中不要使用 bypassPermissions 模式,改用 defaultMode: "dontAsk" 配合精确的 allow 白名单——只有预先批准的工具才能运行,其余全部自动拒绝;第四,设置 DISABLE_AUTO_COMPACT 避免在长任务中意外压缩上下文导致信息丢失。
Q6:Slash Command 和 Skill 有什么区别,什么时候用哪个?
Slash Command 是"你主动输入 /name 触发的保存提示词",适合每次都一样的重复操作(如生成 PR、跑测试、生成 changelog)。Skill 是"Claude 根据当前任务自动决定是否调用的能力包",适合需要附带模板文件、脚本等支撑资源的领域知识。简单判断标准:如果你每次都要手动打一段相同的话,做成 Slash Command;如果你希望 Claude 在合适的时候"自己知道该怎么做",做成 Skill。当命令的提示词长到你自己都记不住全貌时,就该升级成 Skill 了。
七、总结
Claude Code 的 Settings 体系看似复杂,但核心逻辑清晰:四级作用域决定配置的覆盖范围和共享范围,allow/ask/deny 三类规则构成权限防护网,env 字段统一管理运行环境,Slash Commands 把重复操作固化为可复用命令。
落地时记住三条主线:
- 团队规范进项目级配置——
.claude/settings.json+CLAUDE.md+.claude/commands/一起提交到 Git,让每个人 clone 后即获得一致的防护和效率工具。 - 敏感数据用 deny 规则封死——
.env、密钥文件、SSH 目录全部加入 deny 列表,配合apiKeyHelper动态获取令牌,杜绝密钥泄露。 - 个人偏好留在用户级和本地级——主题、编辑器模式等放
~/.claude/settings.json,试验性配置放.claude/settings.local.json,互不干扰。
配置到位后,你会发现 Claude Code 从一个"需要时刻盯着"的工具,变成了一个"在安全边界内自由发挥"的协作伙伴。花在配置上的十分钟,省下的是未来无数次的权限弹窗和安全隐患。
相关文章推荐:
本文发布于 1630.top,转载请注明出处。