← 返回目錄
第 5 章

安全層:權限、Hook 和三層防護網

27 個檔案的權限系統、Hook 三個時點、Pre-hook 五種能力,以及三層防護怎麼組合

安全不是事後補丁

許多工具的安全機制是在核心功能完成後補進去的——加個確認對話框、加個 --dry-run 旗標、加個「你確定嗎」提示。這種做法的問題是安全層和執行層耦合鬆散,繞過不難。

Claude Code 的做法相反。安全層嵌在工具執行 Pipeline 的第 3-8 步(共 14 步),每次工具呼叫都強制經過,不存在「跳過安全檢查直接執行」的路徑。這是架構決策,不是介面設計。

權限系統:27 個檔案,三層配置

權限系統橫跨 27 個檔案,但核心邏輯是三層覆蓋:

Global 層~/.claude/settings.json)定義使用者層面的預設行為,適用於所有專案。Project 層.claude/settings.json)覆蓋 Global 設定,適用於當前專案。Session 層是執行時動態設定的臨時權限,只在當前會話有效,不寫入磁碟。

三層的解析順序是 Session > Project > Global。當 Project 層明確允許某個工具免確認時,Global 層的保守設定失效——更具體的配置優先。這個規則和 .gitignore 的覆蓋邏輯類似,有意為之。

Hook:三個時點

Hook 是使用者或 Plugin 注入自訂邏輯的機制,有三個觸發時點:

PreToolUse 在工具執行前觸發,能力最強,可以修改輸入、阻止執行、追加上下文。PostToolUse 在工具成功執行後觸發,主要用於審計日誌和後處理。PostToolUseFailure 在工具執行失敗後觸發,用於錯誤通知或清理邏輯。

三個時點裡,PreToolUse 是最關鍵的,後面詳細看。

PreToolUse:五種能力

Pre-hook 的回傳值不是簡單的允許/拒絕,而是五種結構化能力:

permissionBehavior 控制這次工具呼叫的權限決定——allowdeny,或把決定權交回給內建規則的 defaultupdatedInput 允許 hook 修改工具的輸入參數,執行時用的是修改後的版本。blockingError 讓 hook 注入一條錯誤訊息,工具不執行,錯誤作為工具結果回傳給模型。preventContinuationblockingError 更強硬——直接中止整個 Agent 執行,不只是這次工具呼叫。additionalContexts 向模型追加上下文資訊,工具照常執行,但模型在下一輪看到的資訊更多。

這五種能力組合起來,讓 hook 能做到細粒度的行為干預:想攔截就攔截,想修改就修改,想補資訊就補,不需要改一行核心程式碼。

resolveHookPermissionDecision()

Pre-hook 的五種回傳值由 resolveHookPermissionDecision() 函式統一解析。它的職責是把 hook 的意圖翻譯成 Pipeline 能理解的決定,處理衝突(多個 hook 回傳不同的 permissionBehavior 時怎麼取捨),以及確保 hook 的回傳格式合法。

這個函式是安全層的決策樞紐。工具執行 Pipeline 的第 5 步就是呼叫它,結果決定後續步驟怎麼走。

三層防護網

把整個安全架構俯視一下,是三層獨立的防護網串聯:

第一層是 Speculative Classifier,在串流階段就預測工具呼叫的風險等級,高風險的提前標記,讓後續步驟有更多時間準備。第二層是 Hook Policy,用 Pre-hook 的五種能力做精細干預,這層可以被使用者和 Plugin 自訂。第三層是 Permission Decision,結合三層配置(Global/Project/Session)和 resolveHookPermissionDecision() 的輸出,做最終的允許或拒絕。

三層串聯,每層獨立,任何一層攔截都能阻止工具執行。這也是「不繞過」原則的實作——沒有一條程式碼路徑能在繞過三層的情況下直接執行工具。


參考來源: 本文內容參考 Xiao Tan(@tvytlx)的《Claude Code 源碼架構深度解析 V2.0》,基於原報告的分析框架和研究成果整理。