了解 Qoder CLI 的权限模式、规则配置和工具调用审批流程。
权限模式
权限模式决定了 Qoder 如何处理工具调用——每种模式在"自动化程度"和"安全宽松度"两个维度上定位不同。
| 模式 | 适用场景 | 行为 |
|---|---|---|
default | 常规交互式使用 | 安全读取和内部动作可自动执行;敏感操作请求确认。 |
accept_edits | 日常编码任务 | 自动批准工作目录内的安全文件编辑。Shell 命令、外部动作和敏感路径仍走正常检查。 |
auto | 无人值守执行 | 由 agent 智能决策授权。 |
bypass_permissions (YOLO) | 仅用于可信本地实验 | 跳过批准提示。少量路径形状保护仍然生效 —— 见「路径形状」。 |
dont_ask | 必须不弹窗的 headless 流程 | 从不询问。任何原本需要询问的动作都会被拒绝。 |
模式循环切换
在交互式会话中,按 Shift+Tab 在所有权限模式间循环切换。按 Ctrl+Y 可直达 YOLO 模式。
启动参数
使用 --permission-mode 选择当前会话的默认行为:
| 标准值 (snake_case) | camelCase | 别名 |
|---|---|---|
accept_edits | acceptEdits | — |
bypass_permissions | bypassPermissions | yolo, YOLO |
dont_ask | dontAsk | — |
default。
权限如何决策
Qoder 在每次工具调用前做权限检查。权限结果只有三种:
allow:立即执行工具。ask:需要外部确认后才能执行。deny:阻止这次工具调用。
决策顺序
Qoder 按固定顺序评估权限:
- 先检查
deny规则——命中即拒绝。 - 工具自身的安全检查(如危险命令检测、敏感路径检测)。
ask规则——命中则标记为需要确认。- 工具级
allow规则和模式带来的自动允许行为。 - 如果最终结果仍是
ask,由运行环境决定如何消费。
不同运行环境下 ask 的消费方式
| 运行环境 | ask 的归宿 | 说明 |
|---|---|---|
| TUI(交互式终端) | 弹窗确认 | 用户在终端中选择允许/拒绝。 |
Headless(-p/--prompt) | 自动拒绝 | 无人交互,ask 转为 deny。 |
| SDK(stdio 协议) | 发送 canUseTool 回调给宿主 | 宿主程序决定 allow/deny。 |
| ACP(IDE 集成) | 发送 requestPermission RPC 给 IDE | IDE 弹窗或自动决策。 |
-p/--prompt)下,可以搭配权限模式使用:
权限配置
配置来源(8 层优先级)
规则从多个来源合并,按优先级从低到高:
| 层级 | 来源 | 说明 |
|---|---|---|
| 1 | userSettings | ~/.qoder/settings.json(用户全局) |
| 2 | projectSettings | <project>/.qoder/settings.json(项目级,团队共享) |
| 3 | localSettings | <project>/.qoder/settings.local.json(本机个人,加入 .gitignore) |
| 4 | flagSettings | --settings <path> CLI 参数指定的文件 |
| 5 | cliArg | --allowed-tools / --disallowed-tools 命令行参数 |
| 6 | command | /allow、/deny 会话中命令 |
| 7 | session | 运行时临时规则(弹窗中“本次会话允许”) |
allowManagedPermissionRulesOnly,则只使用策略托管的规则。
各来源的配置方式:
- 层级 1-3(settings 文件):在对应路径的 JSON 文件中写入
permissions.allow/permissions.deny/permissions.ask数组。settings.local.json适合存放本机个人审批规则,建议加入.gitignore。 - 层级 4(flagSettings):
qoder --settings ./custom-settings.json,指定额外的 settings 文件路径。该文件格式与标准 settings.json 相同。 - 层级 5(cliArg):通过
--permission-mode、--allowed-tools、--disallowed-tools、--tools等命令行参数配置,仅作用于当前会话。 - 层级 6(command):会话中输入
/allow Bash(npm test)或/deny WebFetch,持久化到settings.local.json。 - 层级 7(session):弹窗中选择“本次会话允许”产生的临时规则,进程退出后失效。
模式配置
设置默认模式——在 settings 中配置 general.defaultPermissionMode:
| 值 | 行为 | 别名 |
|---|---|---|
default | 每次操作都提示确认 | — |
accept_edits | 自动批准文件编辑,Shell 命令仍需确认 | acceptEdits |
plan | 只读模式(兼容旧版,实际转为 default + Plan 工作状态) | — |
auto | 由 agent 智能决策授权 | — |
bypass_permissions | 跳过权限提示(YOLO) | yolo、bypassPermissions |
dont_ask | 非交互模式,需要确认的操作直接拒绝 | dontAsk |
--yolo、--permission-mode bypass_permissions 和 Ctrl+Y 均不可用,Shift+Tab 循环也会跳过该模式。子 agent 声明 bypass 时也会被降级为 acceptEdits。
禁用 Plan 模式——如果不需要 Plan 工作流,可以关闭:
/plan 命令不可用,--permission-mode plan 回退为 default,EnterPlanMode/ExitPlanMode 工具不注册。
Auto 模式分类器配置——可以通过自然语言规则引导 AI 分类器的判断倾向:
| 字段 | 作用 |
|---|---|
allow | 分类器倾向于自动批准的操作描述 |
soft_deny | 分类器倾向于拒绝的操作描述 |
environment | 提供给分类器的环境上下文信息 |
autoMode 配置只从你自己的全局 settings 读取。工作区下的文件一律忽略,包括 settings.local.json:工作区里的任何文件都可能随检出一起到来,而能往分类器塞 allow 条目就能把 auto 模式偏向放行。
用户级 AGENTS.md 同样注入分类器上下文,作为判断本次会话意图的依据。仅读取用户级文件。其内容用于说明意图,不构成授权:与安全规则冲突的动作,即使该文件看似许可,仍会被阻塞。
不经分类器判定的动作
- 只读工具(读取文件、搜索、通配匹配)按工具名放行,不校验目标路径,工作目录之外的路径同样放行。
- 工作目录内、以及通过
/add-dir加入的目录内的写入与编辑,直接放行。 - 其余动作全部提交分类器判定,包括写入上述目录之外的路径。
auto 模式下工具调用由 agent 判定授权,不逐项征求确认。连续判定阻塞达到上限时触发熔断:下一次动作转为授权弹窗,其中给出上限告警与最近一次阻塞原因,模式本身保持可用;出现一次放行后计数清零。
熔断是 auto 模式下由权限判定引发授权弹窗的唯一情形。分类器不可达或未返回可用判定时,该次动作被拒绝而不转为弹窗,提示中会说明这不是对该动作的安全判定,可原样重试,只读工具不受影响;无可用分类器模型时拒绝切入 auto 模式。
此外,需要用户输入的工具(如 AskUserQuestion)以及进入和退出 Plan 始终请求确认,会话过长导致分类器无法读取完整上下文时同样转为确认,这些均不属于权限判定的结果。
权限规则配置
规则按 allow、ask 和 deny 分组:
规则语法
| 形式 | 含义 |
|---|---|
ToolName | 作用于整个工具。 |
ToolName(content) | 作用于某个路径、命令、agent 类型,或工具支持的其他特定内容。 |
* | 匹配所有工具。 |
Read、Edit、Write、Bash、Grep、Glob、WebFetch、WebSearch、Agent,以及 mcp__github__create_issue 这类 MCP 工具名。
如果内容中包含括号,需要转义:
ToolName(*) 等同于 ToolName(工具级规则)。
命令行覆盖
--allowed-tools 和 --disallowed-tools 使用与 settings 相同的规则语法。--tools 限制本次运行可用的内置工具集(未列出的工具会被拒绝)。
信任目录
Qoder 将启动时的当前工作目录(CWD)视为主信任目录。在信任目录内:
- 文件读取默认 allow
- 文件写入在
accept_edits和auto模式下可自动批准 - 非默认权限模式(auto、bypass 等)才能生效
default 模式。
扩展信任范围
通过 --add-dir、/add-dir 命令或 permissions.additionalDirectories 增加额外可信工作目录:
permissions.trustDirectories 将常用目录永久信任。
受保护路径
部分路径受到保护,因为编辑它们可能改变执行行为、凭据或工具行为。例如 .git、.vscode、.idea、.husky、大多数 .qoder 配置文件、.bashrc/.zshrc 等 shell 启动文件、Git 配置、.mcp.json、.ripgreprc。在常规交互式模式下,这些路径需要明确批准。
路径形状
某些路径写法能触达本地文件系统之外的资源,或绕过路径比较。它们不走规则,按两条独立的轴单独处理。
- 网络位置 —— 以两个分隔符开头的路径(
\server\share、//server/share)、扩展 UNC 形式(\?\UNC\server\share)、WebDAV 写法,以及/net/<host>/…自动挂载路径。读取、搜索、写入与 Shell 访问一律拒绝。 - 本地挂载 ——
\wsl$\…、\wsl.localhost\…、\?\C:\…与\?\Volume{…}\…指向本地存储,按常规规则处理。回环主机如\127.0.0.1\share仍算网络位置。 - 易绕过写法 —— 交替数据流(
file.txt:stream)、8.3 短名(PROGRA~1)、设备路径(\.\…)、尾随点或空格、三个及以上连续点、保留设备名(CON、NUL、COM1)需要显式批准。
文件访问规则
带路径范围的读取规则使用 Read(...)。带路径范围的写入规则使用 Edit(...);它覆盖 Edit、Write 和 NotebookEdit 的文件写入检查。某个路径上的 Edit(...) allow 规则也会隐含允许读取同一路径。
文件规则使用 gitignore 风格匹配。
| 模式 | 含义 |
|---|---|
/src/** | 基于规则来源根目录的路径。在 project/local settings 中相对于项目根目录;在 user settings 中相对于 home 目录。 |
~/Documents/** | 基于 home 目录的路径。 |
//tmp/data/** | 从系统 / 开始的绝对路径。绝对路径需要使用双斜杠。在规则模式里,前导 // 表示「从文件系统根开始的绝对路径」,与上文的网络位置处理无关。 |
*.secret | 不带根目录的文件名模式,可在任意位置匹配。 |
Bash 规则
Bash(...) 规则可以匹配精确命令、命令前缀或通配模式。
| 规则 | 匹配内容 |
|---|---|
Bash(npm run build) | 精确匹配 npm run build。 |
Bash(npm run test:*) | 匹配 npm run test 以及以 npm run test 开头的命令。 |
Bash(git log *) | 使用 glob 风格通配匹配。 |
Bash(git status) | 精确匹配 git status。 |
deny和ask规则会穿透常见 wrapper 和环境变量前缀,因此Bash(rm -rf:*)仍能拦截被包装过的破坏性命令。- 前缀和通配
allow规则不会静默批准复合命令,除非每个顶层命令片段都能独立被允许。 - 部分可证明只读的 shell 命令,在 deny、ask 和路径检查之后可以被自动允许。
- 危险命令(如破坏性删除或 force push),即使存在宽泛 allow 规则,也可能强制确认。
Bash 或 Bash(*) 这类宽泛规则。
Web 和 MCP 规则
Web 工具可以用工具级规则控制。若所有 web fetch 都需要确认,用 ask;若某个会话或项目应禁用网络访问,用 deny。
| 规则 | 含义 |
|---|---|
mcp__github__create_issue | 单个 MCP 工具。 |
mcp__github__* | github MCP server 下的所有工具。 |
mcp__github | github MCP server 下的所有工具。 |
mcp__* | 所有 MCP 工具。 |
alwaysAllow 为该 server 的工具设置自动允许。如果一次运行只想启用指定 MCP server,可以使用 --allowed-mcp-server-names。
子代理规则
Agent 规则控制子代理(Subagent)的启动。规则内容为子代理名称,匹配时不区分大小写。三种行为均受支持,判定顺序为 deny > ask > allow;未配置匹配规则时,子代理直接启动,不弹出确认框。
| 规则 | 含义 |
|---|---|
Agent | 适用于所有子代理启动。 |
Agent(general-purpose) | 适用于指定名称的子代理,名称匹配不区分大小写。 |
- 命中
deny规则时,启动被拒绝。 - 命中
ask规则时,子代理启动前弹出确认框征询授权。 - 命中
allow规则时,显式记录批准;效果与未配置规则相同。
/agents 查看内置子代理清单和已安装的子代理,其名称即可用于 Agent(...) 规则。
Hook 与权限
Qoder 的 Hook 系统在权限决策链路中有两个注入点,可以通过自定义脚本影响工具的允许/拒绝行为。
影响权限的 Hook 事件
| Hook 事件 | 触发时机 | 可产生的权限影响 |
|---|---|---|
PreToolUse | 工具执行前(权限检查阶段) | 可返回 `permissionDecision: "allow" |
PermissionRequest | 权限管道产出 ask 后、弹窗前 | 可返回 decision.behavior 为 allow 或 deny,代替用户交互 |
PostToolUse、SessionStart、Stop 等)不参与权限决策。
PreToolUse Hook
在工具执行前触发。Hook 脚本可以检查工具名和参数,返回权限决策:
tool_name、tool_input、session_id 等),通过 stdout 输出 JSON 结果:
permissionDecision 可选值:
"allow":跳过权限管道,直接批准"deny":跳过权限管道,直接拒绝"ask":继续走正常权限管道(默认行为)
PermissionRequest Hook
在权限管道产出 ask 之后、弹窗/回调之前触发。适合用于自动化审批系统或外部通知(如 Slack/邮件提醒):
Hook 与权限模式的优先级
Hook 的权限决策优先级高于权限模式——即使在 bypass_permissions 模式下,PreToolUse Hook 返回 deny 仍然会阻止执行。这为组织级安全策略提供了不可绕过的拦截能力。
执行顺序:
- Hook
PreToolUse→ 如果返回 allow/deny,短路 - 权限管道(规则 + 模式 + 安全检查)
- 如果结果是
ask→ HookPermissionRequest→ 如果返回 allow/deny,短路 - 最终由运行环境消费
ask(弹窗/deny/回调)

