权限系统
六种模式 + 细粒度规则,安全地把活交给 AI
权限不是束缚,是让你敢放手让 AI 干活的底气扩展篇到此为止。进入控制篇 —— 权限系统是安全地把 AI 交出去的基础:六种模式 + 细粒度规则,让你敢放手让 AI 干活。
怕它乱来
AI 能改文件、能跑命令——万一改坏或删错怎么办
担心删库
AI 跑 shell 命令时,万一执行了 rm -rf 或 git push --force,损失不可逆。
担心改坏配置
AI 修改 .git、.env、CI 配置这类敏感文件,可能让项目直接挂掉。
自动化时没人盯
在 CI 跑 AI,没人能确认每一步——既想让它自主,又怕失控。
三种结果
每次工具调用前,权限系统给出三种裁决之一
Qoder CLI 在每次工具调用前做权限检查,结果只有三种:
| 结果 | 含义 | 行为 |
|---|---|---|
allow | 允许 | 立即执行工具 |
ask | 询问 | 交互式会话弹确认;非交互式转为拒绝 |
deny | 拒绝 | 阻止这次工具调用 |
权限适用于所有工具:文件读写、Bash 命令、Web 抓取、MCP 工具、子代理调用等。
六种模式
用 --permission-mode 选择会话的默认行为
| 模式 | 适用场景 | 行为 |
|---|---|---|
default |
常规交互式使用 | 安全读取自动执行;敏感操作请求确认 |
accept_edits |
日常编码任务 | 自动批准工作目录内的安全文件编辑 |
plan |
评审、排查、规划 | 偏规划,写入需批准 |
auto |
不弹确认的自动化 | 不弹窗,安全操作自动批,风险操作拒 |
bypass_permissions |
仅可信本地实验 | 跳过大多数批准(仍非无条件放行) |
dont_ask |
必须不弹窗的 headless | 从不询问,需询问的一律拒绝 |
default,嫌确认烦用 accept_edits,做 CI 自动化用 auto 或 dont_ask。其余两个进阶再用。
模式怎么选
不同场景下的推荐选择
本地开发(default)
新手默认。读取自动通过,写文件和跑命令要确认。最安全,适合学习阶段和敏感项目。
日常编码(accept_edits)
写代码时最常用。文件编辑不再逐个确认,但危险 shell 命令仍会问。效率与安全的平衡点。
代码审查(plan)
只想让 AI 看和分析,不想它改东西。读取顺畅,写入受控。review 场景首选。
CI 自动化(auto / dont_ask)
无人值守。auto 自动批准安全操作、拒绝风险操作;dont_ask 更严格,需询问的一律拒。第 14 章详解。
--dangerously-skip-permissions(也叫 --yolo)。只在完全可信的沙盒环境用,且部分安全检查仍会拦截危险操作——它不是无条件放行。
设置默认
不想每次启动都带参数,就持久化配置
用 --permission-mode 只对本次会话生效。想持久默认值,在 settings 里配置:
{
"general": {
"defaultPermissionMode": "accept_edits"
}
}
default。bypass_permissions 还可能被安全设置禁用。
default、accept_edits、plan、auto。需要 bypass 时,通过命令行参数启动而非写进默认配置——避免你忘了自己开着 bypass。
决策顺序
权限判定的优先级,理解它才能写对规则
Qoder 按固定顺序评估权限,早判断的优先:
- 先检查
deny规则——命中直接拒 - 在
auto模式下,必须直接得到 allow 或 deny,不弹窗 ask规则和工具自身检查,先于宽泛 allow 执行- 安全检查仍可能中断宽泛规则或 bypass 模式
- 再应用工具级
allow规则和模式自动允许 - 非交互式会话中,结果仍是 ask 会转为 deny
配置规则
持久权限规则写在 settings 文件中
规则按 allow、ask、deny 三组组织,写在以下文件:
~/.qoder/settings.json # 用户级(所有项目)
${project}/.qoder/settings.json # 项目级(团队共享,提交 Git)
${project}/.qoder/settings.local.json # 本地级(个人,不提交)
{
"permissions": {
"allow": [
"Read(/src/**)",
"Edit(/src/**)",
"Bash(npm run test:*)"
],
"ask": [
"Bash(npm publish:*)",
"WebFetch"
],
"deny": [
"Read(*.pem)",
"Bash(rm -rf:*)"
]
}
}
settings.local.json)放个人审批,加进 .gitignore。
规则语法
三种形式,覆盖从粗到细的需求
| 形式 | 含义 | 示例 |
|---|---|---|
ToolName | 作用于整个工具 | WebFetch |
ToolName(content) | 作用于特定路径/命令/模式 | Read(/src/**) |
* | 工具级匹配所有工具 | * |
规范工具名:Read、Edit、Write、Bash、Grep、Glob、WebFetch、WebSearch、Agent,以及 mcp__github__create_issue 这类 MCP 工具名。
"Bash(python -c \"print\\(1\\)\")"
ToolName(*) 会被视为工具级规则,等同于 ToolName。
文件规则
用路径模式精确控制读写范围
读取规则用 Read(...),写入规则用 Edit(...)(覆盖 Edit/Write/NotebookEdit)。某路径的 Edit allow 会隐含允许读取同路径。路径用 gitignore 风格匹配:
| 模式 | 含义 |
|---|---|
/src/** | 相对规则源根目录的路径(项目级相对项目根) |
~/Documents/** | 相对 home 目录 |
//tmp/data/** | 从系统根 / 开始的绝对路径(双斜杠) |
*.secret | 不带根的文件名模式,任意位置匹配 |
"deny": [
"Read(*.pem)", // 禁止读密钥
"Edit(/.git/**)", // 禁止改 git 内部
"Edit(//etc/**)" // 禁止改系统配置
]
.git、.vscode、.idea、.husky、.mcp.json、.bashrc 等会改变执行行为或凭据的路径,默认模式下需明确批准,auto 模式下直接拒绝。
Bash 规则
最需要细控的工具——精确匹配、前缀、通配
| 规则 | 匹配内容 |
|---|---|
Bash(npm run build) | 精确匹配这条命令 |
Bash(npm run test:*) | 匹配 npm run test 及以其开头的命令 |
Bash(git log *) | glob 风格通配 |
"allow": ["Bash(git status)", "Bash(git log:*)", "Bash(npm run test:*)"],
"ask": ["Bash(npm publish:*)", "Bash(git push:*)"],
"deny": ["Bash(rm -rf:*)", "Bash(sudo:*)"]
deny和ask穿透 wrapper 和环境变量前缀——Bash(rm -rf:*)能拦截被包装的破坏性命令- 前缀/通配 allow 不会静默批准复合命令,除非每个片段都能独立允许
- 危险命令(破坏性删除、force push)即使有宽泛 allow 仍可能强制确认;
auto模式下直接拒
Bash 或 Bash(*) 这种宽泛规则——等于把整个 shell 开放,极其危险。
Web 与 MCP
网络访问和外部工具的权限控制
Web 工具
用工具级规则控制。所有 fetch 都确认用 ask,禁网用 deny:
{
"ask": ["WebFetch"],
"deny": ["WebSearch"]
}
某些项目或会话要完全断网,deny WebFetch 即可。
MCP 工具
用完整限定名 mcp__<server>__<tool>:
{
"allow": ["mcp__context7__*"],
"ask": ["mcp__github__create_issue"]
}
支持 mcp__github__*(某 server 全部)、mcp__*(所有 MCP)。
--allowed-mcp-server-names context7,github。或在 server 配置里用 alwaysAllow 自动放行。
覆盖与 CI
命令行一次性覆盖 + 非交互式场景
命令行覆盖(一次性会话):
qodercli --permission-mode accept_edits
qodercli --allowed-tools 'Read,Grep,Bash(git status)'
qodercli --disallowed-tools 'Bash(rm -rf:*),mcp__github__delete_repo'
qodercli --tools 'Read,Grep,Edit' # 限制本次可用工具
非交互式会话(print mode、CI)的特殊处理:
- 无法弹确认,任何
ask都转为deny - 自动化时优先配置精确的 allow 规则,而非依赖模式
- 需要编辑文件用
accept_edits - 要严格 fail-closed 用
dont_ask - 可信环境确需宽泛执行才用
bypass_permissions
auto 或 dont_ask 模式。这是"既自主又安全"的标准组合,第 14 章会完整演示。
排错指南
权限相关的高频问题
accept_edits 没生效
原因:当前目录未受信任,回退成了 default。修复:先信任该目录;或在可信目录运行。
allow 规则没放行
原因:规则语法错(括号没转义)、路径模式不对、或被 deny/安全检查优先拦截。修复:核对语法;用 /config 看生效规则;deny 优先于 allow,检查是否冲突。
CI 里 AI 啥都做不了
原因:非交互式 ask 转 deny,没配 allow 规则。修复:在项目 settings 加精确 allow;或用 accept_edits/auto 模式。
危险命令还是被拦
这是设计如此,不是 bug。即使 bypass 模式,危险 shell 仍可能被安全检查拦截。如确需执行,在可信环境手动跑。
动手练习
为你的项目搭一套合理的权限配置
练习 1:体验不同模式
- 分别用
default和accept_edits启动 - 让 AI 改同一个文件,感受确认次数的差异
练习 2:写项目权限规则
- 在
.qoder/settings.json配置:allow 常用测试命令、deny 危险命令 - 禁止读写
*.pem和.env
练习 3:只读会话
- 用
--permission-mode plan启动 - 让 AI 分析项目,观察它无法改文件
- 体会 plan 模式在 review 中的价值
本章回顾
带走的三个核心认知
三种结果六种模式
allow/ask/deny 三种裁决,default/accept_edits/plan/auto/bypass/dont_ask 六种模式。
规则可细到路径和命令
Read/Edit 按路径,Bash 按命令前缀,MCP 按 server/tool。deny 永远优先。
CI 用精确 allow + auto
非交互式 ask 转 deny,所以自动化要预先配好 allow 规则。
下一章,学习 Quest 模式——在权限保护下,把一个完整需求端到端委派给 AI。
延伸阅读
继续本课程
- 下一章:Quest 模式 — Spec 驱动的自主委派
- 高级特性 — CI/CD 中权限的实战应用
- 钩子 — 和权限配合的自动化检查
官方资源
- 权限官方文档 — 完整规则语法与判定顺序