权限体系基础:访问控制模型、粒度与授权模型
聊权限之前,我先问一个问题:你凭什么能看这条数据?
这个问题看似简单,但落到湖仓一体里,答案会变得很复杂。我见过不少团队,一开始只做了表级权限,结果业务部门投诉说“我能看这个表,但里面有些列是工资信息,不该我看啊”。嗯,这就是粒度没想清楚。
这一章,我们把权限体系的基础打牢。我会从三个维度展开:访问控制模型、权限粒度、授权模型。这三块是后面所有行列权限设计的根基。
访问控制模型:四种主流模式
访问控制模型,说白了就是“谁用什么方式访问什么资源”。业界有四种经典模型,我按出现的先后顺序讲。
| 模型 | 全称 | 核心思想 | 典型场景 |
|---|---|---|---|
| DAC | 自主访问控制 | 资源所有者自己决定谁可以访问 | Linux文件权限、个人网盘 |
| MAC | 强制访问控制 | 系统根据安全标签强制控制 | 军事系统、政府机密数据 |
| RBAC | 基于角色的访问控制 | 权限赋予角色,角色赋予用户 | 企业ERP、数据仓库 |
| ABAC | 基于属性的访问控制 | 根据用户/资源/环境属性动态判断 | 湖仓一体行列权限、微服务 |
DAC:最原始,也最灵活
DAC 就是“我的东西我做主”。你创建了一张表,你可以决定谁能读、谁能写。Linux 的 chmod 就是典型例子。
但 DAC 有个大问题:权限会扩散。比如 A 给了 B 权限,B 又转给了 C,最后你根本不知道谁在访问你的数据。我在项目中遇到过,一个业务部门把表权限通过 DAC 层层转发,最后审计时发现 200 多个账号都有访问权,但只有 30 个人是真正需要的。
MAC:最严格,但最不灵活
MAC 是系统说了算。每个用户和每个数据都有安全标签(比如“绝密”“机密”“公开”),系统强制匹配。用户不能改变标签,也不能传递权限。
我记得在金融行业做项目时,监管要求某些交易数据必须用 MAC 模型。好处是安全等级非常清晰,坏处是——你想想看,一个分析师想临时看一条高等级数据做验证,流程要走三天。太死板了。
RBAC:企业级标配
RBAC 是目前数据平台最常用的模型。核心就一句话:权限不直接给用户,而是给角色。用户加入角色,就继承了角色的权限。
举个例子:
角色:数据工程师 → 权限:读写 ods 层所有表
角色:数据分析师 → 权限:只读 dwd 层部分表
用户张三 → 加入角色:数据工程师
用户李四 → 加入角色:数据分析师
这样做的好处是管理成本低。你不需要给 1000 个用户逐个授权,只需要维护 10 个角色就行。我在做数据中台时,RBAC 帮我们解决了 80% 的权限问题。
但 RBAC 也有短板:它处理不了“行级”和“列级”的细粒度控制。比如“销售部的经理只能看自己部门的订单”,RBAC 做起来很别扭。这时候就需要 ABAC 了。
ABAC:湖仓一体的答案
ABAC 不依赖固定的角色,而是根据属性动态判断。属性可以是:
- 用户属性:部门、职级、区域
- 资源属性:表名、列名、数据行中的地区字段
- 环境属性:访问时间、IP 地址、客户端类型
策略引擎拿到这些属性,算出一个布尔值:允许还是拒绝。
举个例子:
策略:如果 user.department == data.row.region,则允许 SELECT
用户:张三,部门 = "华东"
数据行:region = "华东" → 允许
数据行:region = "华北" → 拒绝
这就是行级权限的核心逻辑。ABAC 的灵活性非常高,但代价是策略引擎的复杂度也高。我建议你在湖仓一体里,用 RBAC 做粗粒度控制,用 ABAC 做细粒度补充,两者结合。
权限粒度:从系统级到行级
权限粒度,就是“控制到多细”。我按粒度从粗到细列出来:
| 粒度层级 | 控制对象 | 典型操作 | 实现难度 |
|---|---|---|---|
| 系统级 | 整个集群/实例 | 能否登录、能否提交作业 | 低 |
| 库级 | 数据库/Schema | 能否访问某个库 | 低 |
| 表级 | 表/视图 | 能否 SELECT/INSERT 某张表 | 中 |
| 列级 | 表中的列 | 能否看到“工资”列 | 中高 |
| 行级 | 表中的行 | 能否看到“华东”的数据 | 高 |
这里我要说一个避坑指南:不要一开始就追求行级权限。我曾经在一个项目里,上来就设计行级权限,结果策略引擎写了两万行代码,性能还跟不上。后来我们退了一步,先用表级 + 列级解决了 90% 的需求,行级只用在最敏感的几张表上。
你想想看,是不是这个道理?大部分业务场景,列级权限就能挡住敏感信息。行级权限,只有在“同一张表里不同人看不同行”时才需要。
授权模型:SQL 标准 vs 策略引擎
授权模型解决的是“怎么把权限赋予出去”。目前主流有两种方式。
SQL 标准授权
就是标准的 GRANT 和 REVOKE 语句。比如:
-- 表级授权
GRANT SELECT ON table_name TO user_name;
-- 列级授权(SQL 标准支持)
GRANT SELECT (col1, col2) ON table_name TO user_name;
-- 行级授权?SQL 标准不支持
-- 你得用视图或者策略
SQL 标准授权的优点是简单、直观、兼容性好。几乎所有数据库都支持。但它的缺点也很明显:
- 不支持行级权限
- 权限变更需要 DDL 操作,不够灵活
- 难以实现动态策略(比如“上班时间才能访问”)
策略引擎授权
策略引擎是 ABAC 的配套方案。它把权限逻辑从数据库里抽出来,放到一个独立的引擎中。常见的实现有:
- Apache Ranger:Hadoop 生态的事实标准
- Apache Sentry:已被 Ranger 取代
- Open Policy Agent (OPA):云原生场景
- 自研策略引擎:大厂常见做法
策略引擎的工作流程大致是:
- 用户发起查询请求
- 查询引擎(如 Spark、Presto)拦截请求
- 向策略引擎发送“用户 + 资源 + 操作”三元组
- 策略引擎根据预定义策略返回 Allow/Deny
- 查询引擎根据结果执行或拒绝
我个人的经验是:SQL 标准授权适合静态、粗粒度的场景;策略引擎适合动态、细粒度的场景。在湖仓一体里,两者通常会共存。比如用 SQL 标准做库级和表级授权,用 Ranger 做列级和行级授权。
本章知识体系总览
下面这张图,把本章的核心知识点串起来了。你可以把它当作一个思维导图来理解。
这张图把三大块的关系理清楚了。你从中心出发,左边是模型选择,中间是粒度层级,右边是授权实现方式。实际做方案时,这三块要一起考虑,不能割裂。
好了,这一章的基础就到这里。记住一句话:权限设计,先定模型,再定粒度,最后选实现方式。顺序错了,后面会很难改。