---
title: "管理許可權"
description: "理解 OpenCode 的 allow、ask、deny、外部目錄和 Agent 級許可權邊界。"
verifiedAt: "2026-05-09"
---

許可權配置是 OpenCode 新手最應該認真理解的一頁。它決定模型能不能讀檔案、改檔案、跑命令、訪問外部目錄、呼叫工具或載入 Skill。

> [!NOTE]
> **這一篇用 10 分鐘換什麼**：你會知道 `allow` / `ask` / `deny` 怎麼選，為什麼不要一開始全開，外部目錄怎麼收口，以及審查 Agent 為什麼應該用許可權禁止寫入。

## 先給結論：真實專案從 ask 開始

新手的目標不是把所有彈出視窗關掉，而是讓高風險動作必須經過確認，讓低風險動作不要打斷工作流。

```mermaid
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` 預設規則的精確寫法是：

```jsonc
{
  "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% 的安全場景。剩下的等遇到具體需求再翻這張表。

## 一個保守起點

專案級許可權可以先從這類基線開始：

```jsonc title="opencode.json"
{
  "$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 要确认，危险动作先拒绝。

> [!IMPORTANT]
> **规则顺序很重要——最后匹配的规则胜出**。所以惯例是把 `"*"` 兜底规则放在**最前面**，把具体规则放在**后面**。如果你把 `"git status*": "allow"` 写在 `"*": "ask"` 之前，`*` 会再次匹配 `git status` 并把它改回 `ask`。`bash` 段里的写法（`*` 在前、具体命令在后）就是这个原因。

> [!WARNING]
> `bash: allow` 不适合作为默认配置。安装依赖、删除文件、发布、数据库操作都可能从 shell 触发。

路径模式支持 `~` 和 `$HOME` 开头展开到 home 目录（`~/projects/*` 等价于 `/Users/<你>/projects/*`）。这是 OpenCode 内部展开的，和 shell 是不是支持 `~` 没关系。

## 文件修改统一看 `edit`

不要只盯着某一个工具名。文件修改能力包括 `edit`、`write`、`apply_patch` 等，应该统一按 `edit` 权限治理。

如果你真的不希望某个 Agent 改文件，不能只在提示词里写“不要修改”。要在权限里写清楚：

```yaml
permission:
  edit: deny
  bash: ask
```

提示词是意图，权限是边界。审查、规划、安全检查这类 Agent，默认应该比 Build Agent 更保守。

## 外部目录要单独批准

OpenCode 默认工作在启动目录内。访问工作区外路径时，会触发 `external_directory`。

不要为了省事允许整个 home 目录。更稳的写法是允许少数可信路径，并单独限制写入：

```jsonc title="opencode.json"
{
  "$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 嘗試改檔案，應該被拒絕。

## 接下來去哪

<Cards>
  <Card title="工具總覽" description="理解 read、grep、edit、bash、apply_patch、web 和 MCP 工具如何受許可權治理。" href="/zh-Hant/docs/opencode/official/04-tools-mcp/tools" />
  <Card title="安全、分享與團隊使用" description="把許可權放到金鑰、share、provider、MCP 和 CI 的整體邊界裡看。" href="/zh-Hant/docs/opencode/understanding/08-security-share-team" />
  <Card title="配置 Agents" description="為 review、docs、security 等 Agent 設定更窄的許可權邊界。" href="/zh-Hant/docs/opencode/official/02-agents-skills/agents" />
  <Card title="分享會話" description="許可權之外，還要單獨處理公開分享和會話資料邊界。" href="/zh-Hant/docs/opencode/official/00-getting-started/share" />
</Cards>

## 官方資料

- Permissions：[https://opencode.ai/docs/permissions](https://opencode.ai/docs/permissions)
- Tools：[https://opencode.ai/docs/tools](https://opencode.ai/docs/tools)
- Agents：[https://opencode.ai/docs/agents](https://opencode.ai/docs/agents)
