权限系统总体设计:从身份、资源到授权决策

很多后台系统最初只有五张表:用户、角色、权限、用户角色、角色权限。它可以解决菜单和接口的基础访问控制,却很快会遇到无法自然表达的问题:某份合同只分享给三个人、销售只能看自己负责的客户、财务主管审批额度为十万元、管理员不能审批自己创建的付款单、外部成员只能临时访问项目文档、AI Agent 代表用户执行时不能突破自身工具权限。

这些问题说明,权限系统不是“把权限字符串装进用户对象”,而是一套围绕身份、资源、关系、属性、作用域和生命周期建立的决策体系。

权限系统总体架构

1. 认证、授权、审计和业务校验

四者必须分开:

层次 回答的问题 典型实现
认证 Authentication 请求方是谁 Session、JWT、OIDC、证书、Workload Identity
授权 Authorization 能否执行这个操作 RBAC、ACL、ABAC、ReBAC、数据权限
审计 Audit 谁在何时做了什么 决策日志、授权变更日志、业务操作日志
业务校验 当前业务状态是否允许执行 状态机、额度、库存、审批流、乐观锁

JWT 不是权限模型,OAuth 2.0 也不是企业角色系统。Token 可以携带身份或部分授权信息,但最终仍要由资源服务判断请求是否被允许。

以付款单 P1001 为例:王芳通过认证后证明自己是 U1003;权限系统判断她是否拥有 finance:payment:approve、是否在华东分公司的作用域内、是否超过审批额度;业务系统再判断付款单是否处于 PENDING_APPROVAL、是否已经被其他流程处理。任何一层失败,操作都不能执行。

2. 一次权限判断有哪些对象

简化模型是:

Subject + Resource + Action + Context → Decision

企业系统需要更完整地记录:

Actor + Principal + Subject + Resource + Action + Context + Scope
→ Decision + Reason + Obligations

授权决策核心对象

Actor、Principal、Subject

普通操作中三者通常相同:张三登录后读取自己的订单,实际操作者、已认证身份和被评估主体都是张三。

代理场景中则不同。赵强模拟张三排查问题时:

Actor = 赵强
Principal = 赵强
Subject = 张三

系统按照张三的权限返回页面,但审计日志必须记录真正操作者赵强。AI Agent 代表用户执行时也必须同时记录 Agent 和用户,不能只留下用户身份。

Resource 与 Action

Resource 是被保护对象,可以是资源类型,也可以是具体实例:

资源类型:order、payment、document
资源实例:O1001、P1001、D1001

Action 应使用业务语义:

read、update、approve、reject、export、share、assign

approve 不能被模糊地塞进 update,导出也不应从读取权限自动推导,因为它们具有不同风险和审计要求。

Context 与 Scope

Context 是请求时的动态环境,例如时间、IP、设备可信度、风险评分和 MFA 状态。Scope 是授权在哪个边界内有效,例如华东销售部、Project-A、当前租户或某份文档。

权限与作用域应成对保存:

sales:order:read → 华东销售部
sales:order:export → Project-A

不能先把权限合并成字符串集合,再把所有 Scope 混成一个大范围。

3. 人类和非人权限主体

权限主体不只有员工。

人类主体

  • 正式员工:通常由 HR 和组织系统驱动生命周期。
  • 管理员:具有管理能力,但不应天然拥有所有业务数据。
  • 外部用户:需要明确的赞助人、有效期和资源范围。
  • 临时人员:权限必须自动过期,不能依赖人工记忆回收。

非人主体

  • 服务账号:有负责人、凭证轮换和到期时间。
  • 微服务:使用服务身份访问下游,不能伪装成任意用户。
  • 定时任务:需要限制时间窗口、数据范围和批量操作能力。
  • 第三方应用:通过 OAuth Scope 或应用角色获得最小权限。
  • AI Agent:既要受用户权限限制,也要受 Agent 自身工具权限限制。

统一抽象 Principal 有利于复用 Role Assignment、ACL 和审计机制,但不同类型的凭证和治理策略不能完全相同。

4. 权限粒度

企业系统常见粒度包括:

  1. 菜单、页面和按钮:主要服务前端体验。
  2. API 与业务操作:真正的后端安全边界。
  3. 数据行:决定可以访问哪些订单、客户和付款单。
  4. 字段:决定敏感字段隐藏、脱敏、只读或禁止导出。
  5. 资源实例:控制某份文档、某个项目和某张报表。
  6. 动态条件:根据金额、时间、设备、风险和业务关系判断。

前端隐藏按钮不能替代后端鉴权。攻击者不需要点击按钮,可以直接构造 HTTP、RPC 或消息请求。

5. ACL、RBAC、ABAC 与 ReBAC

四种模型的分工

ACL:从资源出发

D1001 的 ACL 可以记录:Project-A 项目组允许读取,Alice 允许评论但禁止下载。它适合具体资源分享和资源树继承。

RBAC:从职责出发

王芳获得财务主管角色,角色包含付款读取、审批、拒绝和导出权限。RBAC 擅长规模化管理稳定的功能权限。

ABAC:从属性和上下文出发

即便拥有审批权限,王芳只有在金额不超过审批额度、不是本人创建、MFA 有效且设备风险可接受时才能批准。ABAC 处理动态条件。

ReBAC:从关系图出发

张三是 Project-A 的成员,D1001 属于 Project-A,因此张三可以读取 D1001。ReBAC 适合项目、团队、负责人和资源包含关系。

这些模型不是互相取代。成熟系统通常用 RBAC 提供基础能力,用 ACL/ReBAC 精确到资源,用 ABAC 添加动态限制,再由数据权限把结果落实到数据库访问。

6. 功能权限、数据权限和业务规则

三者经常被混在一起:

功能权限:张三能否查询订单?
数据权限:张三能查询哪些订单?
业务规则:当前订单是否允许修改?

SALES_MANAGER_EAST_CHINA 这种角色把职位、地区和数据范围绑在一起,短期方便,长期会造成角色爆炸。更稳妥的设计是:

Role = SALES_MANAGER
Permission = sales:order:read
Scope = ORG-110
Data Scope = DEPARTMENT

7. 权限从哪里来

用户最终权限可能来自:

  • 直接 Role Assignment;
  • 用户组、组织和岗位的间接角色;
  • 角色层级继承;
  • ACL 和资源所有权;
  • 项目成员等业务关系;
  • 临时委托;
  • ABAC 策略;
  • 系统默认权限。

系统不能只保存“最终有权限”这一结果,还要保留来源链。否则当用户退出项目组或临时授权到期时,无法准确撤销对应来源,也无法解释为什么用户仍有同一权限。

8. 传播和冲突不是一套规则

不同模型的传播机制不同:

  • ACL:父资源向子资源继承,可选择停止继承。
  • RBAC:高级角色继承基础角色的权限,但不自动扩大 Scope。
  • ABAC:组织、资源分类或默认属性向下传播,由策略优先级处理冲突。
  • 数据权限:上级组织范围可以包含下级,但下级不会反向获得上级数据。
  • ReBAC:只沿预先声明的关系路径推导,不能无限遍历任意关系。

统一原则只有两个:默认拒绝;租户隔离和系统级强制规则优先。ACL 是否 Deny 优先、ABAC 使用哪种组合算法,应由具体模型显式定义。

9. 权限系统的组件边界

授权请求流程

一个完整系统通常包含:

  • 身份系统:认证、Token、凭证和 MFA。
  • 组织中心:员工、部门、岗位和汇报关系。
  • 权限目录:应用、资源类型、操作和权限元数据。
  • 授权管理:角色、ACL、Scope、委托和有效期。
  • PAP:管理和发布策略。
  • PDP:计算允许或拒绝。
  • PIP:提供组织、资源、设备和风险属性。
  • PEP:在 API、Service、Repository 或网关执行决策。
  • 审计中心:记录授权变更、决策和业务操作。

权限中心不应复制全部订单、客户和付款单数据。业务状态和动态资源属性仍由业务系统负责,权限中心通过请求上下文或 PIP 获取决策所需的最小信息。

10. 一次请求的默认决策顺序

  1. 验证 Principal、凭证、会话和主体状态。
  2. 建立 Actor、Subject、Tenant、Resource、Action、Context。
  3. 检查租户边界、禁用状态、撤销和强制安全策略。
  4. 收集角色、ACL、关系、委托和所有权来源。
  5. 判断基础功能权限。
  6. 计算 Scope、数据范围和字段限制。
  7. 执行 ABAC、职责分离和风险策略。
  8. 返回 ALLOWDENY,并携带原因和 Obligations。
  9. 业务系统执行脱敏、水印、MFA 和审计义务。
  10. 继续执行状态机、乐观锁和业务事务。

没有任何明确 Allow、必需属性缺失、权限服务无法确定结果时,都应拒绝。低风险操作是否允许使用有效本地快照降级,需要显式配置;高风险审批和权限管理通常应在无法验证最新版本时拒绝。

11. 权限编码

专题统一采用:

<domain>:<resource>:<action>

例如:

sales:order:read
finance:payment:approve
document:file:download
iam:role:assign

编码不包含 tenant_id、organization_id、用户 ID 和资源实例 ID。具体边界由 Scope、Data Scope、ACL 和 Policy 表达。权限进入生产后不能静默改变语义;破坏性变化应创建新权限并执行迁移。

12. 小结

权限系统的核心不是角色表,而是建立可追踪的授权关系,并在一次请求中把身份、资源、操作、作用域、关系和动态条件组合成可解释决策。

后续文章将分别展开:ACL 如何管理资源实例,RBAC 如何管理角色和约束,ABAC 如何建立策略引擎,数据权限如何进入 SQL,企业如何治理权限生命周期,以及权限中心如何处理缓存、一致性和测试。

参考资料