导读: 权限配置是使用 Claude Code 的核心技能之一。合理的权限设置既能让 AI 高效完成任务,又能防止误操作破坏代码或泄露敏感文件。本文将带你从零开始,全面掌握 Claude Code 的权限管理体系。
为什么权限配置如此重要?
Claude Code 是一个具备强大能力的 AI 编程助手,它可以读写文件、执行 Shell 命令、访问网络资源。这些能力在带来便利的同时,也意味着一旦权限配置不当,可能产生以下风险:
- 数据泄露 :AI 误读
.env文件中的 API Key、数据库密码等敏感信息 - 代码损坏:未经审批的文件编辑导致生产代码被意外修改
- 安全漏洞:不受限制的网络请求可能将内部数据发送到外部域名
- 系统破坏 :危险的 Shell 命令(如
rm -rf)被自动执行
Claude Code 的分层权限系统正是为了解决这些问题而设计的------它让你对 AI 的每一个操作都有精确的控制权。
一、权限系统的三大类型
Claude Code 将所有操作分为三类,不同类型拥有不同的默认权限策略:
| 工具类型 | 示例 | 是否需要批准 | 永久允许行为 |
|---|---|---|---|
| 只读操作 | 文件读取、Grep 搜索 | 否 | 不适用 |
| Bash 命令 | Shell 命令执行 | 是 | 每个项目目录和命令永久有效 |
| 文件修改 | Edit/Write 文件 | 是 | 直到会话结束 |
关键理解: 只读操作默认不需要审批,因为读取本身风险较低;而写入和命令执行则需要你的明确授权。
二、三种权限动作
每条权限规则最终会解析为以下三种动作之一:
| 动作 | 效果 | 适用场景 |
|---|---|---|
"allow" |
无需审批,直接自动运行 | 低风险、高频操作,如 git status、npm run build |
"ask" |
弹出审批提示,由你决定是否允许 | 有一定风险的操作,如文件写入、危险命令执行 |
"deny" |
直接阻止,不会执行也不会提示 | 明确不允许的危险操作,如 git push、rm -rf |
三、六种权限模式详解
权限模式控制 Claude 在执行操作前是否询问用户。不同的任务场景需要不同级别的自主权。
| 模式 | 描述 | 最适用场景 |
|---|---|---|
default |
标准行为:首次使用每个工具时提示权限 | 入门学习、敏感工作、需要完全监督 |
acceptEdits |
自动接受会话的文件编辑权限,受保护目录除外 | 迭代正在审查的代码 |
plan |
Plan Mode:Claude 可以分析但不能修改文件或执行命令 | 探索代码库、规划重构 |
auto |
自动批准工具调用,并进行后台安全检查(研究预览) | 长时间运行的任务、减少提示疲劳 |
dontAsk |
自动拒绝工具调用,除非通过权限规则预先批准 | 锁定环境、CI 管道 |
bypassPermissions |
跳过权限提示,但对受保护目录的写入仍会提示 | 仅用于隔离容器和 VM |
受保护目录说明
以下目录即使在宽松模式下也会受到额外保护,写入时仍会提示:
/etc/、/usr/、/bin/、/sbin/等系统目录~/.ssh/、~/.gnupg/等含有密钥的目录- 项目根目录之外的路径(需显式配置才能访问)
如何切换权限模式
方式一:会话期间按键切换
按 Shift+Tab 可循环切换:
default → acceptEdits → plan → auto
方式二:启动时通过命令行指定
bash
claude --permission-mode plan
claude --permission-mode bypassPermissions
方式三:在配置文件中设置默认模式
编辑 .claude/settings.json(项目级)或 ~/.claude/settings.json(用户级):
json
{
"permissions": {
"defaultMode": "acceptEdits"
}
}
实践建议: 日常开发推荐使用
acceptEdits模式,既能自动接受文件编辑(减少频繁点击确认),又对 Bash 命令保持审批。处理敏感代码库时,建议使用default或plan模式。
四、权限规则语法
1. 基本格式
权限规则遵循格式 Tool 或 Tool(specifier),例如 Bash 或 Bash(git status)。
json
{
"permissions": {
"allow": ["Bash", "WebFetch", "Read"],
"deny": ["Edit"]
}
}
上面这个配置的含义:允许所有 Bash 命令、网络请求和文件读取,但禁止所有文件编辑。
2. 不带说明符:匹配该工具的所有调用
| 规则 | 效果 |
|---|---|
Bash |
匹配所有 Bash 命令 |
WebFetch |
匹配所有网络获取请求 |
Read |
匹配所有文件读取 |
Edit |
匹配所有文件编辑 |
Bash(*)与Bash完全等同,两者效果相同。
3. 带说明符:细粒度精准控制
json
{
"permissions": {
"allow": [
"Bash(npm run build)",
"Read(./.env)",
"WebFetch(domain:example.com)"
]
}
}
4. 通配符模式(*)
通配符可以出现在命令中的任何位置:
json
{
"permissions": {
"allow": [
"Bash(npm run *)", // 匹配 npm run build、npm run test 等
"Bash(git commit *)", // 匹配 git commit -m "message" 等
"Bash(git * main)", // 匹配 git checkout main、git merge main 等
"Bash(* --version)", // 匹配任何带 --version 参数的命令
"Bash(* --help *)" // 匹配任何带 --help 参数的命令
],
"deny": [
"Bash(git push *)" // 阻止所有 git push 操作
]
}
}
⚠️ 注意通配符前的空格:
Bash(ls *)匹配ls -la,但不 匹配lsofBash(ls*)则两者都匹配
五、各工具的权限规则详解
1. Bash 命令权限
| 规则 | 匹配示例 |
|---|---|
Bash(npm run build) |
仅 npm run build |
Bash(npm run test *) |
npm run test、npm run test --coverage |
Bash(npm *) |
任何以 npm 开头的命令 |
Bash(* install) |
任何以 install 结尾的命令 |
Bash(git * main) |
git checkout main、git merge main |
⚠️ 重要限制: 尝试通过 Bash 权限规则约束 URL、参数等复杂内容时可能很脆弱。不同的协议写法、重定向符号、Shell 变量、额外空格都可能导致规则不匹配。对于网络请求,建议使用
WebFetch工具配合domain:权限进行过滤,而不是依赖 Bash 规则。
2. Read 和 Edit(文件操作权限)
文件路径支持四种前缀模式:
| 模式前缀 | 含义 | 示例 |
|---|---|---|
//path |
绝对路径(从文件系统根目录) | Read(//Users/alice/secrets/**) |
~/path |
主目录路径 | Read(~/Documents/*.pdf) |
/path |
相对于项目根目录 | Edit(/src/**/*.ts) |
path 或 ./path |
相对于当前目录 | Read(*.env) |
完整配置示例:
json
{
"permissions": {
"allow": [
"Edit(/docs/**)", // 允许编辑项目 docs 目录下的文件
"Read(~/.zshrc)", // 允许读取主目录的 .zshrc
"Edit(//tmp/scratch.txt)", // 允许编辑绝对路径的临时文件
"Read(src/**)" // 允许读取当前目录 src 子目录的文件
],
"deny": [
"Read(*.env)", // 阻止读取 .env 文件(防止泄露密钥)
"Edit(//etc/**)" // 阻止编辑系统目录文件
]
}
}
⚠️ 重要提醒:
Read和Edit的deny规则不适用于 Bash 子进程中的操作(例如cat .env通过 Bash 执行仍可读取文件)。要获得操作系统级别的强制执行,需要额外启用沙箱(Sandbox)功能。
3. WebFetch(网络请求权限)
使用 domain: 前缀精准控制可访问的域名:
json
{
"permissions": {
"allow": [
"WebFetch(domain:github.com)", // 允许访问 GitHub
"WebFetch(domain:api.example.com)", // 允许访问内部 API
"WebFetch(domain:docs.anthropic.com)" // 允许访问 Anthropic 文档
],
"deny": [
"WebFetch(domain:untrusted.com)" // 阻止访问不可信域名
]
}
}
最小权限原则: 只允许 Claude 访问任务所必需的域名,例如只需要查文档时,只开放文档站点域名,而非所有网络访问。
六、工作目录配置
默认情况下,Claude Code 只允许访问启动时的工作目录及其子目录。如果需要访问项目目录之外的路径,必须显式配置。
扩展访问范围的三种方式
方式一:启动时通过 CLI 参数
bash
claude --add-dir ~/shared-libs
方式二:会话期间通过命令
bash
/add-dir ~/shared-libs
方式三:持久配置(推荐)
在 settings.json 中添加 additionalDirectories:
json
{
"additionalDirectories": [
"~/projects/personal/**", // 允许访问个人项目目录
"~/projects/work/**", // 允许访问工作项目目录
"~/dotfiles/**" // 允许访问配置文件目录
]
}
无需额外配置即可访问的内容
即使没有配置额外目录,以下内容始终可访问:
.claude/skills/中的 Skills(支持实时重新加载).claude/settings.json中的插件设置(仅enabledPlugins和extraKnownMarketplaces)- CLAUDE.md 文件和
.claude/rules/(需设置CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1)
七、使用 Hooks 扩展权限控制
PreToolUse hooks 是权限系统的高级扩展机制,它在权限提示之前运行,可以实现更精细的控制逻辑。
Hooks 能做什么
- 拒绝工具调用:在权限评估之前就阻止某个操作
- 强制提示:即使权限规则允许,也强制弹出用户确认
- 跳过提示:在满足自定义条件时,允许直接继续而无需用户确认
一个实际示例
假设你希望在 Claude 执行任何 git 命令之前,先记录日志并检查当前分支是否为 main(防止直接操作主分支):
bash
# .claude/hooks/pre-tool-use.sh
#!/bin/bash
TOOL_NAME="$1"
COMMAND="$2"
# 只处理 Bash 工具
if [ "$TOOL_NAME" = "Bash" ]; then
# 如果是 git 命令,检查当前分支
if echo "$COMMAND" | grep -q "^git"; then
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
echo "[Hook] Git command on branch: $BRANCH" >> ~/.claude/hook.log
# 如果在 main 分支上执行写操作,退出码 2 阻止执行
if [ "$BRANCH" = "main" ] && echo "$COMMAND" | grep -qE "git (push|reset|rebase)"; then
echo "阻止在 main 分支上执行危险操作: $COMMAND"
exit 2
fi
fi
fi
在 settings.json 中注册 hook:
json
{
"hooks": {
"PreToolUse": [".claude/hooks/pre-tool-use.sh"]
}
}
重要说明
⚠️ 跳过提示不等于绕过规则。 Hook 返回 "allow" 只是跳过了用户提示,
deny和ask规则在 hook 之后仍会被评估。只有当 hook 以退出码 2 退出时,才会在权限规则评估之前完全阻止工具调用。
八、配置文件的优先级
Claude Code 的配置文件有多个层级,当存在冲突时,优先级从高到低如下:
| 优先级 | 配置来源 | 说明 |
|---|---|---|
| 1(最高) | 托管设置 | 由管理员控制,无法被任何其他级别覆盖 |
| 2 | 命令行参数 | 临时会话覆盖,仅当次生效 |
| 3 | 本地项目设置 | .claude/settings.local.json(不提交到 Git) |
| 4 | 共享项目设置 | .claude/settings.json(提交到 Git,团队共用) |
| 5(最低) | 用户设置 | ~/.claude/settings.json(全局默认) |
关键规则: 如果某个工具在任意一个层级被 deny,则其他任何层级都无法将其 allow。这意味着:
- 团队管理员可以通过托管设置锁定某些危险操作,开发者无法绕过
- 项目级配置 (
.claude/settings.json)可以为整个团队统一权限策略,建议提交到 Git 仓库 - 本地配置 (
.claude/settings.local.json)用于个人偏好,应加入.gitignore
九、完整配置示例
场景一:个人日常开发(推荐配置)
适合大多数开发者的平衡配置:
json
{
"permissions": {
"defaultMode": "acceptEdits",
"allow": [
"Bash(git status)",
"Bash(git log *)",
"Bash(git diff *)",
"Bash(npm run *)",
"Bash(yarn *)",
"Bash(* --version)",
"Bash(* --help *)",
"WebFetch(domain:github.com)",
"WebFetch(domain:npmjs.com)",
"WebFetch(domain:docs.anthropic.com)"
],
"deny": [
"Bash(git push *)",
"Bash(rm -rf *)",
"Bash(sudo *)",
"Read(*.env)",
"Read(*.env.*)",
"Read(**/.env)",
"Edit(//etc/**)",
"Edit(~/.ssh/**)"
]
}
}
场景二:CI/CD 流水线(锁定环境)
在自动化流水线中,只允许预定义的操作:
json
{
"permissions": {
"defaultMode": "dontAsk",
"allow": [
"Bash(npm run build)",
"Bash(npm run test)",
"Bash(npm run lint)",
"Read(/src/**)",
"Read(/tests/**)",
"Edit(/dist/**)"
],
"deny": [
"Bash(git push *)",
"WebFetch(*)"
]
}
}
场景三:代码探索与重构规划(只读模式)
在不确定如何改动时,先用 plan 模式安全探索:
json
{
"permissions": {
"defaultMode": "plan",
"allow": [
"Read(/src/**)",
"Read(/docs/**)",
"WebFetch(domain:github.com)"
]
}
}
十、安全最佳实践
✅ 应该做
- 从最小权限开始:先配置最严格的限制,根据实际需要逐步扩展,而不是一开始就给予宽泛权限
- 保护敏感文件 :始终用
deny规则阻止访问.env、密钥文件、证书等 - 限制网络访问 :使用
WebFetch(domain:xxx)只允许必要的域名,防止数据外泄 - 区分项目配置和个人配置 :团队共用的规则放
.claude/settings.json并提交 Git;个人偏好放.claude/settings.local.json并加入.gitignore - 在 CI 环境使用
dontAsk模式 :配合精细的allow规则,确保自动化流程可控 - 定期审查配置:检查沙箱违规尝试记录和被拒绝的操作,按需调整策略
- 使用沙箱提供 OS 级保护:权限规则在应用层工作,沙箱才能提供底层系统级隔离
❌ 不应该做
- 不要在非隔离环境使用
bypassPermissions:这个模式不提供任何安全保障,只能在容器或 VM 中使用 - 不要依赖 Bash 规则过滤文件访问 :通过 Bash 执行的
cat .env不受Read(*.env)deny 规则约束 - 不要无限制允许
sudo *:提权操作应该永远需要人工审批 - 不要忽略 Hooks 的退出码语义:Hook 返回 "allow" ≠ 绕过权限规则,两者作用不同
十一、常见问题 FAQ
Q:我设置了 deny: ["Read(*.env)"],但 Claude 还是读到了 .env 文件里的内容,为什么?
A:如果 Claude 是通过 Bash 命令(如 cat .env)读取的,Read 的 deny 规则不会拦截 Bash 子进程。要彻底防止这类访问,需要启用沙箱功能,或者同时添加 deny: ["Bash(cat *.env)", "Bash(cat .env)"] 等规则(注意 Bash 规则匹配相对脆弱)。
Q:auto 模式和 bypassPermissions 模式有什么区别?
A:auto 模式会自动批准工具调用,但仍然运行后台安全检查 ,是更安全的自动化选项;bypassPermissions 直接跳过所有权限提示,不做任何安全检查,只应在完全隔离的环境(容器/VM)中使用。
Q:项目的 .claude/settings.json 和用户的 ~/.claude/settings.json 冲突时,哪个生效?
A:项目设置(优先级 4)高于用户设置(优先级 5)。但要注意,任意层级的 deny 规则都无法被更低优先级的 allow 覆盖。
Q:我想让团队所有人都不能用 git push,但每个人都可以自定义其他权限,怎么配置?
A:在共享项目设置 .claude/settings.json 中添加 deny: ["Bash(git push *)"],这条规则会对整个团队生效,且无法被个人的 settings.local.json 覆盖。
Q:plan 模式下,Claude 完全不能做任何操作吗?
A:不是的,plan 模式下 Claude 仍然可以读取文件 和搜索代码 ,只是不能修改文件 或执行命令。这非常适合在正式动手改代码前,先让 Claude 分析代码库并制定重构方案。
总结
Claude Code 的权限系统是一个设计精良的多层防护体系。掌握它的核心逻辑很简单:
- 用模式 (
default/acceptEdits/plan/auto)控制整体自主程度 - 用规则 (
allow/deny+ 工具说明符)精确控制每个具体操作 - 用目录配置限制文件访问范围
- 用 Hooks 实现复杂的自定义逻辑
- 用优先级系统在团队和个人偏好之间取得平衡
从保守配置开始,随着你对 Claude Code 行为的了解加深,再逐步开放权限------这是最安全也是最推荐的使用方式。
