阶段 | 检查项 | 命中后行为 |
0 | Hooks / 交互型工具特例 | PreToolUse 可直接 allow / deny / ask;AskUserQuestion 这类工具本身就要求交互 |
1 | Deny 规则 | 立刻拒绝,最高优先级 |
2 | 可信 Allow 规则(user / CLI / session / policy / 已信任项目规则 / --allowedTools) | 立刻放行,且可越过交互态危险命令检查 |
3 | 命令安全检查(仅交互式) | 高危 Bash 命令强制进入 ask |
4 | Ask 规则 | 强制 ask |
5 | Bypass 模式短路 | bypassPermissions 在这里放行大多数动作;若已被禁用则退化 |
6 | 不可信 Allow 规则(未信任项目规则、command / sandbox 来源) | 可放行,但不能越过上一步危险命令检查 |
7 | 权限模式基线策略 | |
8 | 非交互兜底 | 无法弹审批框时,把 unresolved ask 转成 deny |
9 | dontAsk / auto 最终收口 | dontAsk 把 ask 改写为 deny;auto 只接管 ask 并交给分类器 |
deny 永远优先。allow 分成“可信 allow”和“不可信 allow”两层。项目目录在您显式信任前,仓库内 .codebuddy/settings.json / .codebuddy/settings.local.json 的 allow 规则不能越过危险命令检查,目的是防止恶意仓库把自己的 settings 提交进来后悄悄放宽本地安全边界。auto 不是整条链的替代品,它只处理“最后仍然会 ask 的动作”;显式 ask 规则不会进入 classifier。deny / ask / allowdefault / acceptEdits / auto / dontAsk / ...deny 会先于任何 mode 生效ask 规则会先于 auto 生效,因此仍然需要人工确认dontAsk 不会绕过规则;它只是把最后得到的 ask 改写成 denybypassPermissions 也不会抹掉前置规则;deny / ask 仍可能拦住它bypassPermissions 下,也可能因为安全检查而进入 askpermissions 对象下三个数组对应三种行为:{"permissions": {"allow": ["Bash(npm test)", "Read(/tmp/data/**)"],"ask": ["WebFetch"],"deny": ["Bash(rm -rf *)", "Edit(.git/**)"]}}
allow:CodeBuddy 可使用且无需弹审批ask:每次使用都弹审批deny:绝不能使用/permissions 命令/permissions 打开权限管理面板,可以查看当前所有 allow / ask / deny 规则、它们来自哪一层 settings,并临时增删(写到 user / project 或 project-local 任一作用域)。弹窗里勾选 "Yes, don't ask again" 时,CodeBuddy 会把当前命令对应的最稳前缀写入对应作用域 settings 的 allow 数组。参数 | 作用 |
--allowedTools <tools...> | 进程级临时 allow 规则。空格或逗号分隔。例: --allowedTools "Bash(git:*) Edit" |
--disallowedTools <tools...> | 进程级临时 deny 规则。同上 |
--add-dir <path> | 把额外目录加入信任目录范围(影响 Read 是否需要弹询问) |
-y / --dangerously-skip-permissions | 等价于 --permission-mode bypassPermissions |
作用域 | 路径 |
user | ~/.codebuddy/settings.json |
project | <repo>/.codebuddy/settings.json(提交进 git) |
project-local | <repo>/.codebuddy/settings.local.json(不进 git,本地覆盖) |
cliArg / flagSettings / session / policySettings | 进程态,不落盘 |
Tool 或 Tool(specifier)。规则 | 含义 |
Bash | 所有 Bash 命令 |
WebFetch | 所有 web 抓取 |
Read | 所有文件读 |
Edit | 所有文件编辑 |
规则 | 匹配 |
Bash(npm run build) | 精确匹配 npm run build |
Bash(npm:*) 或 Bash(npm *) | npm 开头的所有命令 |
Read(./.env) | 当前目录的 .env |
Edit(/src/**/*.ts) | 项目根下 src/**/*.ts |
Read(~/.zshrc) | 用户目录的 .zshrc |
Read(//tmp/scratch.txt) | 文件系统绝对路径 /tmp/scratch.txt |
WebFetch(domain:example.com) | 抓取 example.com |
mcp__puppeteer__navigate | MCP 工具 puppeteer 服务的 navigate |
Agent(Explore) | 子代理 Explore |
语法 | 含义 | 示例 |
精确匹配 | pattern 完全等于命令 | Bash(npm run build) 仅匹配 npm run build |
:* 前缀 | pattern 末尾 :* → 匹配命令第一个词 / 多词前缀 | Bash(git:*) 匹配 git status / git push origin main |
通配符 | pattern 含 * 时按 bash glob 模式匹配(*** 可跨 /**) | Bash(npm run *) 匹配 npm run build;Bash(ls *) 匹配 ls -al /tmp/x |
* 能跨越 / —— 否则 ls * 无法匹配 ls -al /xxx,这是用户最常踩的坑。&& / || / ; / |,对每个子命令独立判定:allow: ["Bash(git:*)"]git status → 允许git status && rm * → 询问(rm * 不在 allow 内,需所有子命令都命中)git status; rm * → 询问(同上)
> / < / >> / << / &> 的命令在 allow 规则下要求精确匹配,通配符规则不生效。pattern | 解释 | 示例 |
//path | 文件系统绝对路径 | Read(//etc/hosts) |
~/path | 用户目录起 | Read(~/.zshrc) |
/path | 项目根起 | Edit(/src/**/*.ts) |
path 或 ./path | 当前工作目录起 | Read(.env) |
Edit(.git/**) 之类的 deny 规则会阻挡所有走 Edit / Write / NotebookEdit 的尝试;但不阻挡通过 Bash 跑 python -c 'open(".git/config", "w")...' 这类间接路径 ,操作系统级保护需要靠 Bash 沙箱cat、head、tail 等)拦截解析WebFetch # 任何 URLWebFetch(domain:example.com) # 仅 example.com 及子域
domain: 前缀做主机名匹配(含子域)。mcp__<server>__<tool>,用双下划线 __ 分段(名字里的单下划线只是普通字符)。四种写法:规则 | 匹配 |
mcp__puppeteer | 前缀为 mcp__puppeteer__ 的全部工具 |
mcp__puppeteer__* | 同上,两者等价 |
mcp__puppeteer__navigate | 仅 navigate 一个工具 |
mcp__* | 全部 MCP 工具,仅 deny / ask 生效 |
mcp__web-search 与 mcp__web_search 等价* 只能整段替换最后一节。mcp__pup*、mcp__puppeteer__nav* 匹配不到任何工具,而且不会报错mcp__ 开头的规则,裸 * 对它无效;要全部禁用请写 "deny": ["mcp__*"]{"permissions": {"deny": ["Agent(Explore)", "Agent(Plan)"]}}
codebuddy --disallowedTools "Agent(Explore) Agent(Plan)"
subagent_type 会被拒。{"permissions": {"deny": ["Skill(dangerous-skill-name)"]}}
方式 | 持久度 |
--add-dir <path> 启动参数 | 进程级 |
会话内 /add-dir 命令 | 会话级 |
Web UI 添加目录( /api/v1/workspace-dirs) | 进程级(前端持久化) |
permissions.additionalDirectories 配置项 | 持久化 |
permissions.trustedDirectories 配置项 | 持久化 |
settings.trustedDirectories + 启动时 --add-dir / 会话内 /add-dir / Web UI 添加的目录。--add-dir 和 permissions.additionalDirectories 都只授予文件访问权,不会让 CodeBuddy 加载这些目录里的 .codebuddy/ 配置(agents / hooks / settings 等都仍以启动目录的为准)。<repo>/.codebuddy/settings.json 与 .codebuddy/settings.local.json 里的 allow 规则会被归到不可信层(Phase 6),不能越过命令安全检查.git、.gitconfig、.gitmodules.bashrc / .zshrc / .envrc 等.npmrc / .yarnrc / bunfig.toml 等.vscode / .idea / .husky / .devcontainer.codebuddy(除 .codebuddy/worktrees).mcp.json / .codebuddy.jsonbypassPermissions 模式仍然会让其中绝大部分通过,但 rm -rf / / rm -rf ~ 这类"灾难性命令"会被强制询问。{"hooks": {"PreToolUse": [{"matcher": "Bash","hooks": [{ "type": "command", "command": "/path/to/bash-policy.sh" }]}]}}
退出码 | 行为 |
0 + JSON 决策 | 按 JSON 里的 permissionDecision(allow / ask / deny)执行 |
2 | 阻断(stderr 内容回填给模型) |
其他非 0 | 非阻断错误(提示但放行) |
PreToolUse 的结构化 permissionDecision 会在常规权限规则前生效:allow / deny / ask 分别直接放行、拒绝或强制询问permissions.deny,便于在 /permissions 和 settings 中统一审计deny 规则阻挡 CodeBuddy 主动尝试受限工具domain: allow 规则与沙箱 allowedDomains 都生效,最终边界取交集flagSettings / cliArg / session > userSettings > policySettings >projectSettings > localSettings > command/sandbox 来源
deny 数组从所有作用域合并,任一作用域 deny 即拒allow 数组按“可信 / 不可信”分两次合并:可信合并里 user / cli / flag / session / policy 永远在;project / local 仅在目录被信任时算可信disableBypassPermissionsMode 在 user / project / local / CLI 启动参数四层任一为 "disable" 即生效{"permissions": {"defaultMode": "default","allow": ["Bash(npm test)","Bash(npm run lint)","Read(/src/**)","Read(/test/**)"],"deny": ["Bash(rm:*)","Bash(curl:*)","Bash(wget:*)","Edit(.git/**)","Edit(/.codebuddy/**)"]}}
{"permissions": {"defaultMode": "bypassPermissions","deny": ["Bash(rm -rf /:*)","Bash(sudo:*)","Bash(curl * -o /etc/*)","WebFetch(domain:internal-corp.example)"]}}
<repo>/.codebuddy/settings.json(提交进 git):{"permissions": {"deny": ["Bash(rm:*)", "Edit(.git/**)"]}}
~/.codebuddy/settings.json(用户级,私有):{"permissions": {"defaultMode": "acceptEdits","allow": ["Bash(git:*)", "Bash(npm:*)"]}}
--allowedTools / --disallowedTools / --add-dir 等启动参数文档反馈