3. 权限控制模型:RBAC/ABAC/ReBAC 对比与选型
权限控制,说白了就是解决「谁能干什么」的问题。我在金融风控系统里摸爬滚打这些年,见过太多因为权限设计不合理导致的线上事故。有的公司直接给所有开发人员配了生产库的读写权限,结果一个误操作,几百万条风控规则被清空。嗯,这种教训太深刻了。
今天咱们就聊聊三种主流的权限模型:RBAC、ABAC 和 ReBAC。我会结合自己的实战经验,帮你理清它们的适用场景和选型思路。
3.1 三种模型的核心差异
先看一张对比图,我亲手画的,帮你快速建立整体认知。
3.2 RBAC:最经典的权限模型
RBAC 是我最早接触的权限模型。它的核心思想很简单:把权限分配给角色,再把角色分配给用户。用户不直接拥有权限,而是通过角色间接获得。
我在一个风控后台系统里用过 RBAC。当时定义了三个角色:风控管理员(能配置规则)、风控操作员(能查看和审批)、审计员(只能查看日志)。结构清晰,维护起来也方便。
RBAC 的核心要素:
- 用户(User):系统的操作者
- 角色(Role):权限的集合,如「风控管理员」
- 权限(Permission):对资源的操作,如「创建规则」
- 会话(Session):用户激活的角色集合
但 RBAC 有个坑。你想想看,如果业务复杂了,角色数量会爆炸。比如一个风控系统,按业务线分、按地域分、按操作类型分,最后可能定义出上百个角色。我见过一个项目,角色表里躺着 300 多个角色,维护成本极高。
避坑指南:我曾经在一个项目中过度使用 RBAC,导致角色数量失控。后来我们引入了「角色继承」和「角色约束」机制,才勉强控制住。如果你发现角色数量超过 50 个,就该考虑其他模型了。
3.3 ABAC:更灵活的细粒度控制
ABAC 就不一样了。它不依赖角色,而是通过属性来判断权限。属性可以是用户的(如部门、职级)、资源的(如风险等级、创建时间)、环境的(如访问时间、IP 地址)。
举个例子:在风控系统中,我们要求「只有风控部门的员工,在工作时间(9:00-18:00),才能修改高风险规则」。用 ABAC 表达就是:
策略示例:
IF
用户.部门 = "风控部" AND
用户.职级 >= "高级" AND
环境.时间 BETWEEN "09:00" AND "18:00" AND
资源.风险等级 = "高"
THEN
允许修改
ABAC 的灵活性是 RBAC 没法比的。但代价也很明显:策略引擎的性能开销大,策略管理复杂。我在一个实时风控系统里用过 ABAC,每次权限判断都要查询多个属性源,延迟从 2ms 飙升到 50ms。后来我们加了本地缓存和属性预加载,才把延迟降下来。
我的建议:ABAC 适合权限规则频繁变化的场景。但一定要做好策略的版本管理和测试。我曾经因为策略写错,导致所有风控人员都无法登录系统,整整排查了 3 个小时。
3.4 ReBAC:基于关系的权限模型
ReBAC 是相对较新的模型。它的核心是「关系」。用户通过某种关系(如「属于」、「管理」、「分享」)来访问资源。
典型的例子是 Google Docs:你可以把文档分享给某个团队,团队里的每个人都能访问。这种权限用 RBAC 或 ABAC 表达都很别扭,但 ReBAC 天然支持。
在风控系统中,ReBAC 也有用武之地。比如一个风控规则集,被多个业务线共享。某个用户因为「属于」业务线 A,所以能访问规则集 A 下的所有规则。这种关系链的权限表达,ReBAC 最擅长。
ReBAC 的典型实现:
- Google Zanzibar:全球统一的权限系统
- OpenFGA:开源的 ReBAC 实现
- 关系图谱:用户、资源、关系三元组
3.5 选型建议
说了这么多,到底怎么选?我根据自己的经验,整理了一个选型表:
| 场景 | 推荐模型 | 原因 |
|---|---|---|
| 组织架构清晰,角色固定 | RBAC | 简单、易维护、性能好 |
| 权限规则复杂,动态变化 | ABAC | 灵活、细粒度、可扩展 |
| 社交、协作、共享场景 | ReBAC | 自然表达关系权限 |
| 混合场景 | RBAC + ABAC | 兼顾简单与灵活 |
我个人习惯的做法是:先用 RBAC 搭骨架,再用 ABAC 做补充。比如风控系统的基础权限用 RBAC 管理,但一些特殊的、动态的权限规则用 ABAC 策略引擎来处理。这样既保证了核心权限的稳定性,又保留了灵活性。
3.6 细粒度权限引擎设计
说完了模型,咱们聊聊怎么落地。一个细粒度的权限引擎,核心要解决三个问题:
- 策略定义:怎么描述权限规则?
- 策略评估:怎么高效判断权限?
- 策略管理:怎么维护和审计权限?
我设计过一个权限引擎,架构大概是这样的:
权限引擎核心组件:
1. 策略定义层
- 支持 JSON/YAML 格式的策略描述
- 支持条件表达式(AND/OR/NOT)
- 支持属性来源配置(用户、资源、环境)
2. 策略评估层
- 策略缓存(本地 + 分布式)
- 属性预加载(减少查询次数)
- 短路评估(快速拒绝/允许)
3. 策略管理层
- 策略版本管理
- 策略测试沙箱
- 策略变更审计日志
性能优化技巧:我在一个高并发风控系统里,把权限判断的 P99 延迟从 100ms 降到了 5ms。核心做法就是「策略预编译」和「属性本地缓存」。每次策略变更后,预编译成可执行的表达式树,缓存到本地。属性值也提前加载到本地内存,避免每次判断都查数据库。
3.7 权限审计与越权检测
权限设计得再好,也防不住人为的误操作或恶意越权。所以权限审计和越权检测是最后一道防线。
3.7.1 权限审计
权限审计的核心是「谁在什么时候,通过什么方式,访问了什么资源」。我建议至少记录以下信息:
- 用户身份:用户 ID、角色、部门
- 操作行为:访问、修改、删除、审批
- 资源信息:资源 ID、资源类型、风险等级
- 环境信息:时间、IP、设备指纹
- 决策结果:允许、拒绝、异常
审计日志不能只存不用。我见过很多公司,审计日志存了几年,从来没分析过。这等于白存。建议定期做权限审计报告,检查是否存在「权限滥用」或「权限漂移」的情况。
避坑指南:我曾经发现一个审计日志的漏洞:日志记录的是「用户请求的权限」,而不是「实际执行的权限」。结果有人通过 API 直接调用,绕过了权限判断。后来我们强制在权限引擎的「执行点」记录日志,才堵住这个漏洞。
3.7.2 越权检测
越权检测分为两种:
- 水平越权:用户 A 访问了用户 B 的资源(如 A 查看了 B 的风控规则)
- 垂直越权:普通用户执行了管理员的操作(如操作员修改了系统配置)
检测方法也很直接:
- 实时检测:在权限引擎中增加「异常行为检测」模块。比如一个用户突然在凌晨 3 点批量查询敏感数据,直接触发告警。
- 离线分析:定期分析审计日志,用规则或机器学习模型发现异常模式。比如某个角色突然访问了它从未访问过的资源类型。
我个人的经验是:实时检测用规则引擎(如 Drools),离线分析用 Spark 或 Flink。两者结合,基本能覆盖 90% 的越权场景。
总结一下:权限控制不是一锤子买卖。选对模型是第一步,设计好引擎是第二步,持续审计和检测是第三步。三步都做好了,你的风控系统才算真正安全。
公众号:蓝海资料掘金营,微信deep3321