OpenCode 权限系统(Permissions)配置实战指南:让 AI 编程助手在安全边界内自由发挥

引言

AI 编程助手在带来极高生产力的同时,也带来一个关键问题:我们敢不敢让它放手执行命令? 当 AI 代理在终端里自动运行 git push、批量修改文件、甚至执行 rm -rf 的时候,如果没有一套完善的权限控制机制,后果不堪设想。

OpenCode 内置了一套灵活而强大的权限系统(Permissions)。通过 permission 配置,你可以精确控制哪些操作需要经过你审批(ask)、哪些可以自动执行(allow)、哪些必须被禁止(deny)。本文将从基础用法到高级模式,带你全面掌握 OpenCode 的权限体系,让你的 AI 编程助手既能高效干活,又不会越界闯祸。

权限规则的核心三值

OpenCode 的每一条权限规则最终都会解析为三种结果之一:

  • "allow":无需审批,自动执行
  • "ask":弹出提示,等待你审批
  • "deny":直接阻止该操作

理解了这三个动作,权限配置的思路就清晰了:把危险操作设为 askdeny,把安全且高频的操作设为 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"
    }
  }
}

这段配置实现了非常精细的控制:

  • 所有 shell 命令默认询问
  • gitnpm 开头的命令自动放行(比如 git statusnpm install
  • rm 开头的命令直接禁止,防止误删文件
  • grep 搜索命令自动执行
  • 文件编辑默认全部禁止,但 packages/web/src/content/docs/ 目录下的 .mdx 文档文件允许修改

匹配规则:最后一个匹配生效

规则的求值方式是模式匹配,最后一条匹配的规则生效。因此推荐的写法是把兜底的 "*" 规则放在最前面,后面再跟上越来越具体的规则,后者会覆盖前者。这也是上面示例中使用这种排列顺序的原因。

通配符语法

模式匹配使用简单的通配符:

  • * 匹配任意多个任意字符
  • ? 匹配恰好一个字符
  • 其余字符按字面匹配

例如 "git *" 会匹配 git statusgit log 等命令,而 "git status *" 则只在命令带参数时匹配。注意:"grep" 单独写只能匹配不带参数的情况,"grep *" 才能匹配 grep pattern file.txt 这类实际用法。

自动审批模式(Auto Mode)

如果你觉得每次弹窗太打扰,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:所有文件修改(覆盖 editwritepatch
  • 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_loopexternal_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 statusgit diffnpm run)自动放行,提升效率
  • 会改变状态的命令(安装、提交、推送)必须询问
  • rm -rfsudo 直接拉黑,杜绝灾难性操作
  • 外部目录只信任 ~/.config/opencode 下的配置
  • 文档类文件编辑放行,代码文件仍需审批

总结

OpenCode 的权限系统提供了一种「信任但验证」的安全协作模式:allow 让你效率拉满,ask 让你掌控关键节点,deny 为你守住安全底线。配合对象语法的模式匹配、外部目录控制、按代理定制等高级能力,你可以为不同项目、不同代理打造精准的权限边界。

建议你从一两条规则开始,随着对 AI 编程助手信任度的提升,逐步放开操作权限。安全与效率的平衡,永远掌握在你自己手中。