1. 权限模型核心概念:访问控制三元组、主体-客体-操作、权限判定本质
1.1 访问控制三元组:权限系统的原子结构
所有权限模型的底层逻辑都建立在同一个原子结构之上——访问控制三元组。无论 RBAC、ABAC 还是 ReBAC,最终都要回答同一个问题:谁(主体)能否对什么(客体)执行何种(操作)。三元组是不可再分的最小权限单元,任何权限判定的本质都是对这个三元组进行一次布尔判决。
| 元素 | 定义 | 典型示例 |
|---|---|---|
| 主体(Subject) | 发起访问请求的活跃实体 | 用户、服务账户、设备、进程 |
| 客体(Object) | 被访问的被动资源 | 文件、API 端点、数据库行、微服务 |
| 操作(Operation) | 对客体执行的动作类型 | 读取、写入、删除、执行、授权 |
设计原则:三元组中的每个元素都必须是系统中可枚举的实体。如果主体、客体或操作的定义出现模糊,后续的权限判定将产生不可预测的冲突或绕过风险。
1.2 权限判定本质:从三元组到决策
权限判定的数学本质是一个布尔函数:allow(Subject, Object, Operation) → { true, false }。该函数由策略引擎根据预置的规则集计算得出。无论模型如何演进,RBAC 引入角色、ABAC 引入属性、ReBAC 引入关系,最终都是为这个核心函数提供更丰富的判定维度,而非改变其二元输出的本质。
// 权限判定核心逻辑(策略无关的通用形式)
function checkPermission(subject, object, operation) -> boolean:
// 1. 加载适用于 subject/object/operation 的策略集
// 2. 按模型规则(角色/属性/关系)进行匹配
// 3. 返回 allow 或 deny
return policyEngine.evaluate(subject, object, operation)
1.3 模型边界:三元组的扩展方式
三种主流模型对三元组的扩展路径不同,决定了各自的适用边界:
- RBAC:在主体与权限之间插入角色层,将主体-操作的直接映射变为主体-角色-权限的间接映射,适合职责清晰、角色稳定的组织。
- ABAC:为主体、客体、操作和环境附加属性,判定时按属性表达式动态计算,适合资源类型多样、权限规则频繁变化的场景。
- ReBAC:在主体与客体之间建立关系图,判定的依据是两者之间是否存在特定的关系路径,适合社交网络、文档协作等强关联场景。
三者的核心差异在于:RBAC 压缩了主体维度,ABAC 展开了属性维度,ReBAC 展开了关系维度。超过模型边界强行使用会导致策略爆炸或语义失真。
1.4 分层职责:权限系统的三层结构
一个完整的权限系统在逻辑上分为三层,每层有明确的职责边界:
- 策略定义层:负责管理角色、属性、关系等元数据以及权限规则的定义与存储。
- 策略决策层(PDP):接收访问请求,加载策略,执行判定并返回决策结果(Allow/Deny/NotApplicable)。
- 策略执行层(PEP):拦截用户请求,调用 PDP 获取决策,并根据结果强制执行(放行或阻断)。
分层职责的核心价值在于:决策与执行分离,使得策略变更不影响执行逻辑,执行效率也不受策略复杂度拖累。
1.5 数据流与信任链路
一次完整的权限判定数据流包含以下步骤:
- 用户通过客户端发起资源访问请求,PEP 拦截请求并提取三元组(Subject, Object, Operation)。
- PEP 将三元组封装为判定请求,发送至 PDP。
- PDP 从策略仓库加载适用的策略集,执行判定逻辑。
- PDP 返回决策结果(Allow/Deny)给 PEP。
- PEP 根据决策结果放行请求或返回拒绝响应。
信任链路的关键在于:PEP 必须能够可信地获取主体身份和客体标识,任何环节的身份伪造或标识篡改都会导致判定失效。建议在 PEP 与 PDP 之间使用双向 TLS 并附带请求签名。
1.6 选型权衡
围绕三元组的扩展方式,不同模型在以下三个维度上存在根本性权衡:
| 维度 | RBAC | ABAC | ReBAC |
|---|---|---|---|
| 策略灵活性 | 低(角色变更需管理员干预) | 高(属性表达式动态计算) | 中(关系变更自动传播) |
| 判定性能 | 高(预计算角色权限表) | 中(每次请求需计算属性表达式) | 中低(需要遍历关系图) |
| 治理复杂度 | 低(角色数量可控) | 高(属性值分散,策略易膨胀) | 中(关系维护需图数据库支持) |
选型红线:当主体数超过 10⁴ 且客体类型超过 50 种时,纯 RBAC 会出现角色爆炸;当属性维度超过 20 个且策略数超过 1000 条时,ABAC 的审计成本急剧上升;当关系深度超过 5 层时,ReBAC 的查询延迟需要图索引优化。
1.7 风险点
- 三元组定义不全:遗漏环境上下文(如时间、IP、设备状态)作为隐式因子,导致权限被非预期绕过。例如未限制操作只能在办公网络执行。
- 主体-客体边界模糊:同一实体有时扮演主体、有时扮演客体(如服务账户同时调用其他 API 并暴露自身接口),必须在模型设计时明确其角色归属。
- 操作语义冲突:不同团队对“写入”的理解不同(覆盖 vs. 追加),导致策略评估结果不一致。所有操作必须在组织内建立统一的语义注册表。
- 信任链路截断:PEP 无法验证主体身份的真实性,或 PDP 加载了过期的策略,造成决策依据不可信。
常见反模式:在 RBAC 中为每个用户创建独立角色来模拟 ABAC 的灵活性,这会导致角色数量爆炸且审计无法追踪。遇到此类需求应直接考虑 ABAC 或 ReBAC,而非在原有模型上打补丁。
1.8 落地步骤
- 盘点资源与实体:列出系统中所有需要保护的对象(客体)、所有可能发起请求的实体(主体)以及所有允许的操作类型。
- 建立三元组目录:将主体、客体、操作逐一编号并录入元数据中心,确保每个元素有唯一标识和负责人。
- 绘制数据流图:明确每次权限请求从 PEP 截获到 PDP 决策再到 PEP 执行的完整链路,标注信任边界。
- 选择扩展模型:根据主体规模、客体多样性、变更频率三个指标选择 RBAC / ABAC / ReBAC 或组合模型。
- 定义策略模板:基于三元组输出第一条策略(如“允许 管理员 对 系统配置 执行 写入”),并逐步补充边界条件。
- 实施灰度验证:在非关键路径上开启权限判定,观察误杀率和性能损耗,迭代优化策略表达式。
1.9 验收标准
| 验收项 | 通过标准 | 验证方法 |
|---|---|---|
| 三元组完整性 | 所有受保护资源均被客体目录覆盖,无遗漏 | 对比资源清单与客体目录 |
| 判定一致性 | 同一三元组在不同时间、不同 PDP 节点上得到相同结果 | 批量回放历史请求日志 |
| 链路可审计 | 每次权限判定都记录主体、客体、操作、决策、策略版本号和时间戳 | 检查审计日志是否包含上述字段 |
| 性能基线 | P95 判定延迟 ≤ 10ms(RBAC)/ ≤ 50ms(ABAC)/ ≤ 100ms(ReBAC) | 压测脚本模拟并发请求 |
| 变更可追溯 | 每条策略的创建、修改、启用、停用都有操作人、时间和原因 | 审查策略管理后台的变更记录 |
核心理念回顾:访问控制三元组是权限系统的“不可变基座”。无论选择哪种模型,最终都是在这个基座上添加角色、属性或关系维度。把三元组定义清楚、把判定链路梳理干净,是后续所有权限工作的前提。