前言
Claude Code 可以读文件、写文件、执行 Shell 命令、访问网络。这些能力放在一起很强大,但也意味着如果不加控制,一条错误的指令就可能删掉你不想删的文件,或者把密钥暴露在日志里。
权限系统就是 Claude Code 的安全边界。理解它,你才能在"让 Claude 尽量少打断我"和"不让 Claude 做危险的事"之间找到合适的平衡点。
文章结构
1. 五层配置层级 --- 哪个文件管哪个范围
2. 权限模式 --- 三种默认行为
3. 工具权限规则 --- allow / ask / deny 的写法
4. 沙盒模式 --- 操作系统级别的隔离
5. 常用配置项速查 --- settings.json 的主要字段
6. 典型配置示例 --- 四个场景的完整配置
7. 实战练习
快速参考卡
配置文件位置(优先级从高到低)
/etc/claude-code/managed-settings.json ① Managed(企业 IT 部署)
CLI 参数 ② 命令行(当前会话)
.claude/settings.local.json ③ Local(个人项目覆盖,gitignored)
.claude/settings.json ④ Project(团队共享,提交 git)
~/.claude/settings.json ⑤ User(个人全局)
权限模式(permissions.defaultMode)
default 默认,每次操作都询问
acceptEdits 文件编辑无需确认,Bash 命令仍询问
bypassPermissions 跳过所有确认(危险,仅限 CI)
工具权限规则语法
"Bash" 允许所有 Bash 命令
"Bash(git *)" 允许 git 开头的所有命令
"Read(./.env)" 允许读取 .env 文件
"Read(./secrets/**)" 允许读取 secrets/ 下的所有文件
"WebFetch(domain:x.com)" 允许访问特定域名
规则评估顺序:deny 优先 > ask > allow,第一个匹配的规则生效
常用 CLI 权限参数
--permission-mode bypassPermissions 当前会话跳过所有确认
--allowedTools "Read,Grep,Glob" 当前会话只允许这些工具
--disallowedTools "Bash" 当前会话禁用 Bash
第一节:五层配置层级
Claude Code 的 settings.json 遵循严格的五层优先级体系,优先级从高到低:
| 优先级 | 层级 | 文件位置 | 作用范围 | 是否提交 git |
|---|---|---|---|---|
| ① | Managed | /etc/claude-code/managed-settings.json |
机器上所有用户 | 不适用 |
| ② | 命令行参数 | --- | 当前会话 | 不适用 |
| ③ | Local | .claude/settings.local.json |
你自己,当前项目 | 否(自动 gitignore) |
| ④ | Project | .claude/settings.json |
团队所有人 | 是 |
| ⑤ | User | ~/.claude/settings.json |
你自己,所有项目 | 否 |
核心规则:高优先级的设置永远覆盖低优先级。deny 规则尤其如此------任何层级的 deny 都无法被更低层级的 allow 覆盖。
每一层该放什么
Managed :企业 IT 统一下发的安全策略,比如禁止访问 .env 文件、禁用危险的 Shell 命令。开发者无法绕过。
命令行参数:临时性的一次性覆盖。测试某个权限、跑一个特殊任务时用,不影响任何配置文件。
Local:你在这个项目里的个人偏好,不适合提交给团队的内容。比如本机特定路径、你自己测试中的 hook。
Project:团队应当共同遵守的规则。允许哪些测试命令、禁止直接 push main 分支、项目共用的 MCP 服务器配置。
User :你在所有项目里的个人默认值。比如偏好语言、全局禁止访问 ~/.ssh 目录。
配置文件的备份机制
Claude Code 会自动为每个配置文件保留最近 5 份带时间戳的备份。如果你改坏了配置,可以在 .claude/ 目录下找到备份文件恢复。
第二节:权限模式
权限模式(defaultMode)决定 Claude Code 的默认行为------它遇到需要操作文件或执行命令时,是先问你还是直接干。
三种权限模式
default(默认)
每一次文件修改、每一条 Bash 命令都会弹出确认。最安全,但在长时间工作时会不断打断你。适合:陌生代码库、生产环境附近的操作。
acceptEdits
文件的读取和编辑无需确认,Bash 命令仍然询问。这是大多数日常开发的合理选择------你信任 Claude 编辑代码,但对任意 Shell 命令保持警惕。
json
{
"permissions": {
"defaultMode": "acceptEdits"
}
}
bypassPermissions
跳过所有确认,Claude 可以执行任何操作而不打断你。只在完全受控的 CI/CD 环境中使用,绝对不要在本地开发时设置为全局默认。
json
{
"permissions": {
"defaultMode": "bypassPermissions"
}
}
如果企业需要禁止任何人使用 bypassPermissions 模式,可以在 Managed 层设置:
json
{
"permissions": {
"disableBypassPermissionsMode": "disable"
}
}
第三节:工具权限规则
allow、ask、deny 三个规则列表控制具体工具的行为。
规则评估顺序
deny 优先,然后 ask,最后 allow。 第一个匹配的规则生效,后面的规则不再检查。
规则语法
工具名 匹配该工具的所有调用
工具名(*) 同上(显式通配)
工具名(过滤条件) 只匹配符合条件的调用
常用工具名:Bash、Read、Write、Edit、MultiEdit、Glob、Grep、LS、WebFetch、WebSearch、Task
过滤条件示例
json
{
"permissions": {
"allow": [
"Bash(git *)", // 所有 git 命令无需确认
"Bash(uv run pytest *)", // 所有 pytest 命令无需确认
"Bash(ruff *)", // ruff 检查无需确认
"Read(~/.zshrc)" // 读取 zshrc 无需确认
],
"ask": [
"Bash(git push *)" // push 前仍然询问
],
"deny": [
"Read(./.env)", // 禁止读取 .env
"Read(./.env.*)", // 禁止读取所有 .env 变体
"Bash(rm -rf *)", // 禁止强制递归删除
"Bash(sudo *)", // 禁止 sudo
"WebFetch" // 完全禁止网络访问
]
}
}
deny 覆盖 allow 的优先级
如果同一条规则在不同层级出现冲突:
用户全局 allow: ["Bash(git *)"]
项目 deny: ["Bash(git push *)"]
结果:git push 被禁止,其他 git 命令正常。任何层级的 deny 都不能被更低层级的 allow 覆盖。
第四节:沙盒模式
权限规则控制"Claude 被允许做什么",沙盒控制的是"操作系统层面实际能访问什么"------两者是不同的防线。
沙盒模式通过操作系统机制(macOS 上用 Sandbox,Linux/WSL2 上用 Landlock)在内核层面隔离 Bash 命令,即使规则配置出错,沙盒也能提供最后一道防护。
json
{
"sandbox": {
"enabled": true,
"network": {
"allowedDomains": ["github.com", "*.pypi.org", "*.githubusercontent.com"],
"allowLocalBinding": true
},
"excludedCommands": ["git", "docker"],
"autoAllowBashIfSandboxed": true
}
}
各配置项的含义:
| 配置项 | 含义 |
|---|---|
enabled |
开启沙盒 |
network.allowedDomains |
允许访问的出站域名白名单 |
network.allowLocalBinding |
允许绑定 localhost(macOS 上开发服务器需要) |
excludedCommands |
这些命令在沙盒外运行(适合需要访问主机网络的工具) |
autoAllowBashIfSandboxed |
沙盒内的 Bash 命令自动批准,不再弹出确认 |
沙盒模式在 Linux 和 WSL2 上开启时,如果 Claude Code 本身运行在 Docker 里,需要额外设置:
json
{
"sandbox": {
"enableWeakerNestedSandbox": true
}
}
第五节:常用配置项速查
通用设置
json
{
"model": "sonnet", // 默认模型
"language": "chinese", // Claude 回答语言
"cleanupPeriodDays": 30, // 不活跃会话保留天数
"autoUpdatesChannel": "stable", // 更新渠道:stable 或 latest
"alwaysThinkingEnabled": false, // 是否默认开启 Extended Thinking
"respectGitignore": true // @ 文件选择器是否遵守 .gitignore
}
环境变量注入
json
{
"env": {
"PYTHONPATH": "./src",
"ENVIRONMENT": "development",
"BASH_DEFAULT_TIMEOUT_MS": "30000"
}
}
放在 env 里的键值对会在每个 Claude Code 会话启动时自动注入,不需要在 shell 配置里设置。
Git 归因设置
json
{
"attribution": {
"commit": "Co-authored with Claude\n\nCo-Authored-By: Claude <claude@anthropic.com>",
"pr": ""
}
}
commit 控制 Claude 生成的 commit message 末尾追加的内容,pr 控制 PR 描述末尾的内容。设置为空字符串则不追加任何内容。
扩展目录访问
json
{
"permissions": {
"additionalDirectories": ["../shared-lib", "../docs"]
}
}
允许 Claude 访问项目目录之外的路径。Monorepo 和跨仓库场景常用。
第六节:典型配置示例
场景一:日常开发(个人全局配置)
json
// ~/.claude/settings.json
{
"model": "sonnet",
"language": "chinese",
"permissions": {
"defaultMode": "acceptEdits",
"allow": [
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)",
"Bash(git add *)",
"Bash(git commit *)"
],
"ask": [
"Bash(git push *)",
"Bash(git merge *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Bash(sudo *)",
"Bash(rm -rf *)"
]
}
}
效果:文件编辑无需确认,常用 git 命令自动放行,push 和 merge 仍然询问,危险命令全部拒绝。
场景二:Python 项目(项目级配置)
json
// .claude/settings.json
{
"permissions": {
"allow": [
"Bash(uv *)",
"Bash(ruff *)",
"Bash(mypy *)",
"Bash(pytest *)",
"Bash(python -m *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Write(./production.config.*)"
]
},
"env": {
"PYTHONPATH": "./src",
"ENVIRONMENT": "development"
}
}
效果:所有 Python 工具链命令无需确认,保护环境变量文件和生产配置。
场景三:只读审查模式(适合审查陌生代码库)
json
// 临时用命令行参数,不修改任何配置文件
// claude --allowedTools "Read,Grep,Glob,LS" --permission-mode default
或者写成一次性的 Local 配置:
json
// .claude/settings.local.json
{
"permissions": {
"defaultMode": "default",
"deny": [
"Write",
"Edit",
"MultiEdit",
"Bash"
]
}
}
效果:Claude 只能读文件,无法做任何修改,适合初次接触陌生代码库时安全审查。
场景四:CI/CD 自动化(完全无人值守)
json
// 在 CI 环境中通过环境变量或命令行参数控制,不写入文件
// claude -p "运行测试并修复失败用例" --permission-mode bypassPermissions
如果需要写成配置:
json
// .claude/settings.local.json(CI 机器上,不提交)
{
"permissions": {
"defaultMode": "bypassPermissions",
"allow": [
"Bash(uv run pytest *)",
"Bash(git commit *)",
"Bash(git push *)"
],
"deny": [
"Bash(rm -rf *)",
"WebFetch"
]
},
"sandbox": {
"enabled": true,
"network": {
"allowedDomains": ["*.pypi.org", "github.com"]
}
}
}
效果:完全不打断,同时用沙盒限制网络访问范围,避免数据泄露。
实战练习
练习 1:查看当前有效的权限配置
bash
claude
/config
在 /config 界面里可以看到所有层级的配置汇总,以及每一条规则最终是 allow 还是 deny。
练习 2:为你的项目创建第一个 settings.json
bash
mkdir -p .claude
cat > .claude/settings.json << 'EOF'
{
"permissions": {
"defaultMode": "acceptEdits",
"allow": [
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Bash(sudo *)"
]
}
}
重启 Claude Code,验证 git 命令是否不再询问。
练习 3:用 Local 配置做个人覆盖
bash
cat > .claude/settings.local.json << 'EOF'
{
"permissions": {
"allow": [
"Bash(git push *)"
]
}
}
EOF
这样你自己可以 push 而无需确认,但其他团队成员仍然需要确认(因为他们没有这个 local 文件)。
练习 4:测试只读模式
bash
# 以只读方式审查一个项目
claude --allowedTools "Read,Grep,Glob,LS" "帮我分析这个项目的整体架构"
观察 Claude 是否会尝试修改任何文件。
练习 5:理解 deny 覆盖 allow 的优先级
在 ~/.claude/settings.json 里添加:
json
{ "permissions": { "allow": ["Bash(rm *)"] } }
在 .claude/settings.json 里添加:
json
{ "permissions": { "deny": ["Bash(rm *)"] } }
在会话里让 Claude 执行一个 rm 命令,观察结果。然后删除这两条测试规则,理解优先级规则后再继续正常工作。
下一篇预告
#05 --- Hooks:让 Claude Code 每次都做对的事
权限系统控制 Claude 能不能做某件事,Hooks 控制做某件事之后自动发生什么。格式化、lint、通知、阻断危险命令------下一篇我们深入 Claude Code 的确定性自动化系统。
参考文档:Claude Code 官方文档