权限模型
2019 年,某云服务商的一次误操作导致某政务云平台数据被批量删除。事后复盘发现,运维人员的账号拥有「删除任意数据」的权限——这个权限原本只应该在紧急情况下由安全管理员手动授权,却因为权限模型设计粗糙,被长期授予了普通运维角色。
权限模型的设计往往在项目初期被草率对待,却在业务增长后成为安全与合规的噩梦。从简单的 RBAC 到精细化的 ABAC,从开源的 Casbin 到 Google 内部的 Zanzibar,本章节将系统梳理权限控制领域的技术演进与最佳实践。
核心内容概述
权限模型演进
权限模型经历了从粗粒度到细粒度、从静态到动态的��进:
RBAC:经典与陷阱
RBAC 看似简单,却藏着几个深坑:
- 角色爆炸:业务复杂后角色数指数增长,出现「普通管理员」「高级管理员」「特殊权限管理员」等难以维护的角色。
- 权限继承混乱:子角色继承父角色权限时,边界不清晰,容易出现越权。
- 最小权限原则违反:角色权限通常是「够用原则」而非「刚好够用」,长期积累导致过度授权。
详见 RBAC 深度解析 和 RBAC 设计最佳实践。
ABAC:灵活与复杂度
当 RBAC 满足不了需求时,ABAC 通过属性(用户属性、资源属性、环境属性)动态计算权限。它的优势是表达能力极强,劣势是策略管理和性能都是挑战。详见 ABAC 详解 和 ABAC 策略设计。
OPA:策略即代码
Open Policy Agent(OPA)将策略逻辑从应用代码中抽离出来,以声明式 Rego 语言表达。配合 Gatekeeper,可在 Kubernetes 环境中实现Admission Control。详见 OPA 深度解析 和 OPA 与 Kubernetes 集成。
Casbin:轻量级权限框架
Casbin 是一个支持多种访问控制模型的 Go 语言库,通过模型配置文件(.conf)而非代码来定义权限逻辑。详见 Casbin 权限框架。
子主题列表
模型基础
高级模型
策略引擎
开源框架
工程实践
思考题
问题 1:为什么 Google 选择自研 Zanzibar 而不是使用现有的开源方案(如 OPA)?
参考答案
Google Zanzibar 解决的核心问题是超大规模 + 宽松一致性的组合需求:
- 全球一致性要求:YouTube、Google Drive 等产品的权限系统需要服务全球数十亿用户,权限数据需要在全球多个数据中心保持同步。Zanzibar 采用 Paxos 复制的 Slotted Leaf Node 结构,保证最终一致性。
- 超低延迟要求:权限检查是热路径,Zanzibar 优化了 ZooKeeper 不擅长的「前缀匹配」场景,通过 Chandy-Misra-Gals 分布式复制实现毫秒级响应。
- 复杂关系建模:Google 内部有大量「文件夹-文档-分享」的层级和关系型权限,Zanzibar 的 Namespace-Tuple-Object-Subject 四元组模型天然支持这种场景。
- 一致性隔离:不同租户可以配置不同的 ZooKeeper 服务器,实现隔离。
开源方案(如 OPA)更适合中等规模场景,Google 的规模需求超出了通用开源方案的边界。
问题 2:在 RBAC 系统中,「审计权限」应该授予什么角色?审计员需要看到什么?
参考答案
这是一个经典的权限设计问题。
审计员的权限设计:
- 只读权限:审计员不应拥有任何写权限(创建/修改/删除)。
- 分离审计数据:审计日志本身需要受保护,普通管理员不能删除或篡改日志。可使用独立存储,审计员有读取权限。
- 最小知情原则:审计员通常只需要看到「谁在什么时间访问了什么资源」,不需要看到资源内容。
审计内容:
常见陷阱:
- 审计员角色混入写权限 → 审计记录可被篡改
- 审计日志存储在业务库 → 管理员可删除
- 审计员能看到数据内容 → 违反最小知情原则
问题 3:假设你需要为一个 SaaS 多租户系统设计权限模型,其中租户 A 的管理员能否访问租户 B 的数据?
参考答案
答案是 绝对不能,这是多租户安全的核心要求。
多层隔离设计方案:
- 租户标识作为强制属性:在 ABAC 策略中,
tenant_id应作为强制检查字段,任何权限决策必须包含租户隔离校验。 - 数据隔离:
- 方案 A:每个租户独立数据库(最强隔离,但成本高)
- 方案 B:数据库行级隔离(通过
tenant_id字段过滤) - 方案 C:Schema 隔离(PostgreSQL Schema)
- 权限预检查:在 OPA/Casbin 策略中,第一条规则永远是
tenant_id 匹配:
常见错误:
- 只在前端做租户隔离,后端 API 无验证(攻击者可绕过)
- 缓存 key 未包含 tenant_id(不同租户数据串读)
- 内部服务调用未传递 tenant_id(内部滥用)