3、Lakehouse授权模型:RBAC、ABAC与细粒度权限

授权模型这东西,说白了就是「谁能在什么条件下对什么东西做什么」。我在不同公司见过五花八门的实现,有的简单粗暴,有的复杂到连管理员自己都搞不清。今天咱们就把 Lakehouse 里最主流的几种授权模型捋一遍。

3.1 RBAC:基于角色的访问控制

RBAC 是最经典的模式。你把权限打包成「角色」,然后把角色分配给用户。用户不直接跟权限打交道,只跟角色打交道。

核心思想:用户 → 角色 → 权限

举个例子。我在一个金融客户的项目里,他们定义了这么几个角色:

角色 可读表 可写表 可执行操作
数据分析师 ods.*, dwd.* ads.* SELECT, CREATE TEMP VIEW
数据工程师 ods.*, dwd.*, ads.* ods.*, dwd.* SELECT, INSERT, ALTER, DROP
安全审计员 全部 无 SELECT, SHOW
管理员 全部 全部 ALL PRIVILEGES

RBAC 的好处是管理简单。新人入职,直接挂个角色就行。但问题也很明显——它不够灵活。比如「只允许查看 2024 年之后的数据」,RBAC 就搞不定,你得单独建个视图或者新表。

我的习惯:RBAC 适合做粗粒度管控,比如库级别、表级别。别用它做行级或列级控制,否则角色数量会爆炸。

3.2 ABAC:基于属性的访问控制

ABAC 就灵活多了。它不看「你是谁」,而是看「你的属性 + 资源的属性 + 环境属性」是否满足策略。

属性通常分三类:

  • 用户属性:部门、职级、区域、项目组
  • 资源属性:表名、分区时间、数据敏感等级、列名
  • 环境属性:访问时间、IP 地址、客户端工具

举个例子,一条 ABAC 策略可以写成:

允许 SELECT 当:
  用户.部门 = '风控' AND
  表.敏感等级 <= 'L2' AND
  当前时间 BETWEEN '09:00' AND '18:00'

我曾经帮一个电商客户搭过这套。他们的需求是:运营人员只能看自己负责品类的订单数据,而且不能看金额列。用 RBAC 得建几十个角色,用 ABAC 一条策略就搞定了。

注意:ABAC 虽然灵活,但性能开销大。每次查询都要评估策略,如果策略数量上千,会影响查询延迟。我建议把 ABAC 用在关键敏感数据上,普通数据用 RBAC 就够了。

3.3 细粒度权限:行级、列级、文件级

细粒度权限是 Lakehouse 的硬门槛。传统数仓很少做到行级,但 Lakehouse 因为底层是文件 + 元数据,反而更容易实现。

3.3.1 行级权限

行级权限就是「同一张表,不同人看到不同的行」。实现方式主要有两种:

  • 视图过滤:为每个角色创建带 WHERE 条件的视图
  • 行过滤器:直接在表上挂载过滤策略(如 Spark 的 Row Filter)

比如在 Apache Ranger 里,你可以这样配:

-- 只允许查看自己所在区域的数据
CREATE ROW FILTER region_filter ON sales
  USING (region = current_user_region())

3.3.2 列级权限

列级权限更常见。比如「客服能看到用户姓名,但不能看手机号」。实现方式:

  • 列掩码:显示部分内容,如 138****1234
  • 列拒绝:直接隐藏整列,查询时报错或返回 NULL

我记得有个医疗项目,要求「医生能看到完整病历,护士只能看到诊断摘要」。我们用列掩码 + 角色判断,一行配置就解决了。

3.3.3 文件级权限

文件级权限是 Lakehouse 的特色。因为数据存在 Parquet/ORC 文件里,你可以直接控制某个分区目录的访问。

比如在 Delta Lake 中,分区就是目录:

/data/sales/year=2024/month=01/
/data/sales/year=2024/month=02/

你可以在文件系统层面(如 S3 Bucket Policy)或元数据层面(如 Hive Metastore 权限)控制谁可以读某个分区目录。

避坑指南:我曾经遇到一个案例,文件级权限和表级权限冲突了。表级允许读,但文件级拒绝了,结果查询报「权限不足」。后来我们统一用元数据层做权限,文件系统只做物理隔离,不再做逻辑控制。

3.4 权限继承与覆盖规则

权限多了就会打架。Lakehouse 里常见的规则是:

  • 显式拒绝优先:只要有 DENY,就拒绝
  • 显式允许次之:没有 DENY 但有 ALLOW,就允许
  • 继承默认拒绝:什么都没配,默认拒绝

用表格表示就是:

父级权限 子级权限 最终结果
ALLOW 未配置 ALLOW(继承)
ALLOW DENY DENY(拒绝优先)
DENY ALLOW DENY(拒绝优先)
未配置 ALLOW ALLOW

嗯,这里要注意:不同引擎的实现有细微差别。比如 Spark 的 ACL 是「拒绝优先」,而 Hive 的旧版是「允许优先」。我建议你在做权限设计时,统一用「拒绝优先」策略,这样更安全。

3.5 三种模型的选型建议

说了这么多,到底怎么选?我个人的经验是:

  • 小团队(<50人):只用 RBAC,简单够用
  • 中型团队(50-500人):RBAC + 列级权限,必要时加行级
  • 大型组织(500人+):RBAC 做基础,ABAC 做精细化控制,细粒度权限做兜底

你想想看,如果一开始就上 ABAC,策略写起来爽,但维护成本高。我见过一个公司配了 2000 多条 ABAC 策略,最后没人敢改,因为不知道改了会影响谁。

核心原则:能用 RBAC 解决的,别上 ABAC。能用表级解决的,别上行列级。权限粒度越细,管理成本越高。

3.6 授权模型整体架构图

下面这张图展示了 Lakehouse 授权模型的整体关系。你可以看到用户、角色、属性、策略和资源之间的流转路径。

Lakehouse 授权模型架构 用户 角色 (RBAC) 属性 (ABAC) 策略引擎 拒绝优先 / 继承 表 / 视图 行 / 列 / 文件 分区 / 目录 分配 携带 权限评估流程 1. 用户携带角色 + 属性 2. 策略引擎匹配策略 3. 拒绝优先 → 允许 → 继承默认拒绝

从图里可以看得很清楚:用户通过角色(RBAC)和属性(ABAC)两条路径进入策略引擎,引擎按「拒绝优先」规则评估后,决定用户对表、行列、文件分区的访问权限。这就是 Lakehouse 授权模型的完整链路。