管理权限
理解 OpenCode 的 allow、ask、deny、外部目录和 Agent 级权限边界。
权限配置是 OpenCode 新手最应该认真理解的一页。它决定模型能不能读文件、改文件、跑命令、访问外部目录、调用工具或加载 Skill。
这一篇用 10 分钟换什么:你会知道 allow / ask / deny 怎么选,为什么不要一开始全开,外部目录怎么收口,以及审查 Agent 为什么应该用权限禁止写入。
先给结论:真实项目从 ask 开始
新手的目标不是把所有弹窗关掉,而是让高风险动作必须经过确认,让低风险动作不要打断工作流。
flowchart LR
Action["Agent 想执行动作"] --> Risk{"动作风险"}
Risk -->|只读搜索| Allow["allow"]
Risk -->|写文件 / shell / web| Ask["ask"]
Risk -->|密钥 / 删除 / 发布 / 外部敏感目录| Deny["deny"]
Ask --> Explain["看命令和影响范围"]
Explain --> Approve["一次性批准或拒绝"]
style Allow fill:#dcfce7,stroke:#22c55e
style Ask fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
style Deny fill:#fee2e2,stroke:#ef4444
真实项目里不要依赖默认值。OpenCode 默认相对宽松——多数权限默认 allow、doom_loop 和 external_directory 默认 ask、.env 类文件默认禁读。但项目仍然应该显式写出权限边界。
.env 默认规则的精确写法是:
{
"permission": {
"read": {
"*": "allow",
"*.env": "deny",
"*.env.*": "deny",
"*.env.example": "allow"
}
}
}这条规则同时覆盖了 .env、.env.production、.env.local 等所有变体,但放行 .env.example(公开的示例文件)。
三种动作怎么选
| 动作 | 含义 | 适合场景 |
|---|---|---|
allow | 直接执行 | 低风险、高频、你完全理解的只读动作 |
ask | 执行前询问 | 写文件、跑命令、联网、外部工具 |
deny | 直接拒绝 | 密钥、生产、删除、危险外部目录 |
读文件、搜索、查看项目结构,可以先允许。改文件、跑命令、访问网页,先设置为 ask。删除文件、访问敏感外部目录、运行危险 shell,一开始应该拒绝或至少询问。
完整的 permission key 列表
OpenCode 把权限按工具或安全场景分成下面这些 key。每个 key 可以单独设 allow / ask / deny,部分 key 还支持用对象 + glob/pattern 做更细粒度控制(标 ✅ 的):
| Key | 控制什么 | 细粒度 | 默认 |
|---|---|---|---|
read | 读文件(按路径匹配) | ✅ | allow(.env* 默认 deny) |
edit | 所有文件修改(覆盖 edit/write/apply_patch) | ✅ | allow |
glob | glob 文件匹配(按 pattern) | ✅ | allow |
grep | 正则内容搜索(按 pattern) | ✅ | allow |
list | 列目录(按路径) | ✅ | allow |
bash | shell 命令(按解析后命令匹配如 git status --porcelain) | ✅ | allow |
task | 启动 subagent(按 subagent 名匹配) | ✅ | allow |
external_directory | 工具触碰工作区外路径时触发 | ✅ | ask |
todowrite | 维护 todo 列表 | — | allow |
webfetch | 抓取 URL(按 URL 匹配) | — | allow |
websearch | 网页搜索(按 query 匹配) | — | allow |
lsp | LSP 查询(暂不支持细粒度) | — | allow |
skill | 加载 SKILL.md(按 skill 名匹配) | ✅ | allow |
question | agent 中途反问用户 | — | allow |
doom_loop | 同一工具同输入连续 3 次时触发 | — | ask |
新手要记住的是这 4 个:read / edit / bash / external_directory——它们覆盖 95% 的安全场景。剩下的等遇到具体需求再翻这张表。
一个保守起点
项目级权限可以先从这类基线开始:
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"read": "allow",
"grep": "allow",
"glob": "allow",
"edit": "ask",
"bash": {
"*": "ask",
"git status*": "allow",
"git diff*": "allow",
"rm *": "deny",
"git push*": "deny"
},
"webfetch": "ask",
"websearch": "ask",
"skill": "ask",
"external_directory": "ask"
}
}这不是唯一正确配置,但体现了原则:只读可以更开放,写入和 shell 要确认,危险动作先拒绝。
规则顺序很重要——最后匹配的规则胜出。所以惯例是把 "*" 兜底规则放在最前面,把具体规则放在后面。如果你把 "git status*": "allow" 写在 "*": "ask" 之前,* 会再次匹配 git status 并把它改回 ask。bash 段里的写法(* 在前、具体命令在后)就是这个原因。
bash: allow 不适合作为默认配置。安装依赖、删除文件、发布、数据库操作都可能从 shell 触发。
路径模式支持 ~ 和 $HOME 开头展开到 home 目录(~/projects/* 等价于 /Users/<你>/projects/*)。这是 OpenCode 内部展开的,和 shell 是不是支持 ~ 没关系。
文件修改统一看 edit
不要只盯着某一个工具名。文件修改能力包括 edit、write、apply_patch 等,应该统一按 edit 权限治理。
如果你真的不希望某个 Agent 改文件,不能只在提示词里写“不要修改”。要在权限里写清楚:
permission:
edit: deny
bash: ask提示词是意图,权限是边界。审查、规划、安全检查这类 Agent,默认应该比 Build Agent 更保守。
外部目录要单独批准
OpenCode 默认工作在启动目录内。访问工作区外路径时,会触发 external_directory。
不要为了省事允许整个 home 目录。更稳的写法是允许少数可信路径,并单独限制写入:
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"external_directory": {
"~/projects/shared-docs/**": "allow"
},
"edit": {
"~/projects/shared-docs/**": "deny"
}
}
}允许读取不代表允许修改。这个区分对团队知识库、公共素材目录和凭据目录尤其重要。
审批弹窗怎么判断
OpenCode 的审批弹窗给三个选项:
| 选项 | 行为 | 适合什么时候选 |
|---|---|---|
| once | 只批准这一次 | 默认起点;除非你完全理解后果,否则用这个 |
| always | 批准所有匹配建议 pattern 的同类请求(仅当前 OpenCode 会话有效,重启不保留) | 你已经看清这条规则覆盖什么、且能接受会话内自动放行 |
| reject | 拒绝这一次 | 命令看不懂、影响范围不明、不该让 agent 跑 |
always 不是永久 allow——它只在本次会话生效,关掉 OpenCode 就失效。如果想永久放行,应该写进 opencode.json 的 permission 配置。
如果你看不懂命令,不要批准。让 OpenCode 解释:
- 它要做什么。
- 为什么需要这个动作。
- 会影响哪些文件。
- 有没有只读替代方案。
- 不执行会阻塞什么。
如果请求访问外部目录,先问清它为什么不能在当前工作区完成。
看到 doom_loop 弹窗怎么办
doom_loop 是 OpenCode 的反卡死机制:当同一个工具用同样的输入连续调用 3 次时触发。这通常意味着模型卡在循环里、自己也意识不到。看到这个弹窗时不要默认批准——先看 agent 在做什么,多半要打断它、换个角度提问,或者切到 Plan mode 让它先列计划再继续。
和 Agent 配合
权限可以按 Agent 覆盖。审查 Agent 应该只读;执行 Agent 才允许改文件;联网研究 Agent 可以访问 web,但不一定能 edit。
常见分工:
review:edit: deny,bash: ask。docs:edit: ask,只允许文档目录。security:edit: deny,外部目录和 web 默认 ask。build:按项目默认权限执行。
这比在提示词里写“不要修改文件”更可靠。
新手常见坑
- 为了省弹窗直接全开
allow。 - 只限制
bash,忘记edit也能改文件。 - 允许外部目录后忘记限制编辑权限。
- 把宽泛命令当安全命令,例如允许所有
git *。 - 只靠 Agent 提示词约束行为,没有配权限。
- 看不懂审批内容却点 always。
怎么验收
用这些动作检查权限是否符合预期:
- 让 OpenCode 读一个普通文件,应该不打断。
- 让它改一个文件,应该出现审批或按规则拒绝。
- 让它运行只读命令,应该符合你的 bash 规则。
- 让它访问工作区外路径,应该触发 external directory 规则。
- 让审查 Agent 尝试改文件,应该被拒绝。
接下来去哪
工具总览
理解 read、grep、edit、bash、apply_patch、web 和 MCP 工具如何受权限治理。
安全、分享与团队使用
把权限放到密钥、share、provider、MCP 和 CI 的整体边界里看。
配置 Agents
为 review、docs、security 等 Agent 设置更窄的权限边界。
分享会话
权限之外,还要单独处理公开分享和会话数据边界。
官方资料
- Permissions:https://opencode.ai/docs/permissions
- Tools:https://opencode.ai/docs/tools
- Agents:https://opencode.ai/docs/agents