模式與權限:工具執行前的安全決策

先判斷模式,再套規則,再到工具檢查,最後才執行。

90 秒總覽

權限系統是 Claude Code 執行工具前的安全閘門。每當模型要呼叫一個工具,系統會依序檢查:① 當前模式(Plan / Auto Accept / Default)是否允許、② 使用者設定的 allow/deny 規則是否匹配、③ 工具本身的安全檢查是否通過。如果以上都通過,工具才能執行;否則系統會拒絕或詢問使用者確認。這個三層防護確保使用者始終掌握控制權。

執行路徑(主骨架)

const result = await canUseTool(tool, input, ctx)
if (result.behavior === 'deny') {
  return { ok: false }
}
return tool.run(input, ctx)
讀取當前 permission mode
套用 allow/deny 規則
執行工具特定檢查
必要時詢問使用者
決定執行或拒絕
flowchart TD
  A[工具呼叫請求] --> B[讀取當前模式]
  B --> C[模式規則檢查]
  C --> D[allow/deny 規則比對]
  D --> E[工具特定檢查]
  E --> F{需要使用者確認?}
  F -->|是| G[顯示 prompt]
  G --> H[使用者回覆]
  H --> I[執行或拒絕]
  F -->|否| J[直接執行]
  J --> I

路徑判讀重點

  • 三層檢查依序執行:模式 → 規則 → 工具,任一層拒絕即短路中止。
  • 使用者確認是阻塞式操作,在回覆前工具不會被執行。
  • Auto Accept 模式跳過使用者確認,但仍經過規則與工具檢查。

關鍵決策(為什麼這樣設計)

決策 1:三層檢查順序固定(模式→規則→工具)

原因:確保最廣泛的限制先生效。模式是全域控制,規則是使用者自訂偏好,工具檢查是最細粒度的安全確認。

代價:順序固定意味著無法讓工具層覆寫模式層的決定,靈活性較低。

決策 2:Plan mode 下禁止所有寫入操作

原因:保護使用者免於非預期變更。Plan mode 的設計目的是「只看不動」,任何寫入都違反此保證。

代價:使用者在 Plan mode 下無法做小幅修正,必須切換模式才能操作。

決策 3:使用者確認是阻塞式而非建議式

原因:安全決策不能被忽略。如果確認只是通知,模型可能在使用者未注意時執行危險操作。

代價:互動流暢度降低,頻繁確認可能造成使用者疲勞。

替代方案與取捨

方案 優點 缺點 為何未採用/何時可採用
單層權限(僅模式判斷) 實作簡單,判斷路徑短 缺乏細粒度控制,無法針對特定工具設定例外 安全需求要求多層防護,單層無法滿足
三層權限(模式+規則+工具) 分層明確,各層職責清楚 判斷邏輯較複雜,除錯時需逐層排查 目前採用;在安全與靈活度之間取得平衡
白名單模式(預設拒絕,逐一開放) 最嚴格,安全性最高 初始設定成本高,使用者體驗差 適合高安全場景,但對初學者不友善
黑名單模式(預設允許,逐一封鎖) 上手容易,開箱即用 可能遺漏危險操作,安全性較低 不適合安全敏感場景
阻塞確認(等待使用者回覆才執行) 使用者完全掌控,不會漏看 中斷工作流,頻繁確認造成疲勞 目前採用;安全優先於流暢度
非阻塞通知(執行後通知使用者) 流暢度高,不中斷操作 使用者可能錯過危險操作通知 安全決策不適合事後通知

失敗路徑與防護

Failure 1:模式切換後規則快取未更新

症狀:切換到 Plan mode 後,寫入工具仍能執行,因為舊模式的快取規則還在生效。

防護:模式切換時強制清除並重建規則快取,確保新模式立即生效。

Failure 2:使用者確認對話超時

症狀:等待確認的 prompt 長時間無回應,工具呼叫卡在佇列中,後續操作全部阻塞。

防護:設定合理的超時機制,超時後自動拒絕並通知使用者,避免無限等待。

Failure 3:工具繞過權限檢查

症狀:某些工具直接執行而未經過 canUseTool 檢查,導致未授權操作被執行。

防護:在工具執行入口處統一攔截,確保所有工具呼叫都必經權限檢查管線。

實作驗證(你改完要怎麼確認)

  • 確認 Plan mode 下寫入工具被拒絕:切換到 Plan mode,嘗試執行寫入操作,應收到拒絕回應。
  • 確認 deny 規則正確攔截:新增一條 deny 規則後,對應工具呼叫應被阻擋。
  • 確認使用者確認後才執行:在需要確認的情境下,觀察工具是否在回覆前保持等待。
  • 確認模式切換即時生效:切換模式後立刻測試對應權限,不應沿用舊模式行為。

這四步對應「模式層、規則層、確認流程、即時性」,是最低可接受驗證集。

← 上一頁 下一頁:記憶系統 →