Contents

数据平台权限管理:从 Scoped RBAC 到 ABAC 与 ReBAC

数据平台的权限问题,往往不是“这个人有没有登录”,而是“这个人能否在项目 A 中查看某段视频、导出原始文件、运行高成本任务,以及修改其他人的标注”。按钮能不能显示,只是这套系统的最后一层表现。

本文参考 Data Flywheel 的“设计权限管理系统”讨论,以及 2026-09-06 阅读到的本地代码。当前方案是 Keycloak 负责身份认证,FastAPI 管理应用会话,平台用户/组、角色与作用域负责业务授权,PyCasbin 执行角色权限判断。以下将现有实现与后续扩展建议分开说明。

1. 先分清认证、授权和数据过滤

层次回答的问题数据平台中的例子
Authentication你是谁通过 Keycloak 完成登录
Authorization你能做什么是否允许执行 dataset:export
Data Scope你能操作哪些对象只允许导出项目 A 的授权数据
Audit谁在什么情况下做了什么记录导出人、数据版本、范围与结果

Keycloak 支持独立账号与身份集成,因此没有企业 SSO 也可以先建设平台登录。选择它管理账号,不意味着需要把每个视频和每条需求的授权都塞进身份系统。参见 Keycloak 官方介绍。

本文建议将身份源与平台内部用户分离,外部身份用 (issuer, subject) 映射到稳定的内部用户 ID。这是扩展建议:当前代码使用 keycloak_subject 字段处理既定身份源,不能直接把它视为已经实现了任意多身份源绑定。

2. RBAC、ABAC、ReBAC 如何选择

这些模型解决的复杂性不同,可以组合使用。下表用于工程决策,不是产品排名。模型概念可参见 OpenFGA 授权概念。

模型基本表达适合的业务主要代价
ACL对象列出谁能做什么少量对象的直接共享对象多时维护与继承困难
RBAC用户通过角色获得操作权限管理员、工程师、标注员分工粗粒度角色难表达复杂条件
Scoped RBAC角色绑定限定生效范围同一人在不同项目担任不同角色需要明确作用域继承与越界规则
ABAC根据用户、资源与环境属性判断敏感等级、地区、用途、有效期限制属性可信度、规则冲突与解释成本
ReBAC根据对象关系推导授权团队、目录、数据集共享与继承关系模型、查询与一致性更复杂

对 Data Flywheel 当前阶段,项目级 Scoped RBAC 加必要的业务条件足够直接。不要为每个项目复制一套角色;应把“编辑者”作为可复用角色,把“项目 A”放到授权绑定中。

如果以后出现复杂目录共享,再评估 ReBAC;如果数据访问大量依赖标签、区域和用途,再评估 ABAC。简单地增加一个 owner_id == user_id 检查,不代表已经需要建设通用属性策略平台。

3. 当前项目如何实现 Scoped RBAC

核心对象可以表达为:

1
2
3
用户 ──属于── 用户组
用户或用户组 ──在某作用域绑定── 角色
角色 ──包含── 权限(resource, action)

例如:

主体角色作用域
算法组数据查看者项目 A
数据工程组数据编辑者项目 A
用户甲数据导出者项目 A
用户甲数据查看者项目 B

当前 apps/api/app/rbac.py 先从数据库筛选用户直接绑定与用户组绑定,保留全局或匹配当前 scope 的角色,再交给 PyCasbin 判断资源与动作。casbin_model.conf 本身使用的是 sub, obj, act 三元模型,作用域过滤在外层 Python 代码完成,并非直接使用四元 domain 模型。

这与 Casbin 官方提供的 RBAC with Domains 是两种实现路径。文章描述设计时要看实际执行位置,不能因为系统叫 Scoped RBAC,就假定配置文件中一定存在 domain。

目前允许权限取并集,没有匹配授权则拒绝。账号停用、会话限制和资源归属应作为额外约束检查;用户具有某项操作权限,并不应绕过对象范围。

4. 后端必须执行完整的数据边界

推荐的请求处理顺序是:

1
2
验证会话 → 确定有效身份 → 检查操作权限
→ 解析可信资源归属 → 限定查询范围 → 执行动作 → 审计

客户端提交的 project_id 是选择条件,不能作为授权证据。列表、详情、统计、导出和文件访问应遵循同一套范围规则,否则用户可能无法打开详情,却能从统计接口或下载地址拿到信息。

Data Flywheel 的需求模块提供了一个具体例子:在现有业务规则下,拥有管理权限的人可以查看更广范围;普通开发角色只读取自己发起或负责的需求。交付动作还会校验负责人,验收动作对非管理用户校验发起人。这里的“角色操作许可 + 对象关系”共同决定结果。

面向其他数据对象,还应考虑:

  • 行级:按租户、项目、数据集或负责人过滤记录。
  • 列级:隐藏或脱敏敏感字段,同时限制排序、搜索、聚合等间接访问。
  • 对象存储:播放、缩略图、下载都经服务端授权,短期签名链接的有效期与撤权窗口匹配。
  • 批量操作:验证所有目标对象,明确全部失败还是返回逐项结果,不能只检查第一条。
  • 检索:在可信查询层限定候选范围,并在返回前复核;结果片段、计数和缓存同样受限。

Apache Ranger 提供面向数据服务的集中策略与插件集成能力;是否能实施某种细粒度控制,要看具体引擎与插件支持。它适合评估多种数据引擎统一治理的场景,而非替代所有应用业务规则。参见 Apache Ranger。

5. 策略引擎不等于执行边界

可以把授权系统拆为三个职责:管理策略、做出决策、执行限制。OPA 侧重把策略决策与应用逻辑分离,但应用仍要在正确位置调用并执行结果。参见 OPA 官方文档。

选择更适合评估的条件不应误以为
PyCasbinPython 应用内角色规则、嵌入式决策自动过滤所有 SQL 与文件访问
OPA多服务共享属性规则与策略测试引擎返回 allow 后就有完整数据隔离
OpenFGA对象共享、组织与目录关系复杂接入后不再需要资源查询与撤权设计
Ranger数据湖与多引擎访问治理安装管理端后所有存储直连都被覆盖

当前代码逐次构造授权判断所需状态,逻辑容易理解。将来优化缓存时,需要一起设计权限变更版本、撤权失效、最长陈旧窗口与失效失败行为。不能只为减少数据库查询而让已撤销权限长时间有效。

6. 受控代登录:保留两种身份

排查用户问题时,“管理员看到的页面”和“普通用户看到的页面”可能不同。当前项目实现了应用层 Impersonation,核心区别是:

1
2
actor = 实际登录并发起代操作的人
effective_user = 本次业务操作使用权限的人

授权按有效用户执行,审计保留实际操作者。代操作不能把管理员权限叠加到普通用户身上,否则无法验证真实用户体验。

目前代码包含专用代登录权限、原因、期限、禁止嵌套、CSRF 检查和前端持续提示。后续应继续验证目标停用、权限撤销、会话超时、多标签页与缓存切换等情况。代登录可以帮助排障,但不能代替对真实登录流程的测试。

浏览器使用 HttpOnly Cookie 有助于限制脚本直接读取会话值,修改操作仍需要 CSRF 等配套控制;它也不意味着 XSS 后的操作风险消失。生产配置必须与本地自动开发会话分开。

7. 用反向案例验证权限

以下测试比“管理员能打开页面”更有价值:

场景期望结果
将项目 A 的对象 ID 换成项目 B 的 ID后端拒绝或按统一策略隐藏对象存在性
开发者直接调用他人需求的交付 API拒绝
批量导出混入一个无权限对象按约定拒绝或返回明确的逐项拒绝结果
移出用户组后继续访问旧缓存在定义的撤权时限内失效
开始或结束代登录后返回上一页不残留其他身份的业务数据
API 返回无权限前端显示受限状态,不能用演示数据伪装成功

数据平台的授权体系应围绕具体对象与操作逐步完善。插件任务如何获取受限能力,继续见 Operator as Plugin 的可行性讨论;界面如何呈现权限与身份状态,见 UI 设计与视觉规范。