07-权限中心的工程落地-架构缓存一致性与高可用
权限中心的工程落地:架构、缓存、一致性与高可用
权限模型正确不代表系统能够在生产环境稳定运行。微服务每个请求都远程调用权限中心会增加延迟和单点依赖;把全部权限放进 JWT 又会导致撤销延迟、Token 膨胀和动态策略失真。
工程落地需要在一致性、性能、可用性和可解释性之间做明确取舍。
1. 权限中心与业务系统的边界
权限中心负责:权限目录、角色、授权关系、策略、版本、决策接口和授权审计。
业务系统负责:资源状态、金额、客户归属、领域状态机、数据查询和最终事务。权限中心不复制完整业务数据库,也不能成为所有业务规则的脚本平台。
身份系统负责认证和凭证,组织系统负责员工与部门事实源。权限中心保存引用、必要快照和版本。
2. PAP、PDP、PEP、PIP 的部署
PAP 通常位于控制面,用于管理角色、策略和发布版本;PDP 可以是中央服务、Sidecar 或进程内库;PEP 分布在网关、Controller、Service、Repository 和消息消费者;PIP 从组织、业务、设备和风险服务获取属性。
决策接口应稳定统一:
{
"actor": "U1006",
"principal": "U1006",
"subject": "U1001",
"tenant": "T1001",
"resource": {"type": "ORDER", "id": "O1001"},
"action": "sales:order:read",
"context": {"impersonationSession": "IMP-1001"}
}
返回:
{
"decision": "ALLOW",
"reasonCode": "ALLOW_ROLE_PERMISSION",
"effectiveScope": {"type": "SELF"},
"obligations": [],
"permissionVersion": 42,
"policyVersion": 12
}
3. 三种运行模式
远程实时决策
优点是策略集中、撤销快、解释统一;缺点是每次调用增加网络延迟和中央依赖。适合高风险、低频、动态属性多的操作。
本地快照决策
控制面下发角色、ACL、策略或编译快照,业务服务本地判断。性能和可用性好,但需要版本、签名、失效和差异检测。
混合模式
常见选择:静态功能权限和低风险读本地判断;付款审批、跨租户管理和临时提权远程判断;数据权限在业务服务的 Repository/数据库执行。
4. 批量决策
菜单渲染和列表操作不应对每个按钮或每个资源发一次远程请求。权限中心应支持:
- 多 Action Check;
- 多资源 Check;
- List Objects;
- List Users;
- 数据过滤条件或授权索引。
批量接口必须限制请求规模、超时和结果版本,避免成为新的性能和数据枚举入口。
5. 缓存分层
可分别缓存:
- 角色权限集合;
- 角色继承闭包;
- 主体有效 Role Assignment;
- 用户组和组织成员;
- ACL 局部结果;
- 策略编译结果;
- 稳定属性;
- 最终决策。
最终决策缓存最危险,因为结果可能受金额、时间、设备和资源状态影响。不能只使用 userId + permissionCode。
缓存键或缓存条目至少应关联 tenant、subject、application、resource、action、context 摘要、permissionVersion 和 policyVersion。
6. 版本体系
需要区分:
- permission_version:权限项元数据;
- role_version:角色权限、层级和约束;
- assignment_version:授权关系;
- principal_permission_version:主体有效权限汇总;
- policy_version:策略内容;
- tenant_change_sequence:租户内变更序号;
- snapshot_version:下发快照。
不要把所有变化压成一个难以解释的 version。高风险请求应验证主体权限版本达到控制面要求的最低线。
7. 变更传播
基本流程:事务内更新授权状态和 Outbox 事件;消息系统发布变更;业务节点按版本幂等处理;失效缓存并按需拉取新快照。
需要处理:
- 消息丢失:版本轮询或补偿拉取;
- 消息重复:按事件 ID 和版本幂等;
- 消息乱序:忽略旧版本;
- 节点离线:恢复后比较租户序号;
- 快照回滚:拒绝低于最低安全版本的快照。
权限撤销通常比授予更敏感。可对高风险撤销维护快速黑名单或在线版本检查,缩短缓存窗口。
8. Token 中放不放权限
完整权限放入 Token
优势:本地判断、低延迟。问题:角色多时 Token 很大,资源 Scope 和 ABAC 难表达,权限撤销只能等 Token 过期或维护额外状态。
Token 只放身份
权限实时,但每次都依赖权限查询。
推荐混合
Token 放稳定身份、tenant、会话、认证强度和 permission_version;业务服务使用本地缓存或权限中心加载有效权限。短期、低风险的粗粒度 Scope 可以进入 Token,但不能把 Token 当作唯一授权事实源。
9. 服务身份和用户身份传播
order-service 调用 finance-service 时至少有两层身份:调用服务是谁,以及它代表哪个用户。下游不能只信任一个可伪造的 X-User-Id。
可使用:
- mTLS/Workload Identity 验证服务;
- 签名 Token 验证用户;
- Token Exchange 或 On-Behalf-Of 令牌;
- 明确 audience、scope、actor 和 subject;
- 下游同时检查服务调用权限和用户业务权限。
服务自身没有 finance:payment:approve 时,即使代表财务主管,也不能调用审批工具;反之,服务有能力也不能绕过用户权限。
10. 非人主体凭证
API Key、Client Secret、证书和私钥必须与 Principal 分开管理,存入专门密钥系统。建议使用短期工作负载身份,避免长期静态密钥。
每个凭证需要:状态、颁发时间、到期、最后使用、轮换策略和吊销。删除凭证不等于删除主体,撤销权限也不等于轮换密钥,两种生命周期要分别处理。
11. 多租户工程隔离
隔离维度包括:
- 数据库查询;
- Redis Key 和本地缓存;
- 搜索索引;
- 消息 Topic/事件字段;
- 对象存储路径与签名 URL;
- 决策日志和指标;
- 权限快照;
- 管理入口和平台管理员上下文。
必须在每层做显式检查,不能指望最外层网关传入的 tenant 永远正确。
12. 高可用与降级
权限中心超时时默认拒绝,但可以按风险使用有效本地快照:
- 高风险审批、角色分配、模拟用户:无法验证最新版本时拒绝。
- 低风险读取:快照签名有效、未过期且版本高于最低线时可继续。
- 审计服务异常:高风险强制审计操作拒绝;低风险操作仅在可靠本地缓冲可用时继续。
- 属性服务异常:必需属性缺失拒绝,可选属性使用安全默认值。
降级策略要按 Action 配置和测试,不能在故障时临时决定“先放行”。
13. 可观测性
建议指标:
- PDP P50/P95/P99 延迟;
- Allow/Deny/Indeterminate 比例;
- Deny 原因分布;
- 各层缓存命中率;
- PIP 调用失败和延迟;
- 权限变更传播延迟;
- 节点策略版本分布;
- 快照过期和降级次数;
- 高风险权限使用量;
- 通配符和跨租户特权调用。
日志必须包含 traceId、requestId、Actor、Subject、resource、action、reasonCode 和版本,避免只记录“403”。
14. 灰度迁移
旧权限系统迁移到新 PDP 时,可以使用双轨决策:旧系统负责真实结果,新系统 Shadow 计算并记录差异。先覆盖低风险读,再迁移写和高风险操作。
差异要按原因分类:模型数据缺失、Scope 不一致、策略语义不同或旧系统本身存在越权。不能为了追求结果一致,把旧漏洞复制到新系统。
15. 开源方案定位
- Spring Security:Java 应用内认证与授权基础,适合 HTTP、方法权限和扩展 AuthorizationManager。
- Casbin:多语言访问控制库,模型与策略可配置,适合应用内执行。
- OPA:通用策略引擎,使用 Rego,适合策略即代码和多基础设施场景。
- OpenFGA:Zanzibar 风格关系授权,适合 ReBAC、Check/List Objects。
- Cedar:面向授权的策略语言,强调 principal/action/resource/context 和策略验证。
- Keycloak Authorization Services:在身份平台上提供资源、Scope、策略和集中 PDP。
选型前要先确定问题是认证、角色管理、动态策略还是关系授权,不能因为产品都写着“Authorization”就认为可以互换。
16. 推荐架构
小型单体
Spring Security + 本地 RBAC + Repository 数据权限;ACL 仅在有分享需求的资源中实现。
中型多系统
统一权限目录和治理中心,Role Assignment/Policy 集中管理,权限快照分发到业务服务,高风险请求远程决策。
大型平台
控制面与数据面分离;关系授权、策略决策和数据权限各自使用适合的执行组件;版本化快照、全链路审计、灰度策略和故障演练成为基础能力。
17. 常见错误
- 每个请求都同步远程鉴权,没有缓存和降级边界。
- 把所有权限塞入长寿命 JWT。
- 缓存失效只依赖 Pub/Sub,消息丢失后永久陈旧。
- 服务间只传用户 ID,不验证服务身份和代理权限。
- 多租户只在数据库隔离,Redis 和搜索索引共用 Key。
- 权限中心复制全部业务数据,形成新的单体和数据一致性问题。
- 只监控 5xx,不监控错误 Deny、版本分裂和撤销延迟。
18. 小结
权限中心的关键不是“提供一个 hasPermission API”,而是管理事实源、版本、传播、执行和故障边界。正确的模型必须通过稳定的运行时架构才能真正成为安全边界。
评论