#!/bin/bash # .claude/hooks/pre-bash-guard.sh # arcrun PreToolUse guard for Bash # # 職責:擋下會違反 CLAUDE rules 的 shell 指令 # 退出 code: # 0 = 允許 # 2 = 擋下(stderr 訊息會回傳給 CC) set -o pipefail INPUT=$(cat) CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""') block() { local rule="$1" local reason="$2" local fix="$3" cat >&2 </main.go" fi # ───────────────────────────────────────────────────────────────────────────── # 規則 1.3:禁止 wrangler init / generate auth-* credential-* jwt-* # ───────────────────────────────────────────────────────────────────────────── if echo "$CMD" | grep -qE "wrangler[[:space:]]+(init|generate).*[[:space:]](auth|credential|jwt|oauth)[-_]"; then block "1.3" \ "禁止用 wrangler init/generate 建立 auth/credential/jwt Worker" \ "auth primitive 透過 component-worker-template/ 搭配 WASM binary 部署,不要 wrangler init" fi # ───────────────────────────────────────────────────────────────────────────── # 規則 3.1:Service Binding 新增警示 # ───────────────────────────────────────────────────────────────────────────── # 偵測在 wrangler.toml 新增 [[services]] 的 echo/cat/sed 操作(非 100% 準確,但夠用) if echo "$CMD" | grep -qE "echo.*\[\[services\]\].*>>"; then block "3.1" \ "偵測到要在 wrangler.toml 新增 [[services]] binding" \ "零件串接一律走 HTTP URL(cypher binding),不新增 service binding。若有特殊需求,先與 richblack 確認" fi # ───────────────────────────────────────────────────────────────────────────── # 一般性危險指令 # ───────────────────────────────────────────────────────────────────────────── if echo "$CMD" | grep -qE "rm[[:space:]]+-rf[[:space:]]+(/|/\*|~|\\\$HOME|\.)"; then block "general" \ "偵測到危險的 rm -rf 指令" \ "明確指定要刪的目錄,不要對根目錄 / home / 當前目錄遞迴刪除" fi # 禁止 force push 到 main if echo "$CMD" | grep -qE "git[[:space:]]+push.*--force.*(main|master)"; then block "general" \ "禁止 force push 到 main/master" \ "用 feature branch,或和 richblack 確認後手動操作" fi # ───────────────────────────────────────────────────────────────────────────── # 資料外流警示(data-exfil-warning SDD R2):AI 動手把資料變成可被外部呼叫前先擋 # `acr push`(部署 webhook)/ `acr recipe push`(定義資料去向)= 暴露面動作。 # 不含 `acr creds push`(上傳加密 credential 是保護,非暴露)。 # # 信任修正(2026-05-30):無「旗標放行」捷徑——AI 自己能加的旗標 = 自己批准自己。 # 這類動作一律擋,必須由人類在終端機親自執行(CLI 會跳互動、要人類輸入資源名確認)。 # ───────────────────────────────────────────────────────────────────────────── # 只在「指令本身就是執行 acr push / acr recipe push」時擋(錨定到指令開頭, # 允許前置 cd .. && 或環境變數)。避免誤判 git commit -m "...acr push..." 這類 # 「字串裡剛好提到 acr push」的情況(commit message / echo / grep 不該被擋)。 if echo "$CMD" | grep -qE "(^|&&|;|\|)[[:space:]]*(cd[[:space:]][^&;|]*(&&|;)[[:space:]]*)?([A-Za-z_]+=[^[:space:]]*[[:space:]]+)*acr[[:space:]]+(recipe[[:space:]]+)?push\b" \ && ! echo "$CMD" | grep -qE "acr[[:space:]]+creds[[:space:]]+push\b"; then cat >&2 <<'EOF' ❌ BLOCKED:資料外流警示(arcrun data-exfil-warning) 原因:acr push / acr recipe push 會把資料/workflow 變成「可被外部呼叫」(暴露面)。 這種動作你(AI)不能自行執行,也沒有旗標捷徑——需人類明示知情同意(法律憑證)。 正確做法: - 把這件事交給人類:請人類在終端機親自執行(CLI 會跳互動、要人類輸入資源名確認) - 人類第一次確認後 server 會記住,之後同資源不用再確認 參考:.agents/specs/data-exfil-warning/ EOF exit 2 fi exit 0