← 所有作品

CloudSheriff:唯讀的 AWS CIS 設定漂移監控

唯讀的 AWS CIS 設定漂移監控:偵測變更、追查操作者,LLM 只負責解釋、不參與判斷。

問題

AWS 帳號週一還符合 CIS benchmark,週二可能就因為有人開了一條 security group 而不合規。定期掃描只會告訴你某個控制項現在失敗,卻不會說明改了什麼、誰改的,也分不清這是新問題,還是團隊已接受的雜訊。再把 LLM 放進流程,又多一層風險:如果由模型決定什麼算告警,它就可能被資源裡的一段文字說服,而放掉該發的告警。

CloudSheriff 是為 Daytona HackSprint 做的限時專案(time-boxed build),設了兩條硬性限制:對帳號只有唯讀權限,以及模型永遠不參與判斷。

做法

三種證據來源,各司其職:

告警由純程式碼根據結構化欄位決定。LLM 拿到的是已經決定好的告警,只負責替值班工程師寫一段簡短說明。

測試環境是用 OpenTofu 在專用沙盒帳號建立、刻意設錯的實驗環境:一組合規的 security group 作為漂移目標;一組從第一天就對網際網路開放 RDP 的舊 group(已知雜訊,必須保持靜默,還帶著想說服模型降級的文字);以及絕不該告警的負向對照組。

運作方式

從掃描到附說明的告警

  1. 最小權限。 工具使用 external ID 與短期憑證,取得(assume)一個稽核角色:AWS 的 SecurityAudit 與 ViewOnlyAccess,外加明確拒絕讀取物件內容、機密值與解密。
  2. 用完即丟的掃描室。 固定版本的 Prowler 在全新的 Daytona 沙盒中執行;憑證只在該次掃描期間存在,掃完沙盒即刪除。
  3. 穩定的證據。 只正規化 JSON-OCSF 的結構化欄位,不對狀態文字做雜湊,因為掃描器改了用語會製造假漂移。
  4. 三軸比對。 每筆 finding 與已存狀態比較三個維度:評估結果(通過、失敗、未評估)、生命週期(作用中、已解決、資源消失)、變化(新增、退步、變更、不變)。針對性的重掃不會把沒掃到的控制項標成已修復。
  5. 確定性的告警閘門。 必須同時滿足:評估失敗、屬於新增、退步或變更,且嚴重度為 medium 以上。基準線(baseline)掃描永遠不告警。
  6. 溯源。 針對 security group 告警,工具查詢相符的 CloudTrail 事件;事件還沒送達就回報「溯源待定」,而不是「查無此人」。
  7. 說明。 模型只拿到已決定的事實,資源標籤放在標示為不可信資料的區塊,而且沒有任何 AWS 憑證。若 API 失敗或拒答,改由範本產生說明。整個呼叫以 Arize 追蹤。

成果

2026-09-30 完整流程實機跑通:建立基準線、對 demo group 開放 SSH 給網際網路、收到恰好一則帶有 CloudTrail 溯源與 LLM 說明的退步告警,關閉規則後狀態回到已解決。該次 CloudTrail 約兩分鐘送達事件。

離線測試方面,70 個單元測試通過(1 個跳過),6 個 OpenTofu 測試以 mock provider 通過。另有一支腳本模擬稽核角色的政策,檢查 14 個寫入或讀取資料內容的動作會被拒絕、6 個讀取動作會被允許,這是「唯讀」主張的佐證。

專案已下線:實驗環境於 2026-10-06 銷毀,掃描映像檔也已刪除。

學到的事