本文系统梳理了六种主流权限控制模型(ACL、RBAC、ABAC、PBAC、DAC、MAC),从核心思路、优缺点到适用场景逐一剖析,并给出实际项目中的选型建议和混合模型实践。

写在前面

几乎每一个稍具规模的后台系统都绕不开权限控制——谁能看到什么数据、谁能执行什么操作,这些规则直接决定了系统的安全性和可用性。但权限控制远不止"加个权限字段"那么简单,不同的业务场景需要不同的权限模型来支撑。选错了模型,轻则管理成本飙升,重则留下安全漏洞。

我在实际项目中接触过几种权限模型,踩过一些坑,也做过一些取舍。这篇文章把主流的权限控制模型梳理一遍,希望对正在做权限设计的同学有所帮助。

权限控制的基本概念

在展开各种模型之前,先统一几个核心术语:

  • 主体(Subject):发起访问请求的实体,通常是用户,也可以是服务账号、设备等
  • 客体/资源(Object/Resource):被保护的对象,比如文件、接口、数据、菜单等
  • 操作(Action):主体对客体执行的行为,如读取、写入、删除、执行
  • 权限(Permission):主体是否被允许在某种条件下对某种资源执行某种操作
  • 策略(Policy):一组规则声明,定义在什么条件下允许或拒绝访问

理解了这些概念,我们来看看不同的权限模型是如何组织主体、资源和操作之间的关系的。


一、ACL:访问控制列表——最直觉的"谁可以干什么"

核心思路

ACL(Access Control List)是最基础、最直觉的权限模型。它的核心逻辑非常简单:每个资源维护一份"访问者清单",明确记录哪些主体可以对它执行哪些操作。

用公式表达就是:

1
资源 → [(主体, 操作), (主体, 操作), ...]

举个例子:一个文件的 ACL 可能长这样:

1
2
3
4
文件A:
- 张三: 读取, 写入
- 李四: 读取
- 王五: 读取, 写入, 删除

这其实就是很多开发者最初做权限系统的方式——直接在用户和权限之间建立关联。用户量少的时候,这种方式简单直接,非常有效。

优点

  • 直观易懂:权限关系一目了然,排查问题时直接看资源的 ACL 清单就行
  • 粒度极细:可以精确到单个资源的单个操作,想给谁什么权限就给什么权限
  • 实现简单:不需要引入角色、策略等中间层,数据库里一张关联表就能搞定
  • 灵活度高:可以对任意用户做任意粒度的权限调整,不受任何框架约束

缺点

  • 管理成本随规模爆炸:当用户和资源数量增长时,权限记录会急剧膨胀。1000 个用户 × 1000 个资源 = 最多 1,000,000 条权限记录,维护起来极其痛苦
  • 无法批量管理:新增一个员工,需要逐个资源添加权限;员工调岗,需要逐个资源修改权限,极易遗漏
  • 缺乏抽象能力:无法表达"所有经理都能查看财务报表"这样的规则,只能逐个经理添加
  • 权限冗余严重:多个资源的授权规则重复时,无法复用,只能重复配置

适用场景

  • 用户量少(几十人以内)、资源数量有限的内部系统
  • 需要对单个资源做精细化权限控制的场景,如文档协作平台(Notion、Trello 的单页面权限)
  • 操作系统文件权限(Linux 的 chmod 就是 ACL 的典型实现)
  • 临时授权场景,如临时给某人开放某个文件的编辑权限

个人体会

ACL 是我最早接触的权限模型,也是很多人做第一个权限系统时的选择。小项目用起来确实爽——想给谁权限就给谁,没有任何中间层的阻碍。但一旦用户超过一定规模,管理就会变成噩梦。我曾经在一个内部系统中用 ACL 方式管理权限,后来人员变动频繁,每次调岗都要手动改一堆权限,还经常改漏,最后不得不重构为 RBAC。


二、RBAC:基于角色的访问控制——企业级权限的标配

核心思路

RBAC(Role-Based Access Control)是目前应用最广泛的权限模型。它的核心思想是引入"角色"作为用户和权限之间的中间层:先把权限分配给角色,再把角色分配给用户。用户通过关联角色间接获得权限,实现"用户 → 角色 → 权限"的三层映射。

1
用户 → 角色 → 权限

举个例子:

1
2
3
4
5
6
7
角色定义:
- 财务专员: [查看报表, 提交报销, 审批报销]
- 部门经理: [查看报表, 审批报销, 查看员工信息]

用户分配:
- 张三 → 财务专员
- 李四 → 部门经理

RBAC 还可以进一步演进:

  • RBAC0:基础模型,用户-角色-权限三层结构
  • RBAC1:增加角色继承,比如"技术总监"自动继承"开发工程师"的所有权限
  • RBAC2:增加职责分离(SoD),比如"会计"和"出纳"角色互斥,同一用户不能同时拥有

优点

  • 批量管理极其方便:新员工入职只需赋予对应角色,角色下的所有权限自动生效。1000 个新员工入职,也只需要分配角色即可
  • 批量修改同样方便:需要调整某类人员的权限时,只需修改角色对应的权限,所有关联用户自动生效,不会遗漏
  • 结构清晰:权限关系通过角色组织,一目了然,便于审计和合规
  • 职责分离:RBAC2 支持互斥角色,防止权限集中带来的风险
  • 完美匹配企业组织架构:角色天然对应职位/岗位,与企业科层制高度契合

缺点

  • 难以精细化调控:角色的粒度是固定的,无法表达"张三虽然是经理,但不能看某个特定报表"这样的需求。要么给角色加权限(影响所有经理),要么单独处理(又回到了 ACL 的痛点)
  • 角色爆炸问题:当权限需求复杂多变时,角色数量会急剧膨胀。比如矩阵式组织中,一个员工同时属于项目 A 和部门 B,就需要创建 "项目A-经理"、"项目B-经理"、"部门C-经理" 等大量组合角色,角色可能达到上百个,管理反而变得困难
  • 静态性:无法处理动态条件,比如"只有工作时间才能访问"、"临时借调期间可以查看"这类场景
  • 灵活度低:一旦权限需求超出角色模型的表达能力,就只能通过创建更多角色来弥补,陷入角色爆炸的恶性循环

适用场景

  • 企业后台管理系统(ERP、CRM、HR 系统等)
  • 组织架构相对稳定、权限变化不频繁的系统
  • 需要批量管理用户权限的场景
  • 对合规审计有要求的系统

个人体会

RBAC 是我目前用得最多的权限模型,大部分企业级项目都在用。它的优势在组织架构稳定时非常明显——新增角色、调整权限都很方便。但我也遇到过角色爆炸的问题:一个项目里因为权限需求太细,角色从最初的 10 个膨胀到了 80 多个,每次新增功能都要纠结是新建角色还是修改现有角色,管理成本反而比 ACL 还高。后来我的做法是在 RBAC 基础上引入数据权限(行级过滤),一定程度上缓解了角色爆炸的问题。


三、ABAC:基于属性的访问控制——动态灵活的权限引擎

核心思路

ABAC(Attribute-Based Access Control)不再依赖固定的角色或列表,而是根据主体、资源、环境、操作等多个维度的属性动态计算权限

这么说可能还是有点抽象,我们换一种方式理解:在 RBAC 中,权限是"你是经理,所以你能看报表",这是一个静态的、非黑即白的判断;而在 ABAC 中,权限是"你是经理,并且你在工作时间,并且你从内网访问,并且这份报表属于你管辖的部门,所以你能看"——权限取决于多个条件是否同时满足。

ABAC 涉及四维属性:

  1. 主体属性(谁在访问):用户的部门、职级、项目组成员标签等
  2. 资源属性(访问什么):数据的密级、所属业务线、所属区域等
  3. 环境属性(在什么条件下访问):访问时间、网络位置(内网/外网)、设备安全状态等
  4. 操作属性(做什么操作):读取、写入、删除、导出等(不同操作可以有不同的策略)

伪代码示例

下面用一个简化的权限判断函数来展示 ABAC 的工作方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def check_permission(user, resource, action, environment):
"""
ABAC 权限判断核心逻辑
user: 主体属性(部门、职级、区域等)
resource: 资源属性(类型、密级、所属区域等)
action: 操作类型(读、写、删除等)
environment: 环境属性(时间、网络、设备等)
"""

# 规则1:只有财务部的人才能查看财务报表
if resource.type == "财务报表":
if user.department != "财务部":
return DENY

# 规则2:敏感数据只能在工作时间从内网访问
if resource.security_level == "敏感":
if environment.time < "09:00" or environment.time > "18:00":
return DENY
if environment.network != "内网":
return DENY

# 规则3:只能操作自己所属区域的数据
if resource.region != user.region:
return DENY

# 规则4:删除操作需要总监级别以上
if action == "删除" and user.level < "总监":
return DENY

# 所有规则都通过,允许访问
return ALLOW

再来看一个更贴近实际的场景——一个多租户 SaaS 平台的权限判断:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def check_saaS_permission(tenant, user, resource, action, env):
# 首先判断租户是否有这个功能模块(付费功能)
if resource.module not in tenant.purchased_modules:
return DENY, "租户未购买此功能"

# 判断用户在租户内的角色权限
if action == "导出" and user.role != "管理员":
return DENY, "仅管理员可导出"

# 判断数据是否属于当前租户(租户隔离)
if resource.tenant_id != tenant.id:
return DENY, "无权访问其他租户数据"

# 判断是否在安全环境下操作
if resource.level == "机密" and env.device_trust_level < "medium":
return DENY, "请在受信任的设备上操作"

return ALLOW, "允许访问"

从上面的伪代码可以看出,ABAC 的核心就是把权限判断变成一组条件规则的组合。每条规则检查一个或多个属性,所有规则都通过才允许访问。这比 RBAC 的"角色决定一切"要灵活得多——你不需要为"工作日内网财务经理"这种组合创建角色,只需要写几条规则就行。

优点

  • 极高的灵活性:可以表达任意复杂的权限规则,支持多维度组合判断
  • 动态授权:权限不是静态绑定的,而是根据实时属性动态计算,环境变化时权限自动调整
  • 解决角色爆炸:不需要为每种权限组合创建角色,通过属性组合自然表达
  • 上下文感知:可以结合时间、地点、设备等环境因素做权限决策,比如检测到异地登录自动降级权限
  • 数据权限天然支持:通过资源属性可以轻松实现"只能查看本大区销售数据"这类行级权限

缺点

  • 配置复杂:属性定义、策略编写、规则组合都需要专业能力,学习曲线陡峭
  • 性能开销:每次访问都需要实时计算多维度属性,对系统性能有影响,缓存策略至关重要
  • 调试困难:权限被拒绝时,需要追溯是哪个属性不匹配导致的,可观测性要求高
  • 策略测试困难:属性组合的排列组合非常多,很难覆盖所有场景,容易出现意料之外的权限结果
  • 理解成本高:相比 ACL 和 RBAC,ABAC 的权限规则不够直观,非技术人员很难理解

适用场景

  • 多租户 SaaS 平台,需要根据租户属性动态控制权限
  • 权限规则复杂、需要条件判断的系统,如"只有工作日工作时间才能访问"
  • 需要动态权限调整的场景,如临时借调、风险自适应
  • 对数据权限有精细化要求的系统,如"只能查看本部门的数据"
  • 云原生环境下的动态权限控制

四、PBAC:基于策略的访问控制——权限即代码

核心思路

PBAC(Policy-Based Access Control)的核心思想是把权限规则写成一段"策略代码",而不是存在数据库里。这些策略代码用专门的声明式语言编写,可以像普通代码一样放进 Git 做版本管理、Code Review、自动化测试。

这么说可能还是有点抽象,我们来对比一下传统方式和 PBAC 方式的区别:

传统方式(权限规则存在数据库):

  • 管理员在后台界面勾选"经理角色可以查看报表"
  • 这条规则存在数据库的权限表里
  • 要改权限?去后台界面重新勾选
  • 谁改的?什么时候改的?之前的规则是什么?——不知道,数据库里没有历史记录

PBAC 方式(权限规则写成代码):

  • 开发者写一段策略代码,提交到 Git
  • Code Review 通过后部署生效
  • 要改权限?修改代码,提交 PR,Review,部署
  • 谁改的?什么时候改的?之前的规则是什么?——Git 里清清楚楚

架构:PDP 和 PEP 是怎么配合的

PBAC 的运行架构分为两个核心组件,它们各司其职:

  • PEP(Policy Enforcement Point,策略执行点):部署在业务服务里,负责拦截用户的请求。它自己不做权限判断,只做一件事——把请求信息打包,发给 PDP 问"这个请求允不允许",然后根据 PDP 的回答执行允许或拒绝
  • PDP(Policy Decision Point,策略决策点):一个独立的策略引擎服务,负责接收 PEP 的查询请求,根据策略代码计算权限结果,返回"允许"或"拒绝"

整个流程如下:

1
2
3
4
5
6
7
8
9
10
11
用户发起请求

PEP(在业务服务中)拦截请求

PEP 把请求信息(谁、做什么、什么资源)发给 PDP

PDP 根据策略代码计算权限

PDP 返回决策结果(允许/拒绝)

PEP 根据结果放行或拒绝请求

为什么要分成 PDP 和 PEP 两个组件?因为决策和执行解耦带来了几个好处:

  1. 所有业务服务共享同一套策略,权限规则一致
  2. 策略变更只需要更新 PDP,不用改业务代码
  3. PDP 可以独立扩展和部署,不影响业务服务

策略代码长什么样

PBAC 使用专门的策略语言来编写权限规则,最常见的是 OPA 的 Rego 语言。下面看一个具体的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 文件:finance_policy.rego
# 作用:定义财务系统的访问策略

package finance

# 默认拒绝所有访问
default allow = false

# 规则1:财务部员工可以查看财务报表
allow {
input.user.department == "财务部"
input.action == "查看"
input.resource.type == "财务报表"
}

# 规则2:财务经理可以审批报销
allow {
input.user.department == "财务部"
input.user.level == "经理"
input.action == "审批"
input.resource.type == "报销单"
}

# 规则3:工作时间才能访问敏感数据
allow {
input.resource.security_level == "敏感"
input.environment.hour >= 9
input.environment.hour <= 18
input.environment.is_weekday == true
}

当 PEP 发来一个查询时,PDP 会把请求信息作为 input 传入,然后逐条评估策略规则。如果某条规则匹配成功,allow 就变为 true

PEP 发给 PDP 的查询请求大概长这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"input": {
"user": {
"department": "财务部",
"level": "经理"
},
"action": "审批",
"resource": {
"type": "报销单",
"security_level": "普通"
},
"environment": {
"hour": 14,
"is_weekday": true
}
}
}

PDP 返回的结果:

1
2
3
{
"result": true
}

策略也可以写测试

PBAC 的一大优势是策略代码可以像普通代码一样写单元测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 文件:finance_policy_test.rego

package finance

# 测试:财务部员工可以查看报表
test_finance_staff_can_view_report {
allow with input as {
"user": {"department": "财务部", "level": "员工"},
"action": "查看",
"resource": {"type": "财务报表", "security_level": "普通"},
"environment": {"hour": 10, "is_weekday": true}
}
}

# 测试:非财务部员工不能查看报表
test_other_dept_cannot_view_report {
not allow with input as {
"user": {"department": "技术部", "level": "员工"},
"action": "查看",
"resource": {"type": "财务报表", "security_level": "普通"},
"environment": {"hour": 10, "is_weekday": true}
}
}

运行测试:opa test . 就能验证策略逻辑是否正确,这在传统权限管理中是很难做到的。

PBAC 与 ABAC 的关键区别

PBAC 和 ABAC 看起来都能做灵活的权限判断,但它们的侧重点不同:

维度 ABAC PBAC
表达形式 属性键值对 + 规则引擎 领域特定语言(DSL)写策略代码
版本控制 存在数据库,难以追溯 Git 管理,完整变更历史
测试能力 黑盒测试 单元测试、策略模拟
复用性 规则与应用耦合 策略独立,可跨服务复用
审计能力 需要额外实现 策略变更可追溯、可回滚

简单来说,ABAC 侧重的是"用什么方式判断权限"(用属性),PBAC 侧重的是"用什么方式管理权限规则"(用代码)。实际上 PBAC 内部完全可以使用 ABAC 的属性判断逻辑,只不过这些逻辑是用策略代码来表达的,而不是散落在数据库或配置文件里。

优点

  • 策略即代码:权限规则像代码一样管理,支持版本控制、Code Review、回滚
  • 可测试:策略可以编写单元测试,确保权限逻辑的正确性
  • 决策与执行解耦:PDP 独立部署,PEP 只负责查询和执行,架构清晰
  • 集中管理:所有策略集中在一个地方,便于统一管控和审计
  • 高性能:可以采用 Sidecar 模式,每个服务本地部署策略引擎,毫秒级响应

缺点

  • 策略抽象门槛高:需要学习策略语言(如 Rego),对开发人员有额外要求
  • 不利于非开发人员维护:策略以代码形式存在,产品经理、运维人员难以直接参与
  • 系统复杂度增加:引入了 PDP、PEP 等额外组件,部署和运维成本上升
  • 过度设计的风险:对于简单的权限需求,PBAC 可能是杀鸡用牛刀

适用场景

  • 多租户系统,需要集中管控权限策略
  • 零信任架构、安全平台
  • 微服务架构下需要统一权限决策的系统
  • 对合规审计要求极高的系统(金融、医疗等)
  • 权限规则需要频繁变更且需要可追溯的场景

五、DAC:自主访问控制——资源所有者说了算

核心思路

DAC(Discretionary Access Control)的核心特点是资源的所有者可以自主决定谁能访问自己的资源,并可以将权限授予他人。"自主"是 DAC 与 ACL 最关键的区别——ACL 只是记录谁可以访问,而 DAC 允许权限的持有者将权限再分配给其他用户。

举个例子:张三创建了一个文档,他可以自主决定让李四也能编辑这个文档,而李四又可以决定让王五也能查看。权限可以像接力一样传递下去。

优点

  • 灵活性高:资源所有者可以随时调整权限,无需管理员介入
  • 用户理解成本低:逻辑简单,"我的东西我决定谁能用"
  • 授权便捷:适合需要频繁共享和协作的场景

缺点

  • 无集中管控:权限分散在各个资源所有者手中,管理员难以全局管控
  • 易误授权:权限可以传递,可能导致权限扩散到不可控的范围
  • 安全风险高:一旦某个用户的账号被盗,攻击者可以访问该用户拥有的所有资源,并进一步扩散权限
  • 审计困难:权限变更分散,难以追踪完整的权限变更链路

适用场景

  • 文件共享系统(如百度网盘的文件分享)
  • 操作系统文件层权限(Linux 文件系统的 owner 机制就是 DAC 的实现)
  • 协作平台中的个人资源管理
  • 对安全性要求不高、强调便捷共享的场景

六、MAC:强制访问控制——安全至上的铁律

核心思路

MAC(Mandatory Access Control)是最严格的权限模型,系统对资源和用户打上安全标签,权限强制遵守安全等级策略,任何个人都无法修改。权限决策完全由系统规则驱动,不依赖用户的主观判断。

MAC 的核心机制是安全级别:每个用户有一个安全许可级别(如绝密、机密、秘密、公开),每个资源也有一个安全分类级别。系统根据两条铁律强制执行访问控制:

  • 向下读(No Read Up):用户只能读取安全级别等于或低于自己许可级别的资源。也就是说,你不能读取比你许可级别更高的东西
  • 向上写(No Write Down):用户只能写入安全级别等于或高于自己许可级别的资源。也就是说,你不能往比你许可级别更低的地方写东西

为什么要这样设计? 这两条规则是为了防止两种信息泄露方式:

  1. **"向下读"防止的是"越级窥探"**:如果一个"秘密"级别的用户能读取"绝密"文件,那机密信息就泄露了。所以必须禁止低级别用户读取高级别资源
  2. **"向上写"防止的是"故意泄密"**:这是很多人容易忽略的一点。如果一个"绝密"级别的用户能把内容写到"公开"级别的文件里,那他就可以把绝密信息复制到公开文件中,相当于把机密信息"降级"泄露出去。所以必须禁止高级别用户往低级别资源写东西

用一个具体的例子来说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
安全级别从高到低:绝密 > 机密 > 秘密 > 公开

用户张三,安全许可级别:机密

读取权限:
✅ 可以读取"公开"文件 —— 级别低于自己,允许
✅ 可以读取"秘密"文件 —— 级别低于自己,允许
✅ 可以读取"机密"文件 —— 级别等于自己,允许
❌ 不能读取"绝密"文件 —— 级别高于自己,禁止(防止越级窥探)

写入权限:
❌ 不能写入"公开"文件 —— 级别低于自己,禁止(防止把机密信息写到公开地方泄密)
❌ 不能写入"秘密"文件 —— 级别低于自己,禁止(同上)
✅ 可以写入"机密"文件 —— 级别等于自己,允许
✅ 可以写入"绝密"文件 —— 级别高于自己,允许(往更高级别写是安全的)

这样一来,信息只能"向上流动"(从低级别到高级别),永远不能"向下流动"(从高级别到低级别),从而保证了机密信息不会泄露到低安全等级的区域。

优点

  • 安全性极高:权限由系统强制执行,不存在误授权或权限扩散的风险
  • 不依赖用户行为:即使资源所有者也无法修改权限规则,杜绝了人为失误
  • 符合合规要求:军事、政府等高安全等级环境的标准要求

缺点

  • 灵活性极差:安全等级和规则一旦设定就很难调整,无法适应快速变化的业务需求
  • 不适用于业务系统:绝大多数业务系统需要灵活的权限管理,MAC 的刚性约束会严重阻碍业务
  • 管理复杂:安全标签的维护和分级需要专业人员,成本高
  • 用户体验差:严格的限制可能导致正常工作流程受阻

适用场景

  • 军事系统、政府机密系统
  • 金融核心平台(交易系统、清算系统)
  • 对安全性要求极高、可以牺牲灵活性的场景
  • 需要满足特定安全合规标准(如等保四级以上)的系统

模型对比速览

模型 控制方式 粒度 灵活性 管理难度 典型场景
ACL 资源挂权限清单 极细 高(规模大时) 文档协作、小型系统
RBAC 角色分权 中等 企业后台、ERP/HR
ABAC 属性组合判断 细粒度 极高 SaaS 动态权限、云平台
PBAC 策略语言 任意 极高 极高 零信任、合规系统
DAC 所有者自主控制 简单 文件系统、共享平台
MAC 安全标签强制 粗粒度 军事、政府、金融核心

混合模型实践

在实际项目中,单一模型往往难以满足所有需求,组合使用才是更常见的做法:

RBAC + ACL

用 RBAC 管理基础权限结构(角色分配),用 ACL 处理个别资源的精细化授权。比如:大部分权限通过角色管理,但某个敏感文档需要单独控制谁能访问,就用 ACL 在该资源上做例外处理。

这是最常见的组合方式,很多框架(如 Spring Security)天然支持这种模式。

RBAC + ABAC

用 RBAC 分配基础权限(角色决定能访问哪些模块),用 ABAC 控制动态限制(属性决定在什么条件下可以访问)。比如:"经理角色可以查看报表"是 RBAC,"但只有工作日工作时间从内网访问时才能查看"是 ABAC。

这种组合既保留了 RBAC 的管理简便性,又获得了 ABAC 的动态灵活性,是当前企业系统的主流趋势。

PBAC + ABAC + RBAC

在大型中台或多租户系统中,用 PBAC 作为统一的策略管理层,RBAC 管理基础角色结构,ABAC 处理动态属性判断。策略引擎(如 OPA、Casbin)作为 PDP 统一决策,各服务作为 PEP 执行。

这种组合适合架构复杂、权限需求多变的大型系统,但引入的复杂度也很高,需要团队有足够的技术能力来驾驭。


选型建议

最后,给一个简化的选型思路:

  • 系统角色稳定、权限变化不多 → 选 RBAC
  • 有资源级差异访问需求 → RBAC + ACL
  • 需要动态/条件型权限 → 引入 ABAC
  • 需要集中可审计的策略管理 → 上 PBAC
  • 强调便捷共享、用户自主 → DAC
  • 安全等级要求极高 → MAC
  • 业务复杂、单一模型不够用 → 混合模型

没有完美的权限模型,只有适合当前阶段的权限模型。选型的时候想清楚三件事就行:你的系统有多复杂、你的团队有多大精力管权限、你对安全性的要求有多高。系统简单就别搞太复杂,用 RBAC 就够了;系统复杂了也别硬撑,该上 ABAC 就上。核心原则就一句话——够用就好,别过度设计,也别欠设计