SWE · Phone System Design

Snowflake ACL Check Service:判权契约、策略版本与缓存失效

Phone SD 只公开“为另一个服务做 ACL 检查”;本文把对象、主体、动作和默认拒绝写成训练契约,推演缓存与撤权一致性。

题目重点:Phone SD 只公开“为另一个服务做 ACL 检查”;本文把对象、主体、动作和默认拒绝写成训练契约,推演缓存与撤权一致性。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练版主体为用户或服务账号,资源为 tenant/project/object 三级,动作 read/write/admin;调用方经服务身份认证并传稳定 subject、resource、action、tenant。
  • 策略采用允许条目与显式拒绝条目,拒绝优先;没有匹配规则默认拒绝。上层资源授权是否继承下层需在产品契约中明确,训练版允许 project→object 继承。
  • 训练规模假设 1 亿资源、每秒 5 万次判权、p99 小于 20ms;撤权须在 5 秒内生效。这些数字不是面经原题。

解题路线

  1. Check API 返回 allow/deny、policyVersion、decisionId 和短解释码;先验证调用服务身份、tenant 绑定与参数,再收集主体直接授权和群组继承。
  2. 权限写路径把对象策略、群组成员关系和版本一起持久化,通过变更流广播版本;写成功应定义何时对所有判权节点可见。
  3. 读路径先用 (tenant,subject,resource,action,subjectVersion,resourceVersion) 查本地短 TTL 缓存;命中版本不匹配就重算,拒绝结果也可短时缓存。
  4. 撤权强要求下,可让高风险 write/admin 请求检查权威版本或使用同步失效屏障;单纯 5 秒 TTL 无法保证更短撤权窗口。
  5. 跨租户校验必须发生在缓存前;判权服务故障时对敏感动作 fail closed,同时让调用方观察明确错误,不把错误误记为合法 deny。
  6. 日志记录 decisionId、版本、主体/资源/动作与规则来源,但敏感字段脱敏;用 shadow evaluation 比对策略迁移前后的决定。

手动走一遍

用户 U 属于组 G,G 对项目 P 有 read,故 U 对 P/object1 的 read 被允许;管理员撤销 G 的授权并把 P 的 policyVersion 从 7 升到 8。旧缓存键含版本 7,收到版本 8 后不能复用;在广播延迟期间,若读业务要求立即撤权,应走权威版本检查。

规模与取舍

设主体有效群组数 g、资源祖先层数 h、相关规则数 r,未命中判权约 O(g+h+r) 索引读取/规则检查;缓存命中近 O(1)。内存随热点决策键数增长;每秒 5 万次与 p99 20ms 是训练容量假设,需要压测验证。

易错点与追问

容易失分的边界

  • 以资源 ID 为唯一缓存键,漏掉主体、动作、租户和策略版本。
  • 把 ACL 不存在当允许或在鉴权服务故障时无条件放行。
  • 声称有缓存 TTL 就满足任意严格撤权时效。
  • 群组成员变化只更新资源版本,旧成员缓存仍可能命中。
  • 把调用方自报 tenant 当可信身份,不验证服务令牌和资源所属租户。

继续深挖

  • deny override 与允许继承冲突时,怎样给用户解释决策?
  • 批量 Check API 如何合并群组与策略查询?
  • 跨区域撤权传播延迟超过 SLA 怎么降级?
  • 若引入 ABAC 条件,如时间/IP/标签,缓存键与规则评估怎样变?
✓已复制微信号!