别让 Claude Code 一直问你"能不能执行":权限配置完全指南

0 阅读5分钟

用了 Claude Code 一段时间,有件事让我很头疼。

每次让它帮我写完一段代码,它要问我一句"能不能保存文件"。跑个测试,又问一句。创建个目录,再问一句。本来是来解放双手的,结果变成了另一种形式的"人肉确认机器"。

直到我彻底搞懂了它的权限配置系统,这个问题才真正解决。

为什么 Claude Code 会不断打断你

Claude Code 的设计哲学是谨慎优先。它默认对几乎所有文件操作、终端命令都会暂停下来问你一句,因为 AI 执行出错的代价,可能比慢一点高得多。

这个设计是对的。

但问题在于,"谨慎"和"高频打断"之间有巨大的差距。git status 这种只读命令,swift build 这种本地构建,根本不需要每次确认。真正需要谨慎的,是 git pushnpm install、以及任何涉及破坏性的操作。

Claude Code 提供了一套精细的权限配置机制,让你自己来划这条线。

权限系统的三个层级

配置文件有三层,从全局到局部依次覆盖:

~/.claude/settings.json              ← 全局,所有项目生效/.claude/settings.json         ← 项目级,可提交到 git/.claude/settings.local.json   ← 项目本地,加入 .gitignore

优先级:项目本地 > 项目级 > 全局。权限规则是合并生效的,但 deny 永远是最高优先级,任何地方的 deny 规则都不会被覆盖。

实际用法很清晰:

  • • 全局配置放通用规则(git 操作、构建工具、读文件)
  • • 项目配置放这个项目专属的规则(iOS 项目放 xcodebuild,前端项目放 vite)
  • • 本地配置放个人习惯、或者不适合提交的临时规则

权限配置的结构

settings.json 里的 permissions 字段,包含三个数组:

{  "permissions": {    "allow": [],   // 自动执行,不询问    "ask":   [],   // 执行前暂停,等你确认    "deny":  []    // 完全禁止,拒绝执行  }}

规则格式是 操作类型(匹配模式),支持通配符:

操作类型说明示例
Bash终端命令Bash(git status)
Edit修改已有文件Edit(src/**/*.ts)
Write创建新文件Write(src/**/*.tsx)
Read读取文件Read(README.md)
WebFetch抓取网页WebFetch(domain:github.com)

冒号在 Bash 规则里有特殊含义:Bash(git log:*) 表示允许 git log任意参数,而 Bash(git log) 只允许不带参数的裸命令。这个细节很容易忽略,但影响很大。

一份真正好用的全局配置

下面这份配置,是我在 iOS + Vue/TypeScript 的开发栈上磨合出来的版本。

核心策略:读操作全放行,源码编辑按路径放行,写操作和构建命令按风险分级,破坏性操作一律 deny

{  "permissions": {    "allow": [      "Bash(git status)",      "Bash(git log:*)",      "Bash(git diff:*)",      "Bash(git add:*)",      "Bash(git stash:*)",      "Bash(git branch:*)",      "Bash(git switch:*)",      "Bash(git checkout:*)",      "Bash(swift build:*)",      "Bash(swift test:*)",      "Bash(swift run:*)",      "Bash(xcodebuild:*)",      "Bash(npm test:*)",      "Bash(npm run lint:*)",      "Bash(npm run dev:*)",      "Bash(npm run typecheck:*)",      "Bash(npx tsc:*)",      "Bash(bun run:*)",      "Bash(bun test:*)",      "Bash(node:*)",      "Bash(python3:*)",      "Bash(mkdir -p:*)",      "Bash(cp:*)",      "Bash(mv:*)",      "Bash(cat:*)",      "Bash(echo:*)",      "Bash(ls:*)",      "Bash(find:*)",      "Bash(grep:*)",      "Bash(wc:*)",      "Bash(which:*)",      "Bash(gh api:*)",      "Bash(gh repo:*)",      "Bash(xcodegen generate:*)",      "WebSearch",      "WebFetch(domain:developer.apple.com)",      "WebFetch(domain:developers.figma.com)",      "WebFetch(domain:github.com)",      "WebFetch(domain:raw.githubusercontent.com)",      "Read(**)",      "Edit(src/**)",      "Edit(Sources/**)",      "Edit(Tests/**)",      "Edit(tests/**)",      "Write(src/**)",      "Write(Sources/**)",      "Write(Tests/**)"    ],    "ask": [      "Bash(git commit:*)",      "Bash(git push:*)",      "Bash(git merge:*)",      "Bash(git rebase:*)",      "Bash(npm install:*)",      "Bash(npm run build:*)",      "Bash(pod install:*)",      "Bash(brew install:*)",      "Edit(package.json)",      "Edit(Package.swift)",      "Edit(Podfile)",      "Edit(tsconfig.*)",      "Edit(vite.config.*)",      "Write(**)"    ],    "deny": [      "Bash(rm -rf:*)",      "Bash(sudo:*)",      "Bash(curl * | *)",      "Bash(wget * | *)",      "Write(/Users/changyou/.ssh/*)",      "Edit(.env.production)",      "Edit(.env.prod)",      "Read(.env.production)"    ]  }}

把这份内容写入 ~/.claude/settings.json,对你机器上的所有项目立即生效。

哪些操作留在 ask,不是随意的

ask 里的每一条规则都有原因,不是懒得配置:

** / **:提交和推送是有历史记录的操作,AI 生成的 commit message 质量参差不齐,push 之后改起来麻烦,留一个确认节点是值得的。

** / **:安装依赖会修改 lock 文件,引入外部包,需要人工感知,不应该静默发生。

****:构建产物可能直接影响部署,尤其是 CI/CD 流程里,一个无意触发的 build 可能带来副作用。

配置文件(、、):这些文件的改动是全局性的,牵一发动全身,每次都看一眼没坏处。

deny 的几个设计细节

** 而不是 **

很多人会把 .env* 全部 deny,然后发现 .env.local 也编辑不了了,开发寸步难行。只 deny 生产环境的配置文件,本地开发的 .env.local.env.development 正常放行。

** 用绝对路径**

JSON 文件里的 ~ 不会被展开,~/.ssh/* 这条规则其实是无效的。用绝对路径才能真正生效。

** 和 **

拦截的是管道执行模式——把下载内容直接 pipe 给 shell 执行,这是最经典的供应链攻击手法。单纯的 curl 下载文件不受影响。

配置之后的实际变化

一个典型的功能迭代循环,配置前后的体验差别非常明显:

配置前:写代码 → 问你能不能保存 → 你确认 → 跑测试 → 问你能不能执行 → 你确认 → 检查 lint → 问你能不能运行 → 你确认。一个来回三次打断,Claude Code 退化成了一个需要人肉看管的工具。

配置后:Claude Code 独立完成"修改代码 → 保存 → 跑测试 → lint 检查"这整个循环,只在你要 commit 的时候停下来让你看一眼。你喝杯咖啡回来,任务已经完成了大半。

这才是 agentic 工具该有的样子。

一个要记住的判断原则

在决定一条规则放 allow 还是 ask 时,问自己一个问题:

这个操作如果 AI 执行出错,修复成本有多高?

  • • 读文件、搜索、查看目录:成本为零,无脑 allow
  • • 编辑源码:可以 git 回滚,allow 没问题
  • • 安装依赖、提交代码:有副作用,放 ask
  • • 删除文件、执行 sudo、修改生产配置:不可逆,放 deny

权限配置不是一次性工作。随着项目演进,你会遇到新的工具、新的目录结构,规则也要跟着调整。每次遇到"这个操作好像不该每次都问我",就是更新配置的信号。

把 AI 工具真正用好,从来不是"开箱即用"的事。

给它一个合理的边界,它才能在那个边界里跑得更快。

2026.03.25 17:06 沪 · 赵巷

📌 声明:本文由 AI 辅助完成