題幹與適用情境
多個業務服務都要判斷「誰能對哪個資源做什麼」。題目要求你設計共享決策服務,輸入主體、動作、資源與情境,輸出 ALLOW 或 DENY,同時支援使用者與服務帳號、階層資源、租戶邊界和策略變更。
本文採用可計算的面試假設:初始規模為每秒 100,000 次授權檢查,峰值為平均值 3 倍;99 百分位延遲目標為 20 毫秒;策略寫入遠少於讀取;呼叫方必須能區分「明確拒絕」與「授權服務暫時不可用」。這些數字是題目假設,不是業界基準。扣款、發行密鑰與業務資料庫寫入不在服務職責內。
面試官考察重點
強回答會把權限問題拆成四元組與一致性契約,不會只說「放一個 RBAC 服務」:
- 主體、資源、動作、情境的建模邊界,以及階層資源和跨租戶引用如何表達;
- ACL、RBAC、ABAC 或關係型策略的適用條件,如何避免規則散落在每個業務服務;
- 決策讀取路徑、策略寫入路徑、快取與失效通知如何組合;
- 授權變更在什麼時間內對讀取可見,舊快取是否可能放行;
- 拒絕、逾時、依賴不可用時的 fail-open 或 fail-closed 選擇;
- 日誌、解釋資訊、回放與故障注入如何證明「拒絕正確且沒有跨租戶洩漏」。
回答前需要釐清的問題
先問會改變架構的限制:
- 一致性窗口是多少? 如果撤銷權限後必須在 5 秒內生效,快取租約與版本權杖都要圍繞 5 秒設計;若允許分鐘級延遲,可使用較長 TTL。
- 決策是單一資源還是關係查詢? 「使用者能否讀取文件」可能依賴成員關係、群組繼承與父資源;這決定是否需要關係圖或批次檢查。
- 拒絕服務時允許什麼? 公開內容可選擇 fail-open,付款與個人資料通常必須 fail-closed;答案要按風險而非習慣選擇。
- 策略由誰寫、如何審核? 若業務團隊可直接發布規則,需要版本、審批、靜態檢查和回滾;若只有安全團隊寫入,可縮小控制面。
- 是否需要可解釋結果? 除錯可能需要命中的規則 ID,但回傳給客戶端的解釋不能洩漏其他租戶的資源或策略。
30 秒回答框架
可以先這樣回答:
「我會把請求建模為 (principal, action, resource, context),由策略引擎回傳允許、拒絕、策略版本與可選的內部規則 ID。控制面管理租戶隔離的策略與關係資料,資料面用版本化快照和本地唯讀快取完成低延遲檢查;策略發布產生失效事件,呼叫方攜帶決策版本避免舊快取覆蓋新授權。安全敏感路徑在服務不可用時拒絕,低風險讀取按明確業務策略降級。最後用撤銷傳播、跨租戶、快取競態與依賴故障注入驗證一致性和稽核完整性。」
先給模型、資料流、一致性和失敗路徑,再由面試官選一個方向深入。
分步深入解答
先定策略語意。 主體可以是使用者、服務帳號或群組;資源可以是租戶、專案、文件等階層物件;動作應是有限集合,如 read、write、share。情境包含裝置狀態、請求來源或時間窗口,但不能把未驗證的客戶端欄位當成信任事實。ABAC 指引把主體、物件和環境屬性作為決策輸入;關係型策略則把「成員關係」直接表達成可遍歷的邊。
分離控制面與資料面。 控制面負責策略編輯、驗證、審批、版本和回滾;資料面只載入已發布的不可變快照並回答檢查。業務服務不應各自複製一套策略解析器。策略發布後產生單調遞增版本號和失效事件,資料面按版本原子替換快照,避免半套規則可見。
設計檢查介面。 一個內部介面可以是:
Check(principal, action, resource, context, min_policy_version)
-> decision, policy_version, rule_id, expires_at
BatchCheck(principal, [(action, resource, context)...])
-> decisions[]rule_id 只用於受控日誌與除錯;跨租戶請求不能透過錯誤訊息探測資源存在。批次介面減少網路往返,但必須限制批次大小和單次評估成本。
處理一致性與快取。 本地快取可滿足 20 毫秒目標,但撤銷權限後不能只依賴 TTL。呼叫方可攜帶上次觀察到的策略版本;服務發現本地版本不足時從共享儲存讀取,或回傳「暫時無法判定」。失效事件要有可重播游標與定期對帳,避免通知遺失。對極敏感資源,可在決策加入資源版本或短租約,使「權限版本」和「物件版本」一起被檢查。
選擇故障行為。 資料面無法連線控制面時,已載入且未過期的快照可以繼續服務;快照過期後,付款、個人資料與管理動作應 fail-closed,公開靜態內容才可能按產品策略 fail-open。逾時必須是明確的 UNAVAILABLE,不能偽裝成 DENY,否則業務會把基礎設施故障誤認為使用者沒有權限。
隔離租戶與防止濫用。 每個策略物件與快取鍵都帶租戶 ID;伺服器從已驗證身份取得租戶,不接受請求本文的任意租戶欄位。對單一主體、單一租戶與批次請求設定配額,限制遞迴關係深度和策略複雜度,防止一個租戶耗盡評估資源。
稽核與驗證。 記錄請求雜湊、主體、動作、資源類型、決策、策略版本、延遲和失敗原因;敏感值只保留不可逆識別碼。測試應涵蓋撤銷後舊快取、群組繼承循環、跨租戶資源 ID、策略發布中途崩潰、失效事件重複或遺失、資料面重啟和依賴逾時。驗收不只是「回傳 DENY」,還要能重播同一策略版本並解釋原因。
估算瓶頸。 每秒平均 100,000 次、峰值 300,000 次檢查時,若每次請求平均 2 KB,入口流量約為峰值 600 MB/秒。把完整策略放入每次網路請求會放大延遲和頻寬,因此優先使用本地快照、批次檢查和唯讀副本;當關係圖遍歷成為瓶頸,再按租戶或資源分片,並限制深度和 fan-out。估算是設計假設,面試中應說明如何用壓測替換它。
高品質示範回答
「我會先確認撤銷傳播目標與故障時的安全邊界。假設系統峰值每秒 300,000 次檢查、99 百分位 20 毫秒,並要求撤銷在 5 秒內生效,我會分離控制面與資料面。控制面保存帶租戶邊界的 ACL、群組關係與 ABAC 條件,發布前做語法、循環和跨租戶檢查,產生不可變策略快照與單調版本。資料面在每個區域載入快照,先用本地唯讀快取評估 (主體、動作、資源、情境),策略失效事件帶游標且可重播;呼叫方可傳入 minpolicyversion,本地版本落後就讀取共享副本,不能滿足時回傳 UNAVAILABLE。
對付款、個人資料與管理動作,快照過期或依賴不可用時我會拒絕;公開內容是否降級由產品明確批准。每次結果攜帶策略版本與內部規則 ID,日誌記錄決策、延遲和錯誤類別,但不回顯其他租戶資訊。資源版本或短租約用於最敏感物件,避免權限已撤銷而物件仍被舊決策放行。壓測會涵蓋峰值流量與最深關係遍歷,故障注入會涵蓋失效事件遺失、撤銷競態、跨租戶 ID 和區域重啟;透過對帳和按版本回放證明沒有無法解釋的允許結果。」
這份回答把假設、模型、一致性、失敗處理和驗證連在一起。面試時應依追問刪減細節,不要把每秒 300,000 次或 5 秒當成通用生產結論。
常見錯誤
- 把所有問題都歸為 RBAC。 角色不能自然表達資源階層、關係繼承與環境條件;先說明權限語意,再選模型。
- 用固定 TTL 解決撤銷。 TTL 只能限制最壞陳舊時間,通知遺失和版本競態仍存在;補上版本、失效重播與對帳。
- 故障時一律放行或一律拒絕。 不同資源風險不同;按安全底線、快照新鮮度與業務可逆性定義策略。
- 把策略複製到每個服務。 多套解析器會產生漂移和不同拒絕語意;把策略版本化,讓服務呼叫統一決策介面。
- 回傳「資源不存在」或詳細規則。 這會洩漏跨租戶資訊;對外採用穩定錯誤碼,對內受控日誌記錄規則 ID。
- 只測正常允許路徑。 權限系統最容易在撤銷、重播、循環和跨租戶邊界出錯;必須用故障注入和版本回放驗證。
追問與應對
如果業務要求撤銷後立即生效,仍能使用本地快取嗎?
可以,但快取不能單獨決定結果。讓撤銷產生全域可觀察的版本或租約失效訊號;敏感請求攜帶最小策略版本,版本落後時繞過本地快取或等待確認。若無法在預算內確認,就回傳 UNAVAILABLE 或拒絕,不能靜默使用舊允許結果。
如果一個資源屬於多個父群組,關係遍歷出現循環怎麼辦?
策略發布階段拒絕循環,執行時仍設定最大深度、節點數和時間預算。評估器維護造訪集合,重複節點直接停止該分支並回傳可診斷的內部錯誤;不要讓循環把一次檢查變成無限工作。
如何證明不會發生跨租戶越權?
把租戶作為不可省略的策略命名空間與快取鍵前綴,主體租戶由伺服器身份推導。用屬性測試生成不同租戶的相同資源 ID,驗證任何允許結果都滿足主體、資源和策略租戶一致;再做日誌抽樣和拒絕路徑回放。
Zanzibar 的外部一致性是否必須照搬?
不必。先依撤銷延遲和業務風險選擇版本權杖、租約或更強一致性。若產品要求「使用者剛移除的成員關係不能繼續讀取舊物件」,因果順序和物件版本就值得採用;若是低風險公開內容,較弱一致性和較長快取可能更簡單。關鍵是明確承諾與代價。