OpenCode 权限配置
OpenCode 的权限系统用于控制哪些操作可以自动运行、哪些需要你手动审批、哪些会被直接阻止。合理配置权限,既能让 AI 高效完成任务,又能防止误操作破坏代码或泄露敏感文件。
从 v1.1.1 开始,旧版
tools布尔配置已被弃用,并已合并到permission中。旧版配置仍然支持,以保持向后兼容,但建议迁移到新的permission写法。
三种权限动作
每条权限规则最终会解析为以下三种动作之一:
| 动作 | 效果 | 适用场景 |
|---|---|---|
"allow" |
无需审批,直接自动运行 | 低风险、高频操作,如读取文件、运行测试 |
"ask" |
弹出审批提示,由你决定是否允许 | 有一定风险的操作,如写入文件、执行脚本 |
"deny" |
直接阻止,不会执行也不会提示 | 明确不允许的危险操作,如删除文件、推送代码 |
基础配置
权限配置写在仓库根目录(或用户配置目录)下的 opencode.json 文件中,使用 permission 字段进行配置。
1、全局设置所有权限
最简单的写法:用一个字符串一次性设置所有操作的权限。适合快速开始或临时调试:
实例
"$schema": "https://opencode.ai/config.json",
"permission": "allow" // 所有操作都自动运行,不弹任何提示(适合本地开发、充分信任 AI 时使用)
}
2、按工具名称配置
使用对象写法,可以对不同工具分别指定权限。"*" 是通配符,表示匹配所有操作,通常作为兜底默认值:
实例
"$schema": "https://opencode.ai/config.json",
"permission": {
"*": "ask", // 兜底规则:所有未单独配置的工具,默认都弹出提示
"bash": "allow", // bash(执行 Shell 命令):直接允许,不提示
"edit": "deny" // edit(修改文件):直接阻止
}
}
细粒度规则(对象语法)
对于大多数权限,除了设置统一动作,还可以用对象语法根据工具的具体输入内容来应用不同规则。例如,对 bash 工具,可以区分哪些命令允许、哪些需要审批、哪些直接拒绝:
实例
"$schema": "https://opencode.ai/config.json",
"permission": {
"bash": {
"*": "ask", // 兜底:所有 bash 命令默认需要审批
"git *": "allow", // git 开头的命令(如 git status、git log)直接允许
"npm *": "allow", // npm 开头的命令(如 npm install、npm run build)直接允许
"grep *": "allow", // grep 搜索命令直接允许
"rm *": "deny" // rm 删除命令直接阻止(防止误删文件)
},
"edit": {
"*": "deny", // 默认阻止所有文件编辑
"packages/web/src/content/docs/*.mdx": "allow" // 只允许编辑文档目录下的 .mdx 文件
}
}
}
规则匹配顺序:最后匹配的规则优先。 建议将通配的
"*"规则放在最前面作为默认值,更具体的规则放在后面来覆盖它。这样越具体的规则优先级越高,逻辑清晰不易出错。
通配符规则
权限模式支持简单的通配符匹配,规则如下:
| 通配符 | 含义 | 示例 |
|---|---|---|
* |
匹配零个或多个任意字符(不跨目录) | git * 匹配 git status、git log --oneline 等 |
** |
匹配跨目录的任意路径 | ~/projects/** 匹配 projects 下所有文件和子目录 |
? |
精确匹配一个任意字符 | file?.txt 匹配 file1.txt、fileA.txt |
| 其他字符 | 按字面值精确匹配 | git status 只匹配 git status,不匹配带参数的变体 |
注意:对带参数的命令一定要在末尾加
*。例如"grep *"能匹配grep pattern file.txt,而单独写"grep"只匹配没有任何参数的裸命令,实际执行时几乎不会命中。
主目录展开
在模式开头可以使用 ~ 或 $HOME 来引用当前用户的主目录,OpenCode 会自动将其展开为完整路径:
实例
"~/projects/*"
"$HOME/projects/*"
"/Users/username/projects/*" // 直接写绝对路径也可以,但不推荐(不够通用)
外部目录权限(external_directory)
默认情况下,OpenCode 只允许工具访问启动时所在的工作目录及其子目录。如果需要访问项目目录之外的路径(例如另一个项目或共享配置目录),必须通过 external_directory 显式授权。
主目录展开(
~/...)只是一种路径书写简化方式,并不会自动授权访问该路径。工作目录之外的路径仍然必须通过external_directory来允许。
1、允许访问外部目录
实例
"$schema": "https://opencode.ai/config.json",
"permission": {
"external_directory": {
"~/projects/personal/**": "allow" // 允许访问 ~/projects/personal/ 下的所有文件和子目录
// ** 匹配任意层级的子路径
}
}
}
2、允许读取但禁止编辑
被 external_directory 授权的目录会继承当前工作空间的默认权限。由于 read 默认为 "allow",授权后该目录下的文件可以被读取。如果需要进一步限制某项操作(例如允许读取但禁止编辑),可以叠加额外规则:
实例
"$schema": "https://opencode.ai/config.json",
"permission": {
"external_directory": {
"~/projects/personal/**": "allow" // 第一步:授权访问该外部目录
},
"edit": {
"~/projects/personal/**": "deny" // 第二步:在此目录上叠加规则,允许读取但禁止编辑
}
}
}
所有可用权限项
OpenCode 的权限以工具名称为键,涵盖文件操作、命令执行、网络访问等所有类型:
| 权限项 | 控制的操作 | 模式匹配内容 | 默认值 |
|---|---|---|---|
read |
读取文件内容 | 文件路径(如 src/index.js) |
allow(.env 文件除外) |
edit |
所有文件修改,涵盖 edit、write、patch、multiedit | 文件路径 | allow |
glob |
文件通配查找(如查找所有 .ts 文件) |
通配模式(如 **/*.ts) |
allow |
grep |
在文件内容中搜索文本 | 正则表达式模式 | allow |
list |
列出目录中的文件 | 目录路径 | allow |
bash |
运行 Shell 命令 | 解析后的完整命令(如 git status --porcelain) |
allow |
task |
启动子代理 | 子代理类型名称 | allow |
skill |
加载技能 | 技能名称 | allow |
lsp |
运行 LSP 语言服务查询 | 当前不支持细粒度配置 | allow |
webfetch |
获取网络 URL 内容 | 完整 URL(如 https://example.com/api) |
allow |
websearch |
网页搜索 | 搜索查询字符串 | allow |
codesearch |
代码搜索 | 搜索查询字符串 | allow |
external_directory |
访问工作目录之外的路径 | 外部目录路径 | ask |
doom_loop |
同一工具以相同输入重复调用 3 次时触发(防止 AI 卡死循环) | — | ask |
默认权限说明
如果你没有配置任何权限,OpenCode 会使用以下内置默认值:
- 大多数工具权限默认为
"allow",即自动运行不提示 doom_loop和external_directory默认为"ask",需要手动审批read默认允许读取所有文件,但对.env相关文件有内置保护:
实例
{
"permission": {
"read": {
"*": "allow", // 默认允许读取所有文件
"*.env": "deny", // 阻止读取 .env 文件(防止泄露数据库密码、API 密钥等)
"*.env.*": "deny", // 阻止读取 .env.local、.env.production 等变体
"*.env.example": "allow" // 允许读取 .env.example(示例文件,不含真实密钥)
}
}
}
审批提示的三个选项
当某个操作的权限为 "ask" 时,OpenCode 会弹出审批提示,提供以下三种选择:
| 选项 | 效果 | 适用场景 |
|---|---|---|
| once(仅此一次) | 仅批准本次请求,下次相同操作仍会弹出提示 | 临时允许某个操作,不想永久放开 |
| always(始终允许) | 将此操作的匹配模式加入白名单,当前会话剩余时间内不再提示 | 确认某类操作安全,希望本次会话中自动通过 |
| reject(拒绝) | 拒绝本次请求,操作不会执行 | 发现操作有风险,明确不希望执行 |
选择 always 后,OpenCode 会由工具自动提供建议的白名单模式(例如,批准 git status 后通常会将 git status* 加入白名单)。白名单仅在当前会话中有效,重启 OpenCode 后会重置。
为代理单独配置权限
如果你的工作流中使用了多个代理(agent),可以为每个代理单独覆盖权限配置。代理权限会与全局配置合并,且代理规则的优先级高于全局规则。
1、在 opencode.json 中配置代理权限
实例
"$schema": "https://opencode.ai/config.json",
"permission": {
// 全局权限:git 操作允许,但禁止 commit 和 push
"bash": {
"*": "ask",
"git *": "allow",
"git commit *": "deny",
"git push *": "deny",
"grep *": "allow"
}
},
"agent": {
"build": { // 名为 build 的代理
"permission": {
"bash": {
"*": "ask",
"git *": "allow",
"git commit *": "ask", // 覆盖全局:build 代理允许 commit,但需要审批
"git push *": "deny", // 继承全局:依然禁止 push
"grep *": "allow"
}
}
}
}
}
2、在 Markdown 文件中配置代理权限
代理也可以通过 Markdown 文件进行配置,权限写在文件顶部的 YAML Front Matter 中(--- 之间的部分):
实例
---
description: 代码审查代理(只分析代码,不做任何修改)
mode: subagent
permission:
edit: deny # 禁止所有文件编辑
bash: ask # bash 命令需要审批
webfetch: deny # 禁止访问外部 URL
---
Only analyze code and suggest changes.
# 以下是代理的系统提示词,描述该代理的职责和行为规范
实用配置示例
示例一:保守模式(所有操作都需审批)
适合初次接触 OpenCode 或在重要项目上工作时使用,所有操作都需要手动确认:
实例
"$schema": "https://opencode.ai/config.json",
"permission": {
"*": "ask" // 所有工具的所有操作都弹出审批提示
}
}
示例二:开发常用配置(读操作放开,写操作审批)
适合日常开发:允许 AI 自由读取和搜索代码,但修改文件和执行命令时需要确认:
实例
"$schema": "https://opencode.ai/config.json",
"permission": {
"*": "ask", // 兜底:未单独配置的工具默认需要审批
"read": "allow", // 读取文件:直接允许
"glob": "allow", // 文件通配查找:直接允许
"grep": "allow", // 内容搜索:直接允许
"list": "allow", // 列出目录:直接允许
"bash": {
"*": "ask", // bash 命令默认需要审批
"git status *": "allow", // 查看 git 状态:允许
"git log *": "allow", // 查看 git 日志:允许
"git diff *": "allow", // 查看 git 差异:允许
"npm run *": "allow", // 运行 npm 脚本:允许
"npm test *": "allow", // 运行测试:允许
"rm *": "deny" // 删除文件:直接阻止
}
}
}
示例三:允许访问多个项目目录
当 AI 需要跨多个项目目录工作时,授权外部目录访问权限:
实例
"$schema": "https://opencode.ai/config.json",
"permission": {
"external_directory": {
"~/projects/personal/**": "allow", // 允许访问个人项目目录
"~/projects/work/**": "allow", // 允许访问工作项目目录
"~/dotfiles/**": "allow" // 允许访问配置文件目录
},
"edit": {
"~/dotfiles/**": "deny" // 即使允许访问 dotfiles,也禁止编辑(只读)
}
}
}
点我分享笔记