从 ACL 到零信任:权限系统设计模式的演进之路

从 ACL 到零信任:权限系统设计模式的演进之路

从最朴素的"谁对什么有权限",到最复杂的"从不信任,始终验证",权限系统的演进不仅仅是技术的升级,更是安全思维的五次跃迁。

一、全景路线图

arduino 复制代码
ACL          →  RBAC        →  ABAC         →  ReBAC       →  Zero Trust
"谁对什么     "谁能做什么"      "在什么条件下      "因为你和它      "永远不信任
 有什么权限"   (角色)          谁能做什么"       有关系所以        每次都验证"
 (枚举)                       (策略)           能做什么"
                                               (关系)
  ~~~~         ~~~~           ~~~~             ~~~~            ~~~~
 朴素信任       组织信任        条件信任          关系信任         零信任

二、四大核心权限模型

1. ACL(Access Control List)访问控制列表

核心思想 :以资源为中心。每个资源绑定一个列表,明确记录"谁"对"它"有"什么权限"。

css 复制代码
文件A → 张三[读]、李四[读写]
文件B → 张三[读写]、王五[读]
文件C → 李四[读]、王五[读写]
  • 优点:概念直观,实现简单,非常适合细粒度的资源级别控制
  • 缺点:用户和资源规模扩大后,维护成本呈指数级上升("权限地狱")
  • 典型场景:操作系统文件权限(Linux/Windows)、简单的文档管理系统

2. RBAC(Role-Based Access Control)基于角色的访问控制

核心思想 :以角色为桥梁。权限赋予角色,用户通过角色获得权限。

复制代码
用户 → 角色 → 权限 → 资源/操作
  • 优点:高度契合企业组织架构,管理成本大幅降低。新员工入职只需分配角色,离职只需回收角色
  • 缺点:复杂场景下会出现"角色爆炸",缺乏上下文感知能力
  • 典型场景:绝大多数企业级 SaaS 应用、ERP/CRM 系统、后台管理系统

3. ABAC(Attribute-Based Access Control)基于属性的访问控制

核心思想 :以策略为中心。通过评估四个维度的属性动态计算是否放行:

维度 举例
主体属性 用户部门、职级、标签
资源属性 文件密级、类型、所有者
环境属性 时间、IP、设备、地理位置
操作属性 读、写、删除、导出
sql 复制代码
示例策略:
IF User.部门 == '财务部'
   AND Resource.密级 == '机密'
   AND Environment.时间 BETWEEN '工作日9:00-18:00'
   AND Environment.IP IN 内网段
THEN Allow
  • 优点:极度灵活、细粒度,支持上下文感知,策略与代码解耦
  • 缺点:前期设计和规则梳理复杂度高,策略引擎有一定性能开销
  • 典型场景:AWS IAM、零信任架构、金融/医疗系统

4. ReBAC(Relationship-Based Access Control)基于关系的访问控制

核心思想 :基于实体之间的图关系来决定权限,源自 Google Zanzibar 论文。

markdown 复制代码
我能编辑这个文档
  ← 我是这个文件夹的编辑者
    ← 这个文件夹属于我的团队
      ← 团队负责人共享给了我

权限 = 在关系图中是否存在一条允许的路径
  • 优点:天然支持复杂的层级继承和协同场景,权限可沿关系链传递
  • 缺点:需要图数据库或专用引擎,建模复杂度较高
  • 典型场景:飞书/Notion 文档协作、社交媒体、网盘共享
  • 代表技术:OpenFGA、SpiceDB

横向对比

维度 ACL RBAC ABAC ReBAC
控制核心 资源 角色 属性/策略 图关系
粒度 资源级 功能/菜单级 数据行/列级 资源级
灵活性 低(静态绑定) 中(静态分配) 极高(动态计算) 高(图遍历)
管理复杂度 规模大时极高 中等 初期高,后期好 依赖图模型
适用规模 小型系统 中大型企业 超大型/云原生 协同办公平台

三、RBAC 的两大痛点深入解析

RBAC 是中流砥柱,解决了 80% 的企业级管理诉求,但它有两个著名的痛点。

痛点一:角色爆炸(Role Explosion)

本质

静态的枚举(角色)去硬编码动态的多维组合,导致角色数量以笛卡尔积方式失控增长。

实例:医院电子病历系统

初始状态(3 个角色就够了):

复制代码
医生、护士、管理员

引入业务维度后,安全部门要求细粒度管控:

维度 取值
科室 内科、外科、儿科
职级 主任医师、主治医师、住院医生
数据范围 全院、本科室、本病区

于是管理员开始"捏角色":

erlang 复制代码
内科_主任医师_全院数据
内科_主任医师_本科室数据
内科_主治医师_本科室数据
外科_住院医生_本病区数据
...

仅 3 个维度 → 3 × 3 × 3 = 27 个角色

再加院区(3个)和项目(2个)→ 27 × 3 × 2 = 162 个角色

如果有 50 个细分病区 → 角色数突破数千个 💥

爆炸的四个成因
成因 说明
多维正交组合 权限取决于"你是谁 + 你在哪 + 你做什么 + 什么时间",强行枚举必然爆炸
缺乏继承机制 没有使用分层 RBAC,管理员直接复制基础角色改两三个权限,产生大量"克隆角色"
用角色代替策略 把数据过滤条件硬编码成角色(如 北京区_销售经理),而不是抽象为数据权限策略
业务定制诉求 各部门要求"特例角色"(如"周末能看财务的临时审计员"),边缘角色越积越多
爆炸后的危害
  • 管理失控:新员工入职面对几百个角色,根本不知道分配哪个
  • 审计灾难:查"谁能删除数据库"需要遍历几百个角色,极易遗漏
  • 权限冗余:废弃角色堆积,潜伏高危权限,甚至出现违反职责分离(SoD)的"毒性组合"
  • 性能下降:登录时加载用户所有角色权限集,关联关系过多导致鉴权接口超时
解决方案

核心思路:分离功能权限和数据权限

复制代码
功能权限(能不能做)→ 角色控制(按钮/菜单级别)
数据权限(能看哪些)→ 属性/策略控制(数据行/列级别)

用 ABAC 方式替代:不创建 北京区_高级_销售经理,只保留 销售经理,由策略引擎动态判断:

ini 复制代码
IF User.Region == Resource.Region AND User.Level == 'Senior' THEN Allow

无论维度增加多少,角色数量始终保持在基础水平,复杂性转移到了策略引擎。

其他缓解措施:

  • 分层 RBAC(RBAC1):利用角色继承减少重复配置
  • 角色工程(Role Mining):算法分析实际权限集合,合并相似用户群为标准角色
  • 生命周期管理:角色与组织架构绑定,入职自动分配,转岗自动回收

痛点二:缺乏上下文感知能力

本质

RBAC 是静态绑定的:角色一旦分配,权限就固定了,无论上下文怎么变,权限都不会自动调整。

实例
css 复制代码
张医生 = [医生] 角色

→ 上午 10 点,医院内网,查看自己负责的患者 → ✅ 允许
→ 凌晨 2 点,家庭公网,查看无关患者病历     → ✅ 仍然允许!

RBAC 只看"你是不是医生",不看:

  • 时间 --- 是否工作时间?
  • 地点 --- 内网还是公共 WiFi?
  • 关系 --- 是不是你的病人?
  • 设备 --- 是否安装了安全证书?
  • 行为 --- 是否异常操作?
这带来的现实问题
场景 RBAC 的困境
零信任架构 零信任要求"持续验证每一次请求",RBAC 只能做一次性静态鉴权
远程办公 在家/在咖啡厅/在公司,权限应该不同,但 RBAC 一视同仁
敏感操作 删除数据库应要求"内网 + 工作时间 + MFA 通过",RBAC 做不到
跨部门协作 "临时允许市场部小王本周查看产品部文档",RBAC 无法动态控制
解决方案
方案 思路
ABAC 策略引擎 每次请求实时评估用户属性 + 资源属性 + 环境属性
OPA(Open Policy Agent) 策略即代码,支持复杂的环境上下文判断
ReBAC(关系型) 基于实体间图关系判断("你是不是这个文档的协作者")
自适应授权 实时风险评分,动态调整权限(如 Okta Adaptive MFA)

实际落地的混合方案

很多成熟系统采用 "RBAC 为骨架 + ABAC 为血肉" 的混合架构:

sql 复制代码
┌──────────────────────────────────────────────────────┐
│                     鉴权决策层                         │
│                                                       │
│  第一层:RBAC   →  用户是否拥有该功能角色?              │
│                    (菜单/按钮级,静态,快)              │
│                                                       │
│  第二层:ABAC   →  当前上下文是否满足策略条件?           │
│                    (时间/IP/设备/关系,动态,细粒度)    │
│                                                       │
│  第三层:数据过滤 → SQL 注入 WHERE 条件                │
│                    (行/列级数据隔离)                   │
└──────────────────────────────────────────────────────┘

四、零信任架构深入解析

从"城堡护城河"到"零信任"

传统模型的问题

传统安全基于"城堡与护城河"范式 --- 防火墙以内被视为安全区域,一旦突破边界,内部资源几乎不受限制:

复制代码
┌──────────────────────────────────────────┐
│            互联网(不可信)                │
│                                          │
│        ╔═══════════════════╗             │
│        ║   防火墙(护城河)  ║             │
│        ╚═══════════════════╝             │
│                                          │
│        ┌───────────────────┐             │
│        │   内网(完全可信)   │             │
│        │                   │             │
│        │ 一旦进来,畅通无阻   │             │
│        │ ↗ 横向移动无限制    │             │
│        └───────────────────┘             │
└──────────────────────────────────────────┘

这种模型已经失效

挑战 说明
云和远程办公 企业网络边界模糊化,员工可以在任何地方办公
内部威胁 约 43% 的安全事件源自内部,防火墙挡不住"自己人"
移动/IoT 设备 大量不受控设备接入网络
横向移动 攻击者一旦突破边界,就可以在内网自由移动
零信任的核心信条
dart 复制代码
❌ 传统: "内网 = 可信,外网 = 不可信"
✅ 零信任: "从不信任,始终验证" (Never Trust, Always Verify)

NIST 定义的三大核心原则

根据 NIST SP 800-207 标准:

原则 说明
始终验证 每次访问请求都要认证+授权,不做任何"免检"假设
最小权限 只授予完成任务所需的最低限度权限,遵循 JIT(即时授权)和 JEA(适度授权)
假设失陷 假设网络中已经存在威胁,通过微隔离限制横向移动

补充机制:

  • 持续验证 --- 信任不是一次性的,整个会话期间持续评估
  • 动态授权 --- 基于实时上下文动态调整权限
  • 微隔离 --- 将网络切分为细粒度区域,封锁横向移动路径

架构组件

scss 复制代码
┌─────────────────────────────────────────────────────┐
│                                                     │
│                   策略引擎(PE)                      │
│             Policy Engine --- 决策大脑                  │
│  收集身份、设备、上下文 → 计算信任分数 → 做出访问决策    │
│                                                     │
└──────────────────────┬──────────────────────────────┘
                       │ 访问决策 (Allow / Deny / Step-up)
                       ▼
┌─────────────────────────────────────────────────────┐
│                                                     │
│                 策略执行点(PEP)                      │
│          Policy Enforcement Point                   │
│     在网络连接中实际执行策略,控制数据流                  │
│     (API网关、反向代理、微隔离模块)                    │
│                                                     │
└──────────┬──────────────────────────────┬───────────┘
           │                              │
     ┌─────▼─────┐                  ┌─────▼─────┐
     │   用户     │   ←── 访问 ──→  │  应用/资源  │
     │ (Subject)  │                  │ (Resource) │
     └───────────┘                  └───────────┘

     辅助组件:
     ┌────────────┐ ┌────────────┐ ┌────────────┐
     │ 身份提供者  │ │ 威胁情报源  │ │ 日志/监控   │
     │   (IdP)    │ │            │ │  (SIEM)    │
     └────────────┘ └────────────┘ └────────────┘
组件 角色 类比
策略引擎(PE) 决策大脑,评估请求并做出访问决策 保安队长
策略执行点(PEP) 在网络层实施访问控制 门口的闸机
身份提供者(IdP) 管理用户/设备身份,提供认证(SAML/OIDC) 身份证发放机构
威胁情报源 提供外部安全威胁信息 公安通缉令
SIEM 收集所有访问日志,分析和告警 监控中心

信任评估模型 --- 零信任的"灵魂"

零信任引入了**信任分数(Trust Score)**机制,动态计算访问主体的可信度:

ini 复制代码
Trust Score = f(身份置信度, 设备安全状态, 网络环境, 行为基线, 威胁情报)

实际场景示例

yaml 复制代码
张工访问财务系统:

  上午 10 点,公司内网,公司笔记本,正常操作模式
  → Trust Score: 92/100 → ✅ 完全访问

  凌晨 2 点,家庭WiFi,个人手机,从未有过此类访问
  → Trust Score: 35/100 → ❌ 拒绝访问 / 要求额外验证

  上午 11 点,咖啡厅WiFi,公司笔记本
  → Trust Score: 65/100 → ⚠️ 降级权限,仅允许只读

决策矩阵

分数区间 处置方式
≥ 80 分 完全访问权限
50 ~ 79 分 受限访问 / 要求 MFA
< 50 分 拒绝访问 / 要求重新认证

典型访问请求流程

markdown 复制代码
用户发起访问请求
      │
      ▼
 ① PEP 拦截请求
      │
      ▼
 ② PE 收集上下文信息
    ├── 身份认证(MFA 多因素)
    ├── 设备健康检查(补丁版本、杀毒软件状态)
    ├── 地理位置 / 网络环境评估
    └── 行为基线比对(是否异常)
      │
      ▼
 ③ PE 做出访问决策
    ├── ✅ 授予访问   → PEP 放行
    ├── ❌ 拒绝访问   → PEP 阻断
    └── ⚠️ 条件授权   → 降级权限 / 要求额外验证
      │
      ▼
 ④ 持续监控会话(不是一次性的!)
    ├── 行为异常检测
    ├── 设备状态变化监控
    └── 动态调整权限(随时可以收紧或放开)

关键差异:传统模型在第 ① 步就结束了(一次性认证),零信任的第 ④ 步是持续进行的。

零信任与权限模型的关系

零信任不是一个独立的权限模型,而是一个安全架构框架,它需要组合使用多种权限模型:

复制代码
┌─────────────────────────────────────────────────────┐
│                   零信任架构                          │
│                                                      │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐           │
│  │  RBAC    │  │  ABAC    │  │  ReBAC   │           │
│  │ 基础角色  │+│ 动态策略  │+│ 关系判断  │           │
│  │ 功能权限  │  │ 上下文   │  │ 资源协作  │           │
│  └──────────┘  └──────────┘  └──────────┘           │
│                                                      │
│  + 信任分数评估 + 持续验证 + 微隔离                     │
└─────────────────────────────────────────────────────┘
权限模型 在零信任中的角色
功能权限 RBAC 用户是否拥有该角色的基本访问权
动态策略 ABAC 当前上下文(时间/设备/IP)是否满足条件
资源关系 ReBAC 用户与资源之间是否存在允许访问的关系
信任评估 零信任独有 综合信任分数是否达标

传统模型 vs 零信任

维度 传统模型 零信任
信任假设 内网可信 永不信任
防御边界 网络边界(防火墙) 每个资源/身份
访问控制 基于网络位置 基于身份 + 上下文
权限粒度 粗粒度(网段级) 细粒度(应用/数据级)
验证频率 一次性认证 持续验证
横向移动 容易(边界内畅通) 困难(微隔离)

实施路径(渐进式)

零信任不是一蹴而就的,通常分五个阶段推进:

复制代码
阶段一:身份管理
  → 部署 MFA、统一身份管理(IAM)、SSO

阶段二:设备安全
  → 设备健康评估、终端安全代理

阶段三:网络微隔离
  → 细分网络区域、限制东西向流量

阶段四:应用与数据安全
  → 应用级访问控制、数据加密与分类

阶段五:持续监控与优化
  → SOC 安全运营中心、策略持续优化

五、从 ACL 到零信任:五次思维跃迁

权限系统的演进不仅仅是技术升级,更是思维方式的根本转变

第一次跃迁:ACL → RBAC --- 从枚举到抽象

核心问题:用户和权限越来越多,一条条配置配不过来了。

css 复制代码
ACL 的思维:
  文件A → 张三[读]、李四[读写]
  文件B → 张三[读写]、王五[读]
  ... 几百个文件,几千个用户 → 灾难

RBAC 的思维:
  管理者 → 赋予 [读/写/删] 权限
  张三 = 管理者  → 自动拥有 读/写/删

转变:不再逐个列举,而是找到共性归类。用"角色"这个中间层,把 M×N 的网状关系简化为树状结构。

scss 复制代码
之前:User × Permission 的网状关系(O(m×n))
之后:User → Role → Permission 的链式关系(O(m+n))

本质:管理复杂度的优化 --- 解决"怎么管好"的管理学问题。

第二次跃迁:RBAC → ABAC --- 从枚举身份到描述属性

核心问题:角色越来越多,已经"爆炸"了。

vbnet 复制代码
RBAC 的困境:
  "北京区的销售经理只能看北京的订单" → 角色:北京区销售经理
  "上海的也要看" → 再加:上海区销售经理
  "高级经理能看全部" → 再加:高级_北京区销售经理...
  → 💥

ABAC 的思路:
  不创建角色,写一条策略:
  IF User.Region == Order.Region THEN Allow
  → 一条策略覆盖所有情况

转变:不再问"你是什么角色",而是问"你具有什么特征"。权限不再提前分配好,而是在每次访问时实时计算。

本质:表达能力的跃迁 --- 用有限数量的策略规则覆盖无限数量的场景。

第三次跃迁:ABAC → ReBAC --- 从个体特征到关系网络

核心问题:ABAC 擅长描述"属性",但不擅长描述"关系"。

css 复制代码
ABAC 的困境:
  "我能编辑这个文档" --- 为什么?
  → 因为我是这个文件夹的编辑者
  → 因为这个文件夹属于我的团队
  → 因为团队负责人把这个文件夹共享给了我
  这种"层层传递"的关系链,用 ABAC 描述非常笨拙。

ReBAC 的思路:
  直接建模关系图:
  User →[是编辑者]→ Folder →[属于]→ Team →[包含]→ Document
  权限 = 在关系图中是否存在一条允许的路径

转变:权限不仅取决于"你是谁",更取决于"你和资源之间的社会关系"。权限决策从一次查表变成了一次图搜索,且权限可以沿关系链传递。

本质:建模维度的扩展 --- 引入了"关系"这个被长期忽略的维度。

第四次跃迁:从权限模型 → 零信任架构 --- 从静态信任到持续验证

核心问题:前面所有模型都隐含一个假设 --- "信任是稳定的"。

arduino 复制代码
传统模型的隐含假设:
  登录时验证身份 → ✅ 通过 → 获得权限 → 之后一路畅通

  问题:
  - 登录的是合法用户,但后来设备中了病毒呢?
  - 用户从公司内网切到了咖啡厅 WiFi 呢?
  - 用户的行为模式突然变了(凌晨3点批量下载)呢?

零信任的思路:
  登录时验证 → ✅ → 每5秒/每次请求都在验证 → 随时收紧或切断

  信任不是"开关",而是"水龙头" --- 可以实时调节大小

转变

维度 之前 之后
信任模型 二元(信任/不信任) 连续(信任分数)
防御策略 边界防御(坚固外壳) 纵深防御(层层检查)
授权方式 静态(一次性事件) 动态(持续过程)
关注焦点 你是谁 你正在做什么

本质:信任哲学的根本转变 --- 不再假设"管好了就安全",而是假设"随时可能被攻破"。

五条演进主线

维度 演进方向 一句话概括
信任模型 朴素信任 → 组织信任 → 条件信任 → 关系信任 → 零信任 信任越来越"不信任"
控制粒度 资源级 → 角色级 → 属性级 → 关系级 → 请求级 从"粗管"到"微操"
时间维度 一次性 → 一次性 → 每次请求 → 每次请求 → 整个会话 从"一次验证"到"持续验证"
决策方式 查表 → 查表 → 策略计算 → 图遍历 → 综合评估 从静态到动态,从离散到连续
建模对象 资源 → 人 → 属性 → 关系 → 上下文 关注的维度越来越多

最深层的思维转变

如果用一句话概括整个演进的本质:

从"管理复杂性"到"对抗不确定性"

复制代码
第一层(ACL/RBAC):如何高效地分配权限?  ← 管理学问题
第二层(ABAC/ReBAC):如何精确地描述权限?  ← 建模问题
第三层(Zero Trust):如何假设一切都不安全? ← 哲学问题

六、选型建议速查

项目类型 推荐方案 理由
初创项目 / 简单后台 RBAC 开发成本最低,能快速满足"不同岗位看不同菜单"的需求
多租户 SaaS RBAC + 数据权限过滤 RBAC 管功能菜单,SQL 拦截器注入 WHERE tenant_id = ? 做数据隔离
协同办公 / 知识库 RBAC(系统级)+ ReBAC(资源级) 系统管理用 RBAC,文档共享/继承/协作用 ReBAC
零信任 / 云原生平台 ABAC(结合 OPA 策略引擎) 结合设备环境、用户行为、资源标签做动态风控
大型政企 RBAC + ABAC + 零信任 分阶段实施,渐进式演进

七、总结

权限系统的演进是一部"信任不断被质疑"的历史:

  • ACL 回答了"谁能访问什么",但管不过来
  • RBAC 用角色解决了管理效率问题,但角色会爆炸
  • ABAC 用策略解决了灵活性和上下文感知,但设计复杂
  • ReBAC 用关系图解决了协作和继承问题,但需要专用引擎
  • 零信任 把一切归零 --- 不信任任何人,每次都验证,持续监控

没有银弹,只有权衡。 实际落地中,通常是多种模型的组合拳:RBAC 做骨架保证开发效率,ABAC 做血肉保证灵活性,零信任做免疫系统保证安全底线。

选型的终极原则:不是选最先进的,而是选最适合当前业务阶段的。


参考资料:NIST SP 800-207《零信任架构》、NIST SP 800-162《基于属性的访问控制指南》、Google Zanzibar 论文、Forrester ZTX 框架

相关推荐
heimeiyingwang1 小时前
【架构实战】网关架构设计:微服务的统一入口
微服务·云原生·架构
真实的菜1 小时前
微服务架构痛点
java·微服务·架构
MicrosoftReactor2 小时前
技术速递|以 Token 经济学驱动的架构:混合模型、AI Runway、AKS Kata MicroVM 与 MCP
人工智能·ai·架构·copilot·mcp
MemoriKu2 小时前
Flutter 相册 APP 视频模态稳定化实战:从视频抽帧、Embedding 元数据到 Android 真机启动修复
android·开发语言·前端·flutter·架构·音视频·embedding
百珏2 小时前
流量没暴涨,网关却挂了:Spring Cloud Gateway 从 500 QPS 优化到 4200 QPS
后端·spring cloud·架构
程序员二叉2 小时前
【JVM】类加载全过程&双亲委派机制深度解析
java·jvm·面试
ai产品老杨2 小时前
【架构深评】基于 Docker 与 边缘计算,如何打通 GB28181/RTSP 与 X86/ARM 异构算力的企业级 AI 视频流网关?(附源码交付)
人工智能·docker·架构
咖啡八杯2 小时前
GoF设计模式——桥接模式
面试·架构
小林ixn2 小时前
前端必知:JS同步异步与Promise,终于有人讲明白了!
javascript·面试