系統設計面試:設計一個多租戶授權策略服務
題幹與適用場景
一個 B2B 平台有多個業務服務,每個團隊都在重複實作「使用者能否存取資源」的判斷。現在需要統一的多租戶授權策略服務,支援角色、資源關係和屬性條件,策略更新後要能追蹤版本,且不能因中心服務短暫故障就讓租戶越權。
題目重點是授權決策鏈路與一致性邊界。不要只畫一個策略資料庫;要說明呼叫方如何帶上下文、策略如何發布、快取何時失效,以及拒絕或逾時如何影響請求。
面試官考察什麼
面試官會看你能否區分策略決策點(PDP)與業務服務中的執行點(PEP),能否設計租戶隔離、版本傳播和可解釋稽核。OPA 文件強調把決策從執行程式碼中解耦;Zanzibar 論文則展示了在大規模授權檢查中維護因果順序與低延遲的取捨。
回答前要釐清的問題
先問請求量、延遲目標、策略複雜度、租戶數量、資源關係深度和一致性要求。還要問策略作者、審批流程、撤權生效時限、是否允許離線評估、決策日誌的敏感欄位,以及業務服務能否安全地 fail closed。
30 秒回答框架
我會先定義授權模型和「不允許越權」的不變量,再畫 PEP、PDP、策略儲存、分發和稽核鏈路。策略按租戶版本化發布,PDP 在本地或同區域快取已批准版本;請求帶主體、動作、資源和必要上下文。撤權等高風險變更要求版本確認,PDP 不可用時預設拒絕敏感操作。最後用 p99 延遲、策略傳播延遲、拒絕誤報和稽核完整性驗證系統。
分步驟深入分析
第一步:定義授權物件和策略輸入
統一請求形狀為 subject、action、resource、context,並為資源和租戶使用不歧義的命名空間。RBAC 解決角色授予,ABAC 處理部門、裝置、時間等屬性,關係型授權處理「使用者是文件協作者」。策略語言應能表達 allow、deny、優先級和條件,避免業務服務各自拼接規則。
第二步:劃分 PEP、PDP 和策略管理面
PEP 留在 API 閘道或業務服務,負責收集可信身分和執行 allow/deny;PDP 只負責評估並回傳決定、策略版本和可選原因;管理面負責編輯、校驗、審批、發布和回滾。OPA 將策略決策與策略執行解耦,並支援本地或網路部署;選擇部署方式要結合延遲和可用性。
第三步:設計多租戶儲存與版本發布
策略、資源關係和屬性資料都帶 tenant_id,並在讀取路徑強制校驗租戶。發布生成不可變版本和校驗摘要,先在沙箱評估,再分批分發到 PDP。發布記錄作者、審批者、時間和影響範圍;撤權或安全策略可以提高優先級,要求舊版本在短時間內失效。
第四步:處理一致性、快取與撤權
快取鍵至少包含 tenant、subject、action、resource 和 policy_version,不能只按使用者 ID。允許快取低風險 allow,但對撤權、管理員變更和敏感資源設定短 TTL 或強制版本檢查。PDP 回傳決策使用的版本,業務服務可以拒絕過舊版本。跨區域部署要傳播版本水位,而不是假設快取同時更新。
第五步:設計故障模式和安全預設值
PDP 逾時、策略分發延遲、屬性來源不可用和日誌管道擁塞都要有明確行為。敏感寫操作、權限變更和資料匯出預設 fail closed;低風險唯讀可在帶期限的已批准快取上繼續。絕不讓呼叫方把「網路錯誤」當成 allow。限制策略大小、遞迴關係深度和單租戶 QPS,避免策略成為拒絕服務入口。
第六步:稽核、可解釋性與觀測
每次決定記錄 decision_id、租戶、主體摘要、動作、資源摘要、結果、策略版本和延遲;敏感輸入脫敏或雜湊。日誌應能回答「誰在何時依據哪個版本被允許」,同時不能成為新的資料洩露面。監控 p50/p95/p99、快取命中、版本傳播延遲、deny 比例、逾時和重試;對異常 deny 或策略回滾觸發告警。
高品質示範回答
我會把授權服務拆成業務服務內的 PEP、同區域 PDP 叢集和獨立管理面。請求攜帶主體、動作、資源與可信上下文;PDP 根據租戶隔離的 RBAC、關係和屬性策略回傳 allow/deny、decisionid 和 policyversion。策略編輯先校驗和測試,再生成不可變版本,按租戶和區域分發,支援回滾。
快取鍵包含租戶、主體、動作、資源和版本。普通讀取可使用短 TTL 的 allow,撤權、權限變更和資料匯出要求版本確認;若 PDP 回傳的版本落後於業務服務要求,呼叫方拒絕請求。PDP 逾時或屬性來源不可用時,敏感操作 fail closed,不能把錯誤當成允許。
每個決定記錄租戶、主體摘要、動作、資源摘要、結果、版本和延遲,並對輸入脫敏。核心指標是 p99 延遲、快取命中率、策略傳播延遲、過期版本拒絕數、錯誤率和稽核完整性。這樣既把策略從業務程式碼中集中管理,也保留了執行點的安全邊界。
常見錯誤與改進
- 只有一個「權限微服務」:補出 PEP、PDP、管理面和分發鏈路。
- 只說 RBAC:說明屬性和資源關係如何進入策略。
- 快取只按使用者:加入租戶、資源、動作和策略版本。
- 逾時直接放行:敏感操作應 fail closed,並區分低風險快取。
- 日誌記錄完整請求:脫敏輸入,保留可追蹤的 decision_id 和版本。
追問及應對
How quickly must a revocation take effect?
Classify revocations by risk. For administrator, export, and sensitive-data actions, require a fresh policy version or a short bounded propagation window; lower-risk reads can use a measured TTL. State the target and monitor it.
Should PDP run locally or as a shared service?
Use local or same-zone PDP for latency and failure isolation, with a shared management plane for policy distribution. A central network PDP can simplify updates but adds a dependency to every request; choose per workload and test the failure mode.
How do you prevent one tenant from reading another tenant’s policy?
Put tenant identity in the authenticated request, enforce it in storage and cache keys, and test cross-tenant queries as a release gate. Never trust a tenant identifier supplied only by the caller payload.
How do you debug an unexpected deny?
Return a decision_id and policy version, then inspect redacted inputs, matching rules, attribute freshness, and propagation state. Do not expose sensitive policy internals to end users; give operators a controlled explanation view.