跳至主要內容

掛鉤與治理

本頁說明下列路徑中的治理掛鉤: .github/hooks/。這些掛鉤為 Agent HQ 示範加入工作階段記錄、工具執行前安全閘道、工具執行後稽核記錄,以及工作階段摘要。

retail-governance.json 結構描述

.github/hooks/retail-governance.json 宣告一組簡單的掛鉤設定:

  • version:數值型設定版本,目前為 1
  • hooks:對應表,其中每個索引鍵都是生命週期事件名稱。
  • 每個事件值都是命令項目的陣列。
  • 每個命令項目包含:
  • type:目前為 command
  • bash:要執行的指令碼路徑。
  • cwd:命令的工作目錄。
  • timeoutSec:以秒為單位的最長執行時間。

範例項目:

{
  "type": "command",
  "bash": "./.github/hooks/scripts/security-gate.sh",
  "cwd": ".",
  "timeoutSec": 15
}

生命週期事件

治理檔案會將四個生命週期事件連接至四個 Shell 指令碼:

事件 指令碼 用途
sessionStart .github/hooks/scripts/session-init.sh 初始化工作階段記錄
preToolUse .github/hooks/scripts/security-gate.sh 允許或拒絕使用工具
postToolUse .github/hooks/scripts/audit-logger.sh 附加 JSONL 稽核事件
sessionEnd .github/hooks/scripts/session-end.sh 寫入工作階段摘要

指令碼行為

session-init.sh

session-init.sh 會從 stdin 讀取掛鉤 JSON,並使用 jq 擷取 .source.timestamp.cwd,建立 logs/,然後將格式化的 SESSION START 區塊附加至 logs/session.log,其中包含 UTC 時間、來源、cwd 與目前的作業系統使用者。

security-gate.sh

security-gate.shpreToolUse 閘道。它會從 stdin 讀取 JSON,並使用 jq 擷取 .toolName.toolArgs

針對 bash,它會拒絕符合下列破壞性模式的命令:

  • rm -rf /
  • rm -rf .
  • DROP TABLE
  • DROP DATABASE
  • format
  • mkfs.
  • 包含下列內容的 Fork bomb 語法: :(){

它也會拒絕參照認證或祕密路徑與詞彙的 bash 命令:

  • .env
  • credentials
  • secrets
  • .pem
  • .key
  • password

針對 editcreate,它會擷取 .toolArgs.path。若路徑不符合掛鉤的允許清單運算式 — src/tests/docs/.github/ — 即會遭到拒絕,但下列少數頂層專案檔案允許清單除外(README.mdAGENTS.mdmkdocs.yml),比對時會使用相對於儲存庫 的路徑。將比對錨定在儲存庫根目錄,可防止 /etc/README.md 僅因檔名相符而通過。請注意, SECURITY.md 與授權檔案仍不在允許清單內,這符合下列文件中的「未經許可不得修改」規則: AGENTS.md

允許的作業會輸出:

{"permissionDecision":"allow"}

遭拒的作業會在 logs/security-denials.log 附加一行記錄,並輸出下列結構:

{"permissionDecision":"deny","permissionDecisionReason":"Access to credential/secret files blocked by security policy"}

audit-logger.sh

audit-logger.shpostToolUse 掛鉤。它會讀取 .toolName.toolArgs.timestamp.cwd,將字串化的工具引數截短為 500 個字元、分類作業、建立 logs/,然後將每行一個 JSON 物件附加至 logs/agent-audit.jsonl

分類如下:

工具名稱 類別
bash command-execution
edit code-edit
create file-creation
view code-read
grep, glob code-search
其他任何項目 other

稽核記錄格式如下:

{
  "timestamp": "input timestamp",
  "logged_at": "UTC write time",
  "tool": "tool name",
  "category": "operation category",
  "args": "first 500 characters of toolArgs",
  "cwd": "working directory"
}

session-end.sh

session-end.sh 會從 stdin 讀取 .reason,並計算 logs/agent-audit.jsonllogs/security-denials.log 中的行數(若這些檔案存在),然後將格式化的 SESSION END 區塊附加至 logs/session.log

已修正:preToolUse 從未執行

retail-governance.json 先前將 preToolUse 指向 ./.github/hooks/scripts/security-gate-notworking.sh,但該檔案並不存在。實際的指令碼是 security-gate.sh,因此閘道一直未執行且沒有提示。此問題已修正。

此問題顯示掛鉤設定錯誤可能在沒有提示的情況下失敗。務必確認閘道確實會觸發,尤其是用來強制執行安全性控制的拒絕路徑。

手動測試掛鉤

從儲存庫根目錄將具代表性的掛鉤 JSON 透過管線傳入指令碼,以直接執行測試:

echo '{"toolName":"bash","toolArgs":{"command":"cat .env"}}' | \
  ./.github/hooks/scripts/security-gate.sh

預期結果:傳回拒絕用的 JSON 物件,並在下列檔案中新增一行: logs/security-denials.log

您也可以用相同方式測試允許的路徑:

echo '{"toolName":"create","toolArgs":{"path":"docs/example.md"}}' | \
  ./.github/hooks/scripts/security-gate.sh

暫時停用掛鉤

若要進行短暫的本機實驗,請移除相關事件項目,或在 .github/hooks/retail-governance.json 中將該事件陣列設為 [],並在提交前還原。請優先僅停用必要的最小範圍掛鉤;例如,若要測試安全閘道設定,只需清空 preToolUse