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

很多后台系统最初只有五张表:用户、角色、权限、用户角色、角色权限。它可以解决菜单和接口的基础访问控制,却很快会遇到无法自然表达的问题:某份合同只分享给三个人、销售只能看自己负责的客户、财务主管审批额度为十万元、管理员不能审批自己创建的付款单、外部成员只能临时访问项目文档、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. 返回 ALLOW 或 DENY,并携带原因和 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,企业如何治理权限生命周期,以及权限中心如何处理缓存、一致性和测试。

参考资料