diff --git a/.agents/specs/data-exfil-warning/tasks.md b/.agents/specs/data-exfil-warning/tasks.md index b6246a6..fd64f15 100644 --- a/.agents/specs/data-exfil-warning/tasks.md +++ b/.agents/specs/data-exfil-warning/tasks.md @@ -30,10 +30,10 @@ ## 驗收 - [ ] V1 acr push 部署 webhook(首次)→ 互動警示 + 說明暴露 + 提示保護 的終端輸出 - [x] V2 非 TTY 跑 acr push 無 --confirm-exposure → 拒絕的輸出 -- [ ] V3 webhook 部署 API 無 exposure_consent → 拒絕的輸出 -- [ ] V4 同一 workflow 二次部署 → 不重問(已記住) +- [x] V3 webhook 部署 API 無 exposure_consent → 拒絕的輸出 +- [x] V4 同一 workflow 二次部署 → 不重問(已記住) - [ ] V5 --suppress-warning 後 → 不再警示,但 suppress 選擇有 log -- [ ] V6 同意後 → exposure_consent 寫進 record 可查(法律憑證) +- [x] V6 同意後 → exposure_consent 寫進 record 可查(法律憑證) ## 範圍邊界 - 不動用戶 API 入站保護機制(發 key/權限/限流)—— BACKLOG 待決策,本系統只在警示處「提示它存在」。 diff --git a/.claude/hooks/pre-bash-guard.sh b/.claude/hooks/pre-bash-guard.sh index d4cfde7..b86a9a3 100755 --- a/.claude/hooks/pre-bash-guard.sh +++ b/.claude/hooks/pre-bash-guard.sh @@ -78,4 +78,27 @@ if echo "$CMD" | grep -qE "git[[:space:]]+push.*--force.*(main|master)"; then "用 feature branch,或和 richblack 確認後手動操作" fi +# ───────────────────────────────────────────────────────────────────────────── +# 資料外流警示(data-exfil-warning SDD R2):AI 動手把資料變成可被外部呼叫前先擋 +# `acr push`(部署 webhook)/ `acr recipe push`(定義資料去向)= 暴露面動作。 +# 不含 `acr creds push`(上傳加密 credential 是保護,非暴露)。 +# 已帶 --confirm-exposure / --suppress-warning(人類已明示)→ 放行。 +# ───────────────────────────────────────────────────────────────────────────── +if echo "$CMD" | grep -qE "\bacr[[:space:]]+(recipe[[:space:]]+)?push\b" \ + && ! echo "$CMD" | grep -qE "\bacr[[:space:]]+creds[[:space:]]+push\b"; then + if ! echo "$CMD" | grep -qE "\-\-(confirm-exposure|suppress-warning)"; then + cat >&2 <<'EOF' +❌ BLOCKED:資料外流警示(arcrun data-exfil-warning) +原因:acr push / acr recipe push 會把資料/workflow 變成「可被外部呼叫」(暴露面)。 + 這種動作不該由 AI 自行執行——需人類明示知情同意(法律憑證)。 +正確做法: + - 由人類在終端機親自執行(會跳互動警示、要你輸入資源名確認、並提供保護選項) + - 或人類確認後加 --confirm-exposure(你已知悉暴露風險) + - 確定要公開且不再提醒:--suppress-warning +參考:.agents/specs/data-exfil-warning/ +EOF + exit 2 + fi +fi + exit 0