具代表性的面試主題

系統設計面試:如何設計多租戶 Secrets Rotation Service?

系統設計困難
OfferCC 編輯團隊發佈 更新

題幹

請設計一個為多租戶應用自動輪換資料庫密碼和 API 金鑰的服務,並說明如何保證冪等、可恢復和不中斷發布。

題目

設計一個多租戶 Secrets Rotation Service。租戶可以設定資料庫密碼、第三方 API 金鑰或憑證的輪換週期;服務負責產生新值、更新外部系統、寫入版本庫、逐步通知工作負載並停用舊值。請說明故障恢復、並發控制、稽核、權限和回滾方案。

面試官考察點

  • 能否把輪換拆成可重試的狀態機,而不是無法恢復的排程腳本。
  • 能否處理同一 secret 的並發任務、重複訊息和租戶之間的隔離。
  • 能否設計雙版本或灰度發布,避免新值立即造成全量故障。
  • 能否說明舊值清理、洩露應變、稽核證據與最小權限。

參考答案

核心物件包括 Secret、不可變 Version、RotationPolicy、Job 和 Lease。排程器按下一次輪換時間投遞任務;工作佇列按 secret_id 分區,消費者用帶過期時間的租約取得所有權。資料庫唯一約束 (secret_id, idempotency_key),讓重試不會生成兩次外部變更。

輪換狀態可採用 scheduled → generating → external_updated → staged → rolling_out → verified → retired,每個狀態保存外部請求識別、版本號和下次重試時間。先在外部系統建立新憑證,再寫入新版本並標記為 pending;工作負載透過版本引用或動態刷新逐步切換。健康檢查、錯誤率和授權測試通過後,才把新版本提升為 current。

控制面保存元資料,秘密值放在專用加密儲存中,應用只取得短時讀取權限。每次狀態變化寫入不可篡改稽核日誌;日誌中不出現秘密明文。回滾只切回仍有效的舊版本,不能把「撤銷舊憑證」當成回滾後的預設動作。

架構草圖

text
Scheduler -> Durable Queue -> Rotation Workers
     |              |              |
 Policy DB     Lease/Idempotency  External Provider
     |                             |
 Version Store + KMS        Rollout Controller -> Workloads
     |
 Audit Log / Metrics / Alerts

每個 worker 以租約續期,租約失效後其他 worker 才能接管。佇列訊息只攜帶 secret 識別和 job 識別;worker 從權限受限的版本儲存讀取值,避免把秘密放進訊息、日誌或指標標籤。

關鍵流程

  1. 排程器建立帶冪等鍵的 job,按租戶配額排隊。
  2. worker 取得租約,讀取目前版本和輪換策略;若 job 已完成則直接返回。
  3. 產生新值並呼叫外部 provider,使用 provider 的冪等請求號。
  4. 寫入 pending 版本,執行相容性檢查和小批量 rollout。
  5. 觀察錯誤率、認證成功率和健康探針;達到閾值後提升 current。
  6. 等待所有消費者確認,再停用並銷毀舊版本;失敗則重試或回滾。

每一步都持久化狀態和外部回應。重啟時從最後狀態繼續,而不是重新猜測外部系統是否已經更新。

常見誤區

  • 只在 cron 中保存下次時間,程序重啟或重複觸發後無法恢復。
  • 輪換完成就立即撤銷舊值,忽略連線池、快取和長連線的過渡時間。
  • 把秘密值放入佇列、日誌、追蹤 span 或錯誤訊息。
  • 用全域鎖阻塞所有租戶,或者沒有租戶配額導致單一租戶耗盡 worker。
  • 把回滾理解為再次寫入舊值,卻不驗證舊憑證仍未過期或未被撤銷。

一致性與安全取捨

控制面可以使用強一致資料庫保存狀態機和唯一約束;通知與 rollout 使用至少一次投遞,因此消費者必須冪等。版本讀取可短暫快取,但 current 版本變更和撤銷事件必須有明確失效路徑。租戶權限應限制在自己的 secret、job 和稽核記錄,worker 只取得完成當前步驟所需的 provider 權限。

輪換週期不能只按固定時間決定,還要考慮金鑰類型、暴露風險、外部 provider 限制和恢復窗口。NIST 的金鑰管理建議強調使用期限與用途、保護等級和撤銷流程應共同決定策略。

用故障注入驗證:worker 在每個狀態前後崩潰、訊息重複、租約過期、provider 超時、部分實例 rollout 失敗、資料庫主從切換。斷言同一 job 不會產生重複外部憑證,最終只有一個 current 版本,舊值在確認窗口結束後才撤銷。再檢查租戶越權、稽核脫敏和告警延遲。

  • AWS Secrets Manager 的 AWSPENDING/AWSCURRENT 輪換流程:版本標籤和完成步驟。
  • Google Cloud Secret Manager 輪換建議:重試、不可並發輪換、漸進 rollout 與舊版本清理。
  • NIST SP 800-57 Part 1:金鑰用途、保護、使用期限和撤銷的管理原則。

追問

如何防止兩個 worker 同時輪換同一個 secret?

用資料庫租約或帶 fencing token 的分散式鎖,並把 token 寫入每次狀態更新。沒有目前 token 的 worker 即使恢復,也不能覆蓋新狀態;租約需要續期和明確過期時間。

provider 不支援冪等介面怎麼辦?

先在本地 job 持久化請求指紋和外部資源識別,重試前查詢 provider 的目前狀態。若無法查詢,就把該步驟標為需要人工確認,避免盲目建立多個憑證。

為什麼不能只讓應用讀取 latest?

latest 可能把未驗證的新值立即推給全部實例。使用不可變版本、分批 rollout 和健康檢查,可以把錯誤值的影響限制在小範圍並保留回滾點。

輪換任務積壓時如何保護系統?

按租戶和 provider 設定並發配額,使用優先級和退避重試,並暴露最老任務年齡、失敗率和剩餘恢復窗口。接近過期的 secret 可以提升優先級,但不能繞過權限和冪等檢查。

洩露事件發生時,輪換服務要做什麼?

立即凍結相關 job 的普通排程,建立高優先級緊急輪換,縮短 rollout 觀察窗口並保留取證日誌。撤銷舊值前確認所有關鍵消費者已切換,同時通知租戶和安全應變流程。

公開來源

同類題目

資源

產品比較

每份比較均依官方資料整理,並標示複核日期。

查看完整比較

相關面試工具

用 Solve 整理系統設計回答

從澄清需求開始,展開規模、架構、元件選擇和取捨。

查看工具