AI 编程助手在带来极高生产力的同时,也带来一个关键问题:我们敢不敢让它放手执行命令? 当 AI 代理在终端里自动运行 git push、批量修改文件、甚至执行 rm -rf 的时候,如果没有一套完善的权限控制机制,后果不堪设想。
OpenCode 内置了一套灵活而强大的权限系统(Permissions)。通过 permission 配置,你可以精确控制哪些操作需要经过你审批(ask)、哪些可以自动执行(allow)、哪些必须被禁止(deny)。本文将从基础用法到高级模式,带你全面掌握 OpenCode 的权限体系,让你的 AI 编程助手既能高效干活,又不会越界闯祸。
OpenCode 的每一条权限规则最终都会解析为三种结果之一:
"allow":无需审批,自动执行"ask":弹出提示,等待你审批"deny":直接阻止该操作理解了这三个动作,权限配置的思路就清晰了:把危险操作设为 ask 或 deny,把安全且高频的操作设为 allow,其余操作交给审批机制兜底。
权限配置写在项目的 opencode.json 中。最简单的写法是用 "*" 设置全局默认值,再针对具体工具覆盖:
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"*": "ask",
"bash": "allow",
"edit": "deny"
}
}
上面的配置意思是:所有操作默认都需要询问,但 shell 命令自动放行,文件编辑则完全禁止。
如果你对自己信任有加,也可以把所有权限一次性放开:
{
"$schema": "https://opencode.ai/config.json",
"permission": "allow"
}
不过笔者强烈不建议在生产项目里这么做——一次误操作可能让整个代码库遭殃。
对于大多数权限,你还可以使用对象语法,根据工具的输入参数来匹配不同的规则。这是整个权限系统最核心、最实用的能力。
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"bash": {
"*": "ask",
"git *": "allow",
"npm *": "allow",
"rm *": "deny",
"grep *": "allow"
},
"edit": {
"*": "deny",
"packages/web/src/content/docs/*.mdx": "allow"
}
}
}
这段配置实现了非常精细的控制:
git 和 npm 开头的命令自动放行(比如 git status、npm install)rm 开头的命令直接禁止,防止误删文件grep 搜索命令自动执行packages/web/src/content/docs/ 目录下的 .mdx 文档文件允许修改规则的求值方式是模式匹配,最后一条匹配的规则生效。因此推荐的写法是把兜底的 "*" 规则放在最前面,后面再跟上越来越具体的规则,后者会覆盖前者。这也是上面示例中使用这种排列顺序的原因。
模式匹配使用简单的通配符:
* 匹配任意多个任意字符? 匹配恰好一个字符例如 "git *" 会匹配 git status、git log 等命令,而 "git status *" 则只在命令带参数时匹配。注意:"grep" 单独写只能匹配不带参数的情况,"grep *" 才能匹配 grep pattern file.txt 这类实际用法。
如果你觉得每次弹窗太打扰,OpenCode 提供了自动审批模式。启动时加上 --auto 参数即可:
opencode --auto
在 CLI 模式下同样适用:
opencode run --auto "重构这个模块"
需要注意两点:自动模式只作用于原本需要询问的操作,明确的 "deny" 规则依然会被强制执行;其次,在 TUI 中你也可以通过命令面板随时开启或关闭「Enable auto-approve permissions」。自动模式开启后,界面中会显示一个低调的 auto 指示器。
默认情况下,OpenCode 只能访问启动它的项目目录。如果 AI 需要读取或修改项目目录之外的文件(比如个人配置目录),必须通过 external_directory 规则显式授权:
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"external_directory": {
"~/projects/personal/**": "allow"
}
}
}
模式中可以使用 ~ 或 $HOME 表示主目录,例如 ~/projects/* 会被展开为 /Users/username/projects/*。
被 external_directory 授权的目录会继承与当前工作区相同的默认权限(比如 read 默认为 allow)。如果希望在授权读取的同时限制修改,可以叠加额外规则:
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"external_directory": {
"~/projects/personal/**": "allow"
},
"edit": {
"~/projects/personal/**": "deny"
}
}
}
注意:~ 展开只影响模式写法,并不会让外部路径自动变成工作区的一部分,所以外部路径必须通过 external_directory 单独授权。
了解有哪些权限可以配置,才能有的放矢。OpenCode 的权限以工具名称为键,外加几个安全守卫:
read:读取文件(匹配文件路径)edit:所有文件修改(覆盖 edit、write、patch)glob:文件通配搜索(匹配 glob 模式)grep:内容搜索(匹配正则模式)bash:运行 shell 命令(匹配解析后的命令,如 git status --porcelain)task:启动子代理(匹配子代理类型)skill:加载技能(匹配技能名称)lsp:执行 LSP 查询(目前不支持细分规则)question:执行过程中向用户提问webfetch:抓取 URL(匹配 URL)websearch:网络搜索(匹配搜索词)external_directory:工具访问项目工作目录之外的路径时触发doom_loop:同一工具调用以完全相同的输入连续重复 3 次时触发如果你什么都没配置,OpenCode 默认是相当宽松的:
"allow"doom_loop 和 external_directory 默认为 "ask"read 默认为 "allow",但 .env 文件默认被禁止读取.env 文件的默认保护非常贴心,它在底层被展开为这样的规则:
{
"permission": {
"read": {
"*": "allow",
"*.env": "deny",
"*.env.*": "deny",
"*.env.example": "allow"
}
}
}
也就是说,.env、.env.local 等敏感文件默认读不到,但 .env.example(示例模板)允许读取。这为密钥安全加了一道默认保险。
当权限触发 ask 时,弹出的审批界面会给你三个选项:
once:仅批准这一次请求always:批准匹配相同模式的后续请求(仅在当前 OpenCode 会话内有效)reject:拒绝该请求always 会批准的模式集合由工具自身提供,比如 bash 审批通常会白名单化一个安全命令前缀,如 git status*,而不是盲目放行整个命令行。
权限还可以按代理(agent)分别设置。代理权限会与全局配置合并,且代理规则优先:
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"bash": {
"*": "ask",
"git *": "allow",
"git commit *": "deny",
"git push *": "deny",
"grep *": "allow"
}
},
"agent": {
"build": {
"permission": {
"bash": {
"*": "ask",
"git *": "allow",
"git commit *": "ask",
"git push *": "deny",
"grep *": "allow"
}
}
}
}
}
这个例子中,全局配置禁止 git commit,但 build 代理被单独放行(ask 会询问)。如果你不希望 AI 在无人值守时随意提交代码,这种「按代理收紧权限」的方式非常实用。
你甚至可以在 Markdown 格式的代理定义中直接声明权限,比如创建一个只读的代码审查代理:
--- description: Code review without edits mode: subagent permission: edit: deny bash: ask webfetch: deny --- Only analyze code and suggest changes.
最后,笔者分享一套适合日常开发的安全配置,供你参考:
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"*": "ask",
"read": {
"*": "allow",
"*.env": "deny",
"*.env.*": "deny"
},
"edit": {
"*": "ask",
"*.md": "allow",
"*.mdx": "allow"
},
"bash": {
"*": "ask",
"git status *": "allow",
"git diff *": "allow",
"git log *": "allow",
"npm run *": "allow",
"npm install *": "ask",
"npm uninstall *": "ask",
"git commit *": "ask",
"git push *": "ask",
"rm -rf *": "deny",
"sudo *": "deny"
},
"external_directory": {
"~/.config/opencode/**": "allow"
},
"webfetch": {
"*": "allow"
}
}
}
要点解读:
ask,让 AI 大部分动作都处于可控状态git status、git diff、npm run)自动放行,提升效率rm -rf 和 sudo 直接拉黑,杜绝灾难性操作~/.config/opencode 下的配置OpenCode 的权限系统提供了一种「信任但验证」的安全协作模式:allow 让你效率拉满,ask 让你掌控关键节点,deny 为你守住安全底线。配合对象语法的模式匹配、外部目录控制、按代理定制等高级能力,你可以为不同项目、不同代理打造精准的权限边界。
建议你从一两条规则开始,随着对 AI 编程助手信任度的提升,逐步放开操作权限。安全与效率的平衡,永远掌握在你自己手中。