額外內容 — 治理掛鉤¶
📎 額外實作課程 — 不屬於 Copilot SDK。 此內容涵蓋由以下項目驅動的 Shell 掛鉤:
.github/hooks/、一個 Copilot CLI 功能。SDK 有自己的處理程序內對等功能 — 請參閱以下內容的權限章節: 實作課程 03 — 工具。此內容為選修,且與編號的 SDK 學習路徑彼此獨立。
目標: 讓 preToolUse 安全性防護閘門確實會封鎖對機密檔案的存取、觀察稽核記錄器記錄活動,並瞭解設定錯誤的掛鉤為何比完全沒有掛鉤更危險。
時間: 約 20 分鐘
必要條件: 額外內容 — 自訂代理程式 完成。 jq 已安裝 — 掛鉤指令碼仰賴它。
步驟 1 — 查看掛鉤的接線方式¶
四個生命週期事件,各自對應一個指令碼:
| 事件 | 指令碼 | 用途 |
|---|---|---|
sessionStart |
session-init.sh |
宣告原則並開始稽核軌跡 |
preToolUse |
security-gate.sh |
允許或拒絕 工具呼叫執行前 |
postToolUse |
audit-logger.sh |
記錄實際發生的情況 |
sessionEnd |
session-end.sh |
結束並摘要工作階段 |
每個項目都會宣告 type、 bash 要執行的指令碼、工作目錄,以及 timeoutSec.
只有 preToolUse 可以 停止 任何操作。其他事件只負責觀察。
步驟 2 — 一個警示案例¶
此存放庫曾有一段時間包含故障的防護閘門。設定指向:
…但磁碟上的檔案是 security-gate.sh。參照的指令碼 並不存在.
防護閘門沒有發生錯誤,也沒有發出警告。它只是完全沒有執行 — 每個工具呼叫都未經檢查直接通過,但存放庫看起來卻受到完整治理。舊版的 .env
甚至包含註解,聲稱「preToolUse 掛鉤應封鎖對此檔案的存取」。實際上並不會。
這項問題已修正,也是本實作課程中最重要的教訓:
⚠️ 設定錯誤卻毫無警示的控制措施,比完全沒有控制措施更糟,因為這會製造虛假的信心。請務必證明防護閘門確實有觸發。
確認參照現在正確無誤:
列出的每個路徑都必須存在於 .github/hooks/scripts/.
步驟 3 — 閱讀防護閘門¶
合約很簡單 — stdin 輸入 JSON,stdout 輸出決策:
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.toolName')
TOOL_ARGS=$(echo "$INPUT" | jq -r '.toolArgs')
它會在三種情況下拒絕:
- 具破壞性的 Bash 操作 —
rm -rf /,rm -rf .,DROP TABLE,DROP DATABASE,format,mkfs.、Fork bomb 模式 - 機密資訊存取 — 提及以下內容的命令:
.env,credentials,secrets,.pem,.key或password - 越界寫入 —
edit/create之外src/,tests/,docs/或.github/
並發出下列其中一個結果:
⚠️ 請注意,它會以以下狀態結束: 0 ,即使拒絕時也是如此。 決策 會隨 JSON 承載資料傳送,而不是透過結束代碼 — 非零結束代碼看起來會像掛鉤損壞,而非刻意拒絕。
步驟 4 — 證明防護閘門會封鎖機密資訊¶
確認指令碼具備執行權限,且記錄目錄已存在:
現在,請透過管線傳入真正工具呼叫會送出的 JSON,直接進行測試:
echo '{"toolName":"bash","toolArgs":{"command":"cat .env"}}' \
| ./.github/hooks/scripts/security-gate.sh
預期結果:
{"permissionDecision":"deny","permissionDecisionReason":"Access to credential/secret files blocked by security policy"}
這表示防護閘門確實生效 — 也就是先前從未執行的同一項檢查。
步驟 5 — 測試其他路徑¶
具破壞性的命令:
echo '{"toolName":"bash","toolArgs":{"command":"rm -rf /"}}' \
| ./.github/hooks/scripts/security-gate.sh
→ "Destructive command blocked by retail governance policy"
寫入允許目錄之外的位置:
echo '{"toolName":"create","toolArgs":{"path":"/etc/hosts"}}' \
| ./.github/hooks/scripts/security-gate.sh
→ "File edits restricted to src/, tests/, docs/, .github/, and top-level project docs"
位於最上層的專案檔案,必須通過:
echo '{"toolName": "create", "toolArgs": {"path": "README.md"}}' \
| ./.github/hooks/scripts/security-gate.sh
→ {"permissionDecision":"allow"}
允許清單會比對 相對於存放庫 路徑,因此即使存放庫外有外觀相似的項目,仍會遭到拒絕:
echo '{"toolName": "create", "toolArgs": {"path": "/etc/README.md"}}' \
| ./.github/hooks/scripts/security-gate.sh
→ 遭到拒絕。若只比對檔名,原本會讓該操作通過。
以及必須通過的合法呼叫:
echo '{"toolName":"bash","toolArgs":{"command":"dotnet build"}}' \
| ./.github/hooks/scripts/security-gate.sh
→ {"permissionDecision":"allow"}
⚠️ 務必也要測試允許案例。 一個拒絕所有操作的防護閘門,雖然能通過所有「是否有封鎖?」測試,卻會讓存放庫完全無法使用。
步驟 6 — 檢視拒絕記錄¶
每次拒絕都會附上 UTC 時間戳記、工具及原因,並附加至記錄:
2026-08-10T11:04:35Z DENIED tool=bash reason="Access to credential/secret files blocked by security policy"
這正是法規遵循檢閱人員會要求的成品:證明控制措施確實存在 以及 它確實觸發的證據。
步驟 7 — 防護閘門不需要檔案實際存在¶
此存放庫未認可任何機密檔案 — .env 已由 gitignore 忽略,絕不能認可。這不會削弱防護閘門,因為它會比對
命令文字,而不是磁碟上實際存在的內容。
確認沒有 .env,然後仍嘗試讀取它:
ls .env 2>/dev/null || echo "no .env present"
echo '{"toolName":"bash","toolArgs":{"command":"cat .env"}}' \
| ./.github/hooks/scripts/security-gate.sh
仍遭到拒絕。其他機密資訊模式也會得到相同結果:
echo '{"toolName":"bash","toolArgs":{"command":"cat ~/.ssh/id_rsa.key"}}' \
| ./.github/hooks/scripts/security-gate.sh
💡 這是雙面刃。文字比對表示防護閘門不會因檔案尚不存在而遭規避 — 但避免使用觸發詞的命令也可能繞過它(cat .en''v,或透過指令碼讀取檔案)。請將它視為防止意外的防護措施,而非抵禦蓄意攻擊者的防線。
步驟 8 — 在掛鉤啟用時執行工作階段¶
接著檢查稽核記錄器擷取的內容:
💡 掛鉤由 CLI 針對每個工作階段設定。若未顯示任何內容,請確認 CLI 已為此存放庫載入 .github/hooks/retail-governance.json 於此存放庫。
步驟 9 — 停用掛鉤¶
開發掛鉤時,您會希望暫時停用它。您可以重新命名設定:
mv .github/hooks/retail-governance.json .github/hooks/retail-governance.json.off
# restore with the reverse
…或者從陣列中移除個別事件的項目,以註解該事件。
⚠️ 絕不要在共用分支中停用防護閘門後忘記還原 — 這會重現步驟 2 的無聲失敗情況。請考慮新增 CI 檢查,判斷設定中的每個 bash 設定中的路徑確實存在於磁碟上。
✅ 檢查點¶
- [x] 您能說出四個掛鉤事件,以及哪一個可以拒絕操作
- [x] 您已證明防護閘門會封鎖機密資訊、具破壞性的命令及不當位置的寫入
- [x] 您已確認合法呼叫仍會通過
- [x] 您已找到拒絕記錄中的證據
- [x] 您能說明故障的參照為何危險
💡 延伸練習¶
新增規則至 security-gate.sh 以封鎖 git push --force 於 main。請測試它會拒絕強制推送,同時確認一般的 git push 仍會通過。
相關內容¶
- 下一步: 額外內容 — 擴充 API
- 深入解析:掛鉤與治理
AGENTS.md— 適用於 AI 代理程式的存放庫規則