权限系统设计:从 RBAC 到图权限,再到列表查询的性能难题
权限系统设计:从 RBAC 到图权限,再到列表查询的性能难题
一、权限系统的本质
权限系统的核心是三元组:实体、资源、操作
以 Linux 文件系统为例:
- 实体(Who): 用户(User)
- 资源(What): 文件(File)
- 操作(How): rwx(读、写、执行)
# 示例:用户 alice 对文件 /data/report.txt 有读写权限
alice (实体) -> /data/report.txt (资源) -> rw- (操作)
二、权限模型的演进
2.1 ACL(访问控制列表)- 最原始的方式
直接定义 “谁对什么有什么权限”:
alice -> /data/report.txt -> read, write
bob -> /data/report.txt -> read
charlie -> /data/secret.txt -> read, write
问题:
- 用户多了管理困难(每个用户都要单独配置)
- 权限变更成本高(要改 100 个用户的权限就要改 100 次)
2.2 用户组(Group)- 对实体的包装
引入"组"的概念,批量管理用户:
组: managers = [alice, bob, charlie]
组: developers = [david, eve, frank]
managers -> /data/reports/* -> read, write
developers -> /data/code/* -> read, write, execute
改进:
- 新增用户只需加入组
- 调整组的权限即可影响所有成员
仍然不够:权限类型(read, write, execute)仍然散落各处,难以复用
2.3 RBAC(基于角色的访问控制)- 对操作的包装
引入"角色"的概念,封装一组操作:
角色定义:
- 角色: admin -> 操作: [read, write, delete, grant]
- 角色: editor -> 操作: [read, write]
- 角色: viewer -> 操作: [read]
用户分配:
- alice -> 角色: admin (on /data/reports/*)
- bob -> 角色: editor (on /data/reports/*)
- charlie -> 角色: viewer (on /data/reports/*)
优点:
- 权限管理清晰:用户 -> 角色 -> 资源
- 易于扩展:新增角色即可,无需修改用户配置
- Go 语言推荐库:Casbin (支持 RBAC/ABAC/RESTful 等多种模型)
2.4 RBAC 的局限性
RBAC 适合:
- ✅ 静态的组织结构(角色相对固定)
- ✅ 权限与角色强相关(如:管理员、编辑、访客)
- ✅ 资源类型有限(如:文档、订单、用户)
RBAC 不适合:
- ❌ 动态的权限继承(领导自动继承下属权限)
- ❌ 复杂的关系链(A 的上级的上级也有权限)
- ❌ 资源之间有依赖(文件夹权限影响子文件)
三、权限继承的难题:Google Zanzibar
3.1 真实场景:组织层级权限
场景:
- Alice 是 Bob 的领导
- Bob 对资源 C 有权限
- 期望: Alice 自动继承 Bob 的权限(领导能看下属的所有资源)
传统 RBAC 解决不了这个问题,因为:
- Bob 的权限可能很多,手动给 Alice 分配不现实
- Bob 的下属可能变化(离职、调岗),需要实时更新
- 权限是间接的、传递的
