[[我也希望安全第一]]|第 14/30 天
需求看起來很單純:研究團隊要測 Agent 能不能完成資安題目,因此需要 shell、套件安裝和一組可重置的靶機。平台團隊通常會先拿現有 staging 改,因為那裡部署快、資料能重建,大家也習慣共用幾項服務。
真正列權限時,事情開始不對勁。套件要從哪裡下載?runner 能不能解析公司 DNS?雲端 metadata endpoint 是否可達?現有 registry token 還能讀哪些專案?log 要往外送,但 Agent 能不能沿同一條路回寫?
安全評估還可能故意關掉模型防護,交付很難的攻擊任務,允許長時間執行。此時 runner 裡的工作負載可能比一般 production 版本更積極。這套環境不能沿用「反正只是測試」的鬆散習慣。
一個比較能工作的架構不是完全沒有外部依賴,而是所有必要依賴都經過狹窄、可替換的 broker:
┌── immutable package mirror
│ (固定快照、唯讀)
Agent runner ──┬── egress gateway ── synthetic targets
ephemeral │ deny others (私有測試網段)
no host mount│
├── credential broker ── job-scoped token
│ no static secret
└── telemetry sink ──── append-only evidence store
production/corp network/cloud metadata:沒有路由、沒有信任關係
這裡有四個容易被忽略的細節。
第一,套件 mirror 不是任意 HTTP proxy。評估需要哪些套件,可以事先固定 digest;真的要動態安裝,也應經過能檢查目的地和內容的 gateway。第二,runner 不掛 host socket、家目錄或共享 credential cache。第三,每個 job 向 broker 換取短效、單用途身分,job 結束就撤銷。第四,telemetry 往外送的路徑只能 append,Agent 不能回頭修改證據。
若 runner 跑在 Kubernetes,可以先對 namespace 建立出站預設拒絕:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: eval-default-deny-egress
namespace: agent-eval
spec:
podSelector: {}
policyTypes:
- Egress
接著只開到同 namespace、帶有特定 label 的 egress gateway:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: eval-allow-egress-gateway
namespace: agent-eval
spec:
podSelector:
matchLabels:
role: agent-runner
policyTypes: [Egress]
egress:
- to:
- podSelector:
matchLabels:
role: controlled-egress
ports:
- protocol: TCP
port: 8443
套用 YAML 不代表隔離已成立。Kubernetes 官方安全清單建議 namespace 採 default deny,也提醒實際能力取決於 CNI;cloud metadata、DNS、IPv6、host network 與同節點旁路都要另外測。
部署後從真實 runner image 執行一組負向測試,並把預期結果寫死:
測試 A:連公開 HTTPS 網站 → 連線失敗,產生 deny log
測試 B:連 169.254.169.254 metadata → 連線失敗,S1 告警
測試 C:直接連 production IP → 連線失敗,不因略過 DNS 而成功
測試 D:經 gateway 取允許套件 → 成功,只能取得固定 digest
測試 E:跟隨 redirect 到外站 → gateway 拒絕
測試 F:讀取其他 job 的 secret → IAM 拒絕,記錄 actor 與 resource
測試 G:關掉 policy/DNS 服務 → fail closed,不自動開放網路
還要測被允許的支援服務遭攻破。讓紅隊控制一個假 package response,看看能否藉 redirect、DNS、回呼 URL 或錯誤訊息建立第二條通道。Hugging Face 事件教訓最具體的地方,就是「允許的元件」本身也要當作不可信輸入。
完全斷網很適合測不需要外部環境的能力,卻會讓某些真實網安任務失去意義。鎖得太緊,也可能測不出模型發布後會出現的行為。
比較實際的作法是分兩階段:先在無網路環境做能力探測,再把確實需要互動的測試移到獨立私有網段,放入合成網域、假憑證與可重置目標。要測公開網路能力時,則需要更高核准層級、即時監看與明確時間窗,而不是把一般 runner 的開關改成 internet=true。
這些控制都花錢。OpenAI 在 Hugging Face 事件後公布的新監控設計,估計監控本身需要相當於被監控工作約 20% 的算力。對趕 benchmark 的團隊,這很容易被看成拖慢速度的負擔。問題是,一次跨到第三方 production 後,省下來的那 20% 很可能要用更昂貴的事故調查補回去。
第 15 篇接著處理一件隔離無法保證的事:異常已經發生時,誰有權停、要停到哪裡,以及怎麼避免一按 kill switch 就把證據一起清掉。