第 8 章

權限與工具管理

了解 opencode 內建工具的完整生態,掌握 allow / ask / deny 三種權限行為,學會設定細粒度規則來安全地控制代理行為。

中級 Intermediate

學習目標

內建工具總覽

opencode 提供一系列內建工具,讓代理能夠執行各種操作。這些工具可分別啟用或停用,也可以指定不同的權限行為。

工具用途說明
bashShell 指令執行在專案環境中執行 Bash/PowerShell 指令
edit檔案編輯對已讀取的檔案進行精確的區塊取代
write檔案寫入建立新檔案或完整覆寫既有檔案
patch修補檔案以 diff 格式對檔案進行小幅修改
read檔案讀取讀取檔案內容(支援行數偏移與限制)
grep內容搜尋使用正規表達式搜尋檔案內容
glob檔名搜尋以 glob 模式匹配檔案路徑
lsp語言伺服器透過 LSP 取得語法分析與診斷資訊
skill技能載入載入 SKILL.md 定義的代理技能
todowrite任務追蹤寫入待辦事項清單供代理參考
webfetch網頁擷取從 URL 取得網頁內容並轉為 Markdown
websearch網路搜尋執行網路搜尋查詢(需對應提供商支援)
question提問用戶向使用者提問以釐清需求
task子代理調度啟動子代理平行處理獨立任務

三種權限行為

每個工具可以指派以下權限行為之一,決定代理何時需要徵求你的許可:

權限行為適用場景
allow自動允許,不詢問信任的唯讀工具如 readglob
ask執行前先提問用戶可能有副作用的工具如 bashwrite
deny完全禁止使用高風險或不需要的工具如 websearch

貼心提醒:question 工具不受權限系統影響,它總是會被允許,因為它的本質就是問你問題。

全域權限設定

opencode.json 中可設定全域工具權限,所有工具預設繼承這些規則:

{
  "permissions": {
    "allow": [
      "read",
      "glob",
      "grep",
      "lsp",
      "question"
    ],
    "ask": [
      "bash",
      "edit",
      "write",
      "patch",
      "webfetch",
      "skill",
      "todowrite",
      "task"
    ],
    "deny": [
      "websearch"
    ]
  }
}

未在清單中的工具將使用預設權限(通常是 ask)。

細粒度規則(物件語法)

除了簡單的陣列清單,你還可以使用物件語法對特定工具設定更精細的規則。這在 bash 工具的指令層級權限控制上尤其有用:

{
  "permissions": {
    "bash": {
      "allow": [
        "npm test",
        "npm run build",
        "git status",
        "git diff",
        "ls",
        "node --version"
      ],
      "ask": [
        "npm install",
        "git add",
        "git commit",
        "mkdir",
        "rm"
      ],
      "deny": [
        "rm -rf /",
        "sudo",
        "curl"
      ]
    },
    "write": "ask",
    "edit": "ask"
  }
}

當你對 bash 使用物件語法時,代理執行的指令會與規則進行前綴匹配。例如以 npm 開頭的指令會自動允許,而以 sudo 開頭的則完全禁止。

重要:bash 指令比對是前綴匹配(prefix match),所以 "npm" 會同時允許 npm testnpm install some-package。若要更精確,請使用完整的指令字串。

全域 vs 代理級覆寫

權限可以設定在兩個層級,下層會繼承並可覆寫上層:

  1. 全域層級 — 在 opencode.jsonpermissions 區塊中設定,所有代理共用
  2. 代理層級 — 在自訂代理定義中設定,僅影響該代理

範例:全域允許所有唯讀工具,但在自訂的 deploy-agent 中將 bash 設為 ask

{
  "agents": {
    "deploy-agent": {
      "permissions": {
        "bash": "ask",
        "write": "ask",
        "edit": "ask",
        "read": "allow",
        "glob": "allow"
      }
    }
  }
}

安全防護機制

external_directory

預設情況下,opencode 限制代理只能操作專案目錄內的檔案。若需要允許代理存取專案外部的特定目錄(例如共享設定檔或暫存區),可使用 external_directory 設定:

{
  "permissions": {
    "external_directory": [
      "C:\\Users\\YourName\\.shared-config",
      "D:\\temp"
    ]
  }
}

注意:external_directory 是基於開放編碼原則的安全限制,並非強制沙箱。你應該將它視為一個安全提示而非絕對屏障。

doom_loop 防護

為防止代理陷入無限循環(例如不斷執行失敗的指令並重試),opencode 內建了 doom_loop 防護機制。當代理在短時間內重複執行相同操作且持續失敗時,系統會自動介入並終止循環。這個機制預設啟用,不需要額外設定。

實戰練習

練習 1:設定安全的全域權限

  1. 建立一個 opencode.json,將 readglobgrep 設為 allow
  2. websearch 設為 deny
  3. 將其餘所有工具設為 ask
  4. 加入 external_directory 指向 C:\Users\Public\shared

練習 2:bash 指令層級權限

  1. 設定 bash 工具的物件語法規則
  2. 允許 npm testnpm run buildgit status
  3. 設為詢問:npm installgit commit
  4. 完全禁止:sudorm -rf
  5. 啟動 opencode 並使用 !bash npm test 測試權限是否正確生效

練習 3:代理級權限覆寫

  1. 建立一個名為 safe-coder 的自訂代理
  2. 該代理中僅允許 readglobgrepedit
  3. bash 設為 deny(此代理只能編輯程式碼,不能執行指令)
  4. 確認全域權限不會影響此代理的專屬設定