7.44 多租戶平台的隔離層級:資料存放、建置管線、營運後台、資料庫管理與備份的權限範圍,跨租戶資料整合,以及事故報告要交代的隔離資訊
本章處理的是平台商的設計:電商後台、會員系統、客服系統這類 SaaS 把多個客戶(租戶)放在同一套程式與基礎設施上營運時,租戶之間的隔離要做在哪幾層、每一層分得多細。範圍從「一套系統服務多個客戶」已經成立的那一刻開始,不涵蓋要不要做成多租戶的商業決定。
涵蓋範圍:租戶之間的隔離層級,與請求歸屬、授權、容量爭用的分界
本章聚焦租戶之間的隔離層級,以及隔離層級在入侵發生時決定的影響範圍。授權怎麼檢查在 7.2 身分與授權邊界;單一請求屬於哪個租戶、這個主張憑什麼可信,在 7.40 B2B 多租戶的身分接入;租戶邊界要在查詢、cache key、log、稽核與測試裡保持一致的設計責任,見 Tenant Boundary(租戶邊界)。租戶之間搶容量(一家促銷拖慢其他家)與本章的外洩風險來自同一件事:多個租戶共用同一組資源,差別在損失的是可用性,見 Noisy Neighbor 與 Shopify:Pod Architecture 與 Resiliency Matrix。入侵已經發生之後怎麼清查與重建,在 8.25 建置主機被入侵後的根除與重建。
平台附加風險與以租戶數計的影響範圍
平台附加風險是客戶因為與其他客戶共用同一個平台而多承擔的外洩風險。一個商家自己架站時,他的資料只會因為他自己的系統被入侵而外洩;搬上平台之後多了三條路徑:其他租戶的帳號被入侵、攻擊者再利用平台的隔離缺陷讀到這個商家的資料;平台自己的元件被入侵;平台員工的工具被入侵。
平台把每個商家各自做不好的事(修補漏洞、備份、監控、值班)集中由專責團隊做好,商家各自維運時的那些風險因此降低,這是平台的價值。平台附加風險是同一個集中的另一面:集中讓防禦有規模經濟,也讓一次入侵的收穫有規模經濟。所以設計多租戶平台時要算得出一個量:平台上任何一個元件被入侵時,攻擊者存取得到幾個租戶的資料。 這個數字就是該元件的影響範圍(Blast Radius),本章以租戶數為單位計算。
影響範圍由兩件事共同決定,兩件事要分開看:存放層的隔離是資料放在一起的程度,存取層的隔離是能讀寫那些資料的元件與人手上的權限範圍。下文的隔離層級指同一層分得多細。存放層在常見實作下(bridge 共用一個高權限帳號連線)從細到粗是 silo、cell、bridge、pool;存取層從細到粗是每次存取限定單一租戶、限定一個 cell、一份存取憑證讀得到全部租戶。資料分得再細,只要有一個元件手上的憑證能讀所有分區,那個元件的影響範圍就是全部租戶。
存放層的隔離模型
AWS 的多租戶儲存指引(SaaS Storage Strategies 白皮書、Guidance for Multi-Tenant Architectures)用 pool、bridge、silo 三個名字區分資料的放法,本章另外加上把租戶分組的 cell,cell 不在 AWS 這組名字裡。四種放法的差別在一份資料庫憑證被拿走時,讀得到幾個租戶,以下依成本由低到高介紹。
Pool(共用表):所有租戶的資料放在同一組表裡,每一列帶一個 tenant_id 欄位,應用程式在每一條查詢加上租戶條件。成本最低、維運最簡單、跨租戶統計最方便。它的隔離由應用程式的查詢條件與資料庫的列層級安全性(Row-Level Security)承擔,這兩者擋的是正常請求讀到別人的資料。列層級安全性依每次連線設定的租戶變數過濾資料列,而設定這個變數的正是持有憑證的應用程式;憑證落到攻擊者手上,攻擊者可以逐一換成每個租戶的值來讀,所以憑證外洩時影響範圍是全部租戶。
Bridge(共用資料庫伺服器、每租戶一個 schema):同一台資料庫伺服器上每個租戶有自己的 schema,可以替每個租戶發不同的資料庫帳號。連線池以一組帳號建立連線,按租戶分帳號就要每個租戶一個連線池,所以常見的實作仍用一個高權限帳號連到所有 schema。判斷 bridge 的實際隔離強度,要查的是應用程式實際用哪一個帳號連線:同一個帳號連到所有 schema 時,影響範圍與 pool 一樣是全部租戶,只是資料看起來分開了。AWS SaaS Lens 的 bridge 另指同一個系統裡不同層分別採用 silo 與 pool,與這裡的儲存放法不同。
Silo(每租戶一套):每個租戶有自己的資料庫,也可以連運算資源與網路都分開。一份憑證只讀得到一個租戶,影響範圍最小;成本隨租戶數線性上升,升級與 schema 變更要對每一套各做一次。適合少數高營收、高合規要求的大客戶。
Cell(租戶分組):把租戶分成多組,每組有自己的資料庫與快取。組內通常是 pool 或 bridge,組與組之間是分開的資料庫。一個 cell 被入侵時影響範圍是那一組的租戶數,成本隨組數上升,不隨租戶數上升。團隊為每個租戶各維運一套環境的成本超過能承擔的程度時,cell 是仍能把影響範圍從全部租戶降到一組的做法。分組的依據通常是租戶規模、地區與資料敏感度。一個 cell 只放一個租戶時就是 silo。Cell-Based Architecture 描述的 cell 連前端與應用層都按組分開,本章的 cell 只要求資料庫與快取分開,跨組共用的運算改在存取層列為共用元件。
Shopify 的 pod 是 cell 的一個公開實例,它分開的是資料庫與快取,應用伺服器與背景工作的運算大部分跨 pod 共用,用來吸收促銷尖峰。資料分開而運算共用,在以租戶數計的影響範圍上有實質影響:共用的應用伺服器手上有連到每一個 pod 的憑證,它的影響範圍是全部 pod,要在存取層另外盤點。
四種放法並存是常態:大客戶走 silo、一般客戶分 cell、試用帳號走 pool。
存取層的隔離:建置管線、共用運算、營運後台、內部工具平台、資料庫管理、備份與其他共用元件的權限範圍
存放層分得再細,平台上總有一些元件要碰所有租戶:部署程式的建置管線、跨 cell 共用的應用伺服器與背景工作、平台員工用的營運後台與內部工具平台、資料庫管理工具、備份系統、跨租戶的報表資料倉儲(data warehouse)。這些元件各自持有的權限,決定了存放層的分區在入侵時還剩多少效果。下面逐項寫的是最常見的幾類,盤點時不以這幾類為限。
建置與部署管線(CI/CD):管線的職責是把程式碼建置成產物、送到各個環境。這個職責不需要讀取任何正式環境的客戶資料,而平台團隊常在管線主機上放正式環境的資料庫憑證,常見的用途是跑 migration、做部署後的煙霧測試、方便除錯,管線主機兼做排程時還有排程任務。管線主機被入侵時,這份憑證讓攻擊者直接從建置環境走進正式資料庫,存放層的分區全部被繞過。每一種用途都有不需要這份憑證的替代做法,平台團隊限縮管線權限時要把所有用途一起換掉,只要留下任何一種,那份憑證就還得留在管線主機上:
- migration:由部署到正式環境內的工作執行,使用正式環境自己的憑證,管線只觸發這個工作。已經分 cell 的平台,在每個 cell 內各自執行、使用該 cell 的憑證。
- 煙霧測試:改打正式環境的健康檢查端點,或一個專門用來測試的合成租戶,不讀真實租戶的資料。
- 除錯:工程師需要看正式資料時,走營運後台的查詢流程,營運後台的查詢限制(每次查詢指定租戶與工單編號、批次匯出要第二個人核准、存取寫進稽核紀錄)在這裡同樣適用。
- 排程任務:報表、資料清理、回填這類排程工作移到正式環境內的排程器,以正式環境自己的身分執行。
換掉之後,管線手上剩下的是部署權:推送產物、觸發部署。部署出去的產物就是正式環境接下來要執行的程式,所以部署權等於讓正式環境執行任意程式,管線被入侵時攻擊者能做的事變成推送惡意產物,要靠兩項控制一起擋:
- 存取憑證改成短期、按目標分開:管線用工作負載身分(由執行環境發給這個工作、不必在管線設定裡存放長期金鑰的身分)換取只對單一環境有效的臨時憑證。臨時憑證的有效期以十幾分鐘到一小時計(AWS STS 預設一小時、最短十五分鐘,可在角色上調短),外洩之後可用的時間有上限(7.10 Workload Identity 與聯邦信任邊界;GitHub Actions 的做法見 環境保護與 OIDC 雲端認證)。CI 集中持有憑證時怎麼盤點每把憑證的擁有者與用途,見 7.6 秘密管理與機器憑證治理〈CI secrets 集中化跟 blast radius〉。
- 產物由各 cell 驗證後拉取:各 cell 驗證產物的簽章與來源證明(Artifact Provenance)之後才拉取部署,並確認產物對應到經過審查的 commit,管線不必持有進入每個 cell 的憑證。簽章驗證擋得住惡意產物的前提是簽章在建置步驟碰不到的地方產生:獨立的簽章服務,或建置平台在建置步驟之外產生的來源證明。管線自己持有簽章金鑰時,攻擊者推上去的是簽好章的產物,簽章只證明它出自這條管線;建置管線上游被植入、已簽章產物照常發佈的實例見 SolarWinds 2020,簽章金鑰為什麼要與一般憑證分開保管見 7.6〈簽章金鑰跟長期信任根〉。產物在部署前要驗證哪些屬性(來源、完整性、相依套件),見 7.12 供應鏈完整性與 Artifact 信任。
CI 平台本身被入侵、集中保管的 secrets 整批暴露的實例見 CircleCI 2023,CI 伺服器漏洞成為入口的實例見 TeamCity 2023。
跨 cell 共用的應用伺服器與背景工作:本章的 cell 只分開資料庫與快取,跨 cell 共用的應用伺服器手上通常有連到每一個 cell 的憑證,任何一台被入侵(應用程式的遠端執行漏洞是最常見的入口)時影響範圍是全部 cell。應用伺服器在處理請求時才向秘密管理服務取得該 cell 的憑證,縮短的只是憑證留在記憶體裡的時間:攻擊者在伺服器上執行程式時,同樣能以伺服器的身分要到任何一個 cell 的憑證,影響範圍仍是全部 cell。要讓 cell 的分區延伸到運算層,換取憑證的身分本身要按 cell 分開,也就是每個 cell 各有一組運算、各自的工作負載身分只換得到自己 cell 的憑證;代價是失去跨 cell 共用運算吸收尖峰的能力。
營運後台與客服工具(客服工具的讀寫範圍與稽核見 Internal Admin Tool(客服後台)):平台員工要能查任何一個租戶的訂單,這類工具的職責本身需要跨租戶的讀取權。可以限縮的是每一次查詢的範圍,並留下每一次查詢的紀錄:查詢要指定租戶與工單編號、批次匯出要第二個人核准、存取寫進稽核紀錄並讓租戶查得到自己被誰查過(7.7 稽核追蹤與責任邊界)。員工帳號被接管時,這些限制把攻擊者一次能拿走的量從整個資料庫降到一次查詢一個租戶,並讓異常的查詢量成為可偵測的訊號。客服系統成為跨租戶外洩入口的實例見 Okta 2023 客服系統事件。
內部工具平台:營運團隊常用低程式碼的內部工具平台(拖拉介面就能做出查詢頁、批次操作頁的那一類,下面簡稱工具平台)自建後台。工具平台把連線設定集中保存在自己身上:建一個查詢頁時,連到正式資料庫、程式碼儲存庫或雲端帳號的連線與它的帳號密碼或金鑰存在工具平台裡,頁面只是呼叫這些連線。工具平台常被放在內網、只供員工使用,更新節奏比對外服務慢,而內網不等於攻擊者連不到(Lateral Movement(橫向移動))。工具平台被入侵時的影響範圍依攻擊者拿到的權限層級而不同:
- 工具平台本身被入侵(工具平台的漏洞讓攻擊者在它的主機上執行程式,或取得它的管理權限):攻擊者讀得到工具平台保存的每一個連線設定,拿到的是所有連線的權限總和;連線裡只要有一條通到共用的正式資料庫,影響範圍就是全部租戶。
- 能建立或編輯頁面的員工帳號被接管:這類帳號通常能在工具平台上新增查詢,打到自己有使用權的任何一條連線,影響範圍是那些連線的權限總和,不只是現有頁面的查詢範圍。
- 只能使用頁面的員工帳號被接管:攻擊者只能使用這位員工被授權的頁面,影響範圍是那些頁面的查詢在參數可以填的全部值之下碰得到的範圍。頁面的租戶編號這類查詢參數由瀏覽器送上來時,攻擊者直接改參數就查得到畫面上沒有的租戶,這一層的影響範圍等於那條連線本身的權限。
一個已知漏洞落在哪一層(例如認證繞過只拿到一般使用者的權限),要看它讓攻擊者拿到什麼權限;分不出來時,按影響範圍較大的那一層計算。外洩來源還沒確定時,這樣算出的範圍就是判斷嫌疑元件碰得到哪些商家、風險預警要發給誰的依據,見 8.26 資料外洩時對商家的通知〈回報、元件缺陷、子處理者通報與外部通知的取證路徑〉。限縮這幾層的影響範圍,做法有五項:
- 查詢頁呼叫營運後台的 API,不直連資料庫:營運後台的查詢限制(每次查詢指定租戶與工單編號、批次匯出要第二個人核准、存取寫進稽核紀錄)由營運後台的伺服器端執行,查詢頁直連資料庫時這些限制全部不生效。工具平台上保存的因此是一把呼叫營運後台 API 的金鑰,查詢的租戶條件由營運後台依發起操作的員工權限套上,不由頁面送來的參數決定。工具平台本身被入侵時,攻擊者拿著這把金鑰仍可以一個租戶接一個租戶查下去,影響範圍仍可能是全部租戶;限縮的是單次查詢的量,而每一次查詢都留在營運後台的稽核紀錄裡,事後查得出哪些租戶被查過。工具平台要把發起操作的員工身分隨每一次呼叫傳給營運後台、寫進稽核紀錄:只記得到工具平台那一把金鑰時,工具平台被入侵之後發出的查詢與員工正常的查詢在紀錄上是同一個身分,攻擊者放慢查詢速度就分不出來。
- 必須直連的頁面,每個連線各用一個只有該頁面所需權限的帳號:一個只更新出貨狀態的頁面用一個只能寫出貨狀態欄位的帳號。這一項限縮的是權限的種類(讀哪些表、寫哪些欄位),限縮不了租戶數:一個跨租戶查訂單的頁面,連線帳號本身就得讀得到所有租戶的訂單表,這種頁面要改走營運後台的 API。
- 能建立或編輯頁面的帳號減到最少:通到正式環境的連線只開放給少數幾個能編輯頁面的帳號使用,其餘員工只拿到使用頁面的權限。
- 連線改用每位員工自己的身分:工具平台支援以使用者自己的登入身分(例如 OAuth)連到下游時,下游系統看到的是那位員工、套用那位員工的權限,工具平台上不保存共用的長期帳號密碼或金鑰。這一項消除的是共用憑證被濫用;工具平台通常仍會保存每位員工授權之後拿到的權杖,工具平台本身被入侵時,攻擊者拿到的是曾經授權的員工權限的總和。縮短權杖的有效期、不保存可以換發新權杖的長期權杖(refresh token),才限縮得到這些權杖外洩時的影響範圍。
- 工具平台本身列進對外服務同一套的漏洞修補流程(7.B11 Vulnerability Response State Machine),不因為只在內網而延後。自架的工具平台由負責維運它的團隊自己排程修補;供應商託管的版本由供應商修補,負責的團隊要追的是供應商的安全公告與它承諾的修補時程。
資料庫管理與備份:DBA 帳號與備份檔讀得到該資料庫內的全部租戶。備份常由一個排程工作把每個 cell 的快照送到同一個儲存位置、用同一把金鑰加密,這時那個儲存位置的存取權與那把金鑰讀得到所有 cell 的資料。平台團隊按 cell 分開 DBA 權限與備份的儲存位置、加密金鑰,存放層的分區才延伸到 DBA 帳號與備份。金鑰分開要搭配權限分開:共用的備份排程只拿得到加密與寫入的權限,解密與還原的權限按 cell 給各自的還原身分,否則備份工作本身仍讀得到所有 cell。DBA 權限分開要有效,各 cell 的權限不能長期放在同一個人的同一個登入底下;DBA 人數少時,比多開帳號有效的做法是平時不持有正式權限,每次操作申請只對一個 cell、限時有效的權限,申請與操作寫進稽核紀錄。
其他碰得到全部租戶的共用元件:日誌與追蹤管線收進各租戶請求裡的個人資料,讀得到集中日誌的帳號就讀得到全部租戶寫進日誌的個人資料;秘密管理服務與金鑰管理服務(KMS)保管每個 cell 的憑證與金鑰,它的管理權限等於進入每個 cell 的權限;平台員工的單一登入(SSO)帳號同時登得進管線、後台與雲端主控台;決定租戶對應到哪個 cell 的路由層與控制平面,被改寫時可以把一個租戶的請求導到別的 cell;在 cell 之前終止 TLS 的負載平衡器、邊緣代理與 WAF 看得到全部租戶的明文請求;跨 cell 共用的會員登入與 session 服務被入侵時,攻擊者可以冒充任何一個租戶的任何一位會員。這幾類的影響範圍都是全部租戶,盤點時與上面各類一起列。
判斷一個共用元件的權限是否限縮到職責所需,用的是以租戶數計的影響範圍:這個元件被入侵時,攻擊者存取得到幾個租戶的資料。平台整體的影響範圍由影響範圍最大的那個元件決定,所以盤點要逐一列出所有共用元件,而不是只看資料庫的分法。攻擊者如何從一台被入侵的機器走到下一台,見 Lateral Movement(橫向移動)。
跨租戶資料整合與隔離的取捨
平台的產品價值常常來自跨租戶的資料:跨品牌的會員串接、全平台的銷售趨勢、拿所有商家的資料訓練推薦或客服模型。這些功能都要求把原本分開的資料匯進同一個儲存位置,下文稱為跨租戶彙整庫(中央資料倉儲、共用的檢索索引、訓練資料集都是)。跨租戶彙整庫是一個新的共用元件,它被入侵時影響範圍是所有被匯進來的租戶,所以設計整合功能時要同時決定兩件事:匯進來的是什麼形態的資料、誰讀得到跨租戶彙整庫。
資料形態本身又由兩個彼此獨立、可以組合的選擇構成:欄位的粒度(彙總值、去識別化明細、完整明細),以及納入哪些租戶(同意加入的、全部)。依保留的隔離程度由多到少排列,常見的組合是:
- 只匯出衍生資料:各 cell 在自己內部算好彙總值(品類銷量、轉換率),只把彙總結果送進跨租戶彙整庫。彙整庫被入侵時外洩的是各租戶的統計數字:沒有個人資料,但各商家的營業數據本身是商家的機密。一個彙總組裡只有一筆訂單時(某品類某天只賣出一件),統計值就等於那一筆的資料,所以每一個彙總組要設最少筆數門檻,低於門檻的組不輸出或併進上一層的彙總。代價是只能做事先定義好的分析。
- 匯出去識別化的明細:個人識別欄位在離開 cell 之前就移除,或用 cell 內保管、不隨資料匯出的金鑰做帶金鑰雜湊(HMAC)改成代碼,這種做法稱為假名化(Pseudonymization)。電話、Email 的可能值有限,不帶金鑰的直接雜湊可以被窮舉回推。能做較彈性的分析,代價是去識別化有兩種常見的不完整:個人資料殘留在自由文字欄位(地址、電話寫在備註裡),以及郵遞區號、生日、下單時間這類欄位彼此組合後仍能認出個人。
- 按租戶授權匯集明細:只有明確同意加入整合的商家資料進跨租戶彙整庫,每一筆帶租戶標記,彙整庫的每一個讀取者依授權範圍查詢。影響範圍等於同意加入的租戶數。涉及會員個人資料的跨商家串接,除了商家同意,還需要對會員本身的法律依據與告知,依據是什麼由法務依適用法規確認。
- 全量匯集:所有租戶的明細都進同一個彙整庫,存放層的分區對它沒有隔離效果,影響範圍是全部租戶。
每一種功能需要的最低資料粒度,決定它最多能保留到哪一種形態:全平台銷售趨勢只需要彙總值,用衍生資料做得成;購買行為分析需要明細而不需要知道是誰,用去識別化明細做得成;跨品牌會員串接要認出同一個人跨商家的紀錄:假名化的金鑰按 cell 分開保管時,同一個人在不同 cell 的代碼不同,串接不了,只剩按租戶授權匯集明細;改由一個獨立的服務保管一把跨 cell 的金鑰做假名化可以串接,而那把金鑰被拿走時,彙整庫裡全部被串接租戶的代碼都能被窮舉回推,所以金鑰與保管它的服務要和彙整庫一起列進影響範圍盤點;讓代碼的運算在金鑰服務內執行、金鑰不離開服務,攻擊者要持續呼叫服務才算得出代碼,可以限流並寫進稽核紀錄。模型訓練與檢索索引能每個 cell 各訓一份、各建一份時,資料不必離開 cell;做不到時只放同意加入的商家,並把模型與索引本身當成共用元件列進影響範圍盤點。全量匯集只適合資料本身不含個人資料與單筆交易的情形。
誰讀得到跨租戶彙整庫,與管線、後台是同一個盤點:彙整庫的每一個讀取帳號都是共用元件,影響範圍是它查得到的租戶數。按功能分開讀取帳號(推薦模型的訓練工作只讀得到它用的那幾個欄位),一個帳號外洩時拿走的是那個功能的資料,而不是整個彙整庫。
LLM 功能是這個取捨最常出現的位置:把多個租戶的資料放進同一個檢索索引、同一份微調資料或同一段提示詞快取,就是全量匯集的一種。推論層的跨租戶外洩路徑(KV cache 與 prefix cache 共用、prompt log、各租戶模型檔的存取權)見 LLM 多租戶推論隔離。
整合的範圍是產品決定,影響範圍要在同一份架構決策紀錄(ADR,記錄一項架構決定、它的理由與代價的文件)裡寫出來:提出跨租戶功能的產品負責人,在該功能的架構決策紀錄裡寫下它讓哪個元件的影響範圍上升、上升到多少租戶。沒有這個欄位時,影響範圍是逐次上升而沒有人看過累計結果的:分析團隊先只匯出品類銷量,之後為了推薦加進去識別化明細,再為了會員串接加回會員代碼,每一次都以功能變更送審,而審查看的是功能、不是彙整庫碰得到幾個租戶。等到彙整庫的讀取帳號外洩,事故報告只能寫全部租戶受影響;事後要把彙整庫縮回衍生資料,就得拆掉已經依賴明細的推薦模型與報表。
選擇隔離層級的判斷標準
隔離層級由下列變數共同決定,每一項的值都來自平台自己的資料與團隊:
- 資料外洩之後的傷害是否可事後彌補:訂單明細(姓名、電話、地址、購買內容)外洩之後被拿去做精準詐騙,傷害無法收回;商品目錄外洩幾乎沒有傷害。含訂單明細的平台,存放層的目標是 cell 分組,讓一次入侵碰不到全部租戶;在分 cell 之前要先具備哪些條件,見本節末的動手次序。
- 一組被入侵時能承擔的影響租戶數:這個租戶數的上限由兩件事決定,取兩者算出的較小租戶數:一組被入侵時,平台在法規或契約訂的通知時限內通知與協助得完的商家數;以及一組外洩時平台要承擔的賠償,這一項要用該組的會員數或訂單筆數估算,再換算成租戶數,因為各租戶的規模差距可以有好幾個數量級。總租戶數除以這個上限,得出最少的組數。少數大客戶佔大部分營收時,大客戶另外走 silo,其餘再分組;契約或監理要求某些租戶獨立存放(專屬資料庫、專屬金鑰、資料落地)時,那些租戶直接走 silo,不參與上限的計算。
- 共用元件中影響範圍最大的那一個:存放層已經分 cell,但管線、共用的應用伺服器、後台或彙整庫的影響範圍仍是全部租戶時,平台的影響範圍由那幾個元件決定。職責不需要讀客戶資料的元件(建置管線、部署工具),拿掉它們的資料讀取權;職責需要跨租戶讀取的元件(營運後台、客服工具),改成每次查詢指定租戶、批次匯出要另一個人核准、存取寫進稽核紀錄。
- 團隊維運每一套環境的能力:cell 數乘以每次升級的工作量是團隊要付的固定成本。部署與 schema 變更還不能逐 cell 自動執行時,cell 數多了會讓版本漂移(各 cell 的程式與 schema 版本不一致)成為新的風險:一個漏洞修補只上到部分 cell,事故處理團隊要先查出每個 cell 跑的是哪一版,才說得出哪幾組租戶暴露在那個漏洞下。
四個變數給出的行動會互相衝突:資料含無法彌補的傷害時,資料傷害那一項要求分 cell,而維運人力少的團隊分了 cell,維運能力那一項警告的版本漂移就會出現。衝突的解法來自影響範圍的計算方式:平台的影響範圍取所有元件裡最大的那一個,所以只有把當下最大的那個元件降下來,總量才會改變。以單一 pool 為例,拿掉管線的資料庫憑證之後,管線仍有部署權、能讓正式環境執行任意程式,影響範圍仍是全部租戶;反過來,分了 cell 而管線手上還有進入每個 cell 的憑證時,多一個 cell 也不改變管線的影響範圍。逐 cell 部署的能力不直接改變影響範圍,它決定的是每多一個 cell 要付出的維運成本與版本漂移風險。
動手的次序建議先限縮共用元件的權限,因為它不改變資料的放法、可以逐個元件做,而且它是分 cell 生效的前提:在單一 pool 裡限縮,影響範圍的租戶數不會下降,換到的是攻擊者能做的事從直接讀資料庫縮成推送產物、從整庫匯出縮成一次查詢一個租戶;分 cell 之後,已經限縮過的元件才不會把分區抵銷。接著把部署與 schema 變更改成能逐 cell 自動執行,因為不能自動執行時,每多一個 cell 就多一個可能與其他 cell 版本不一致的環境;最後才增加 cell 數。維運人力只夠管一套環境、而部署與 schema 變更已經能逐 cell 執行時,cell 數的起點是兩組:第二組的工作量是重跑同一份部署,加上把一半租戶的資料遷過去與租戶到 cell 的路由。兩組各放一半租戶時,資料庫憑證外洩的影響範圍從全部租戶降到大約一半;應用伺服器、DBA 帳號與備份仍跨兩組共用時,那些元件的影響範圍不變,要照〈存取層的隔離〉逐一限縮。
事故報告應交代的隔離資訊
隔離設計在事故發生時會被商家檢驗。一份事故報告寫「系統之其中一座訂單資料庫遭存取」時,受影響的商家讀完仍不知道三件事:那座資料庫放了幾個租戶、被入侵的元件手上的憑證還讀得到哪些資料庫、以及這次影響的是一組租戶還是全部。這三件事都由同一個量推得出來:被入侵的元件存取得到幾個租戶的資料。
報告要交代的是各道隔離控制在這次事故裡的表現:入口元件(攻擊者最先入侵、再由此往內擴散的元件)是什麼、它的權限碰得到哪些資料分區、哪一道隔離擋住了擴散(「其他 cell 的資料庫憑證不在該主機上」)、哪一道沒有擋住。商家據此判斷自己是否受影響、要不要通知自己的會員;平台交代不出來時,商家只能假設自己受影響。入口元件的權限範圍與各道隔離的表現,在根除進度的哪一個階段才能對外宣告,見 8.25 建置主機被入侵後的根除與重建〈對外宣告已掌握狀況的條件〉;已確認事實與未確認範圍分開寫的更新欄位見 8.4 事故通訊與狀態更新〈更新欄位與節奏〉,影響估算的信心標示見 8.20 Customer Impact Assessment〈通訊與補償〉。這些隔離資訊在對商家的確認通知與事後的調查報告裡各交代一次;外洩來源還沒判定是否在平台這一側時先發給商家的風險預警、確認之後的通知、排除平台之後的結案通知與調查報告,見 8.26 資料外洩時對商家的通知。
常見風險邊界:跨 cell 的長期憑證與共用運算、共用帳號、未收回的除錯用存取憑證、管線持有的簽章金鑰、未記錄的整合功能、只寫資料庫的事故報告
- 存放層分 cell,而建置管線、共用的應用伺服器或營運後台持有進入所有 cell 的憑證:影響範圍仍是全部租戶。
- 每租戶一個 schema,而應用程式用同一個高權限帳號連線:資料看起來分開,憑證外洩時全部可讀。
- 為了除錯方便在管線、跳板機或開發者筆電放正式環境的資料庫憑證,事後沒有收回:這類憑證不在任何盤點清單上。
- 管線自己持有簽章金鑰,而各 cell 只驗簽章:管線被入侵時惡意產物照樣通過驗證。
- 新增跨租戶的分析或 AI 功能時沒有記錄它讓哪個元件的影響範圍上升:每次迭代都讓某個元件的影響租戶數上升,而沒有人做過這個決定。
- 事故報告只寫受影響的資料庫,不寫入口元件的權限範圍:商家無法判斷自己的風險。
延伸閱讀:事後清查、短期憑證、產物驗證、跨網路連線與 cell 的故障局部化
- 隔離層級定了之後,入口元件被入侵時的清查與重建:8.25 建置主機被入侵後的根除與重建
- 管線與工作負載的存取憑證改成短期、按目標分開:7.6 秘密管理與機器憑證治理、7.10 Workload Identity 與聯邦信任邊界
- 管線推送的產物如何被各環境驗證:7.12 供應鏈完整性與 Artifact 信任
- 兩個網路接起來之後各自連得到什麼、被入侵端改不到的限制放在哪裡:7.43 兩個網路之間的連線安全
- 分組結構在可用性上的作用(一個租戶引發的故障同時讓另一個租戶失效的機率),與本章的機密性度量不同:Amazon:Shuffle Sharding 與 Cell 邊界的失效局部化