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 statusgit log --oneline
** 匹配跨目录的任意路径 ~/projects/** 匹配 projects 下所有文件和子目录
? 精确匹配一个任意字符 file?.txt 匹配 file1.txtfileA.txt
其他字符 按字面值精确匹配 git status 只匹配 git status,不匹配带参数的变体

注意:对带参数的命令一定要在末尾加 *。例如 "grep *" 能匹配 grep pattern file.txt,而单独写 "grep" 只匹配没有任何参数的裸命令,实际执行时几乎不会命中。

主目录展开

在模式开头可以使用 ~$HOME 来引用当前用户的主目录,OpenCode 会自动将其展开为完整路径:

实例

// 以下三种写法效果相同,都会展开为 /Users/username/projects/*(路径因系统而异)
"~/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_loopexternal_directory 默认为 "ask",需要手动审批
  • read 默认允许读取所有文件,但对 .env 相关文件有内置保护:

实例

// OpenCode 内置的 read 默认规则(无需手动配置,仅供参考)
{
  "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 中(--- 之间的部分):

实例

# 文件路径:~/.config/opencode/agents/review.md
---
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,也禁止编辑(只读)
    }
  }
}