Important
RBAC 目前处于公开预览阶段。 ABAC 现已正式可用。 本页介绍两者如何协同工作。
Unity 目录中基于角色的访问控制(RBAC)和 基于属性的访问控制(ABAC) 是旨在协同工作的补充控制。 他们回答不同的问题:
- RBAC 控制用户在会话中以 哪种身份 进行操作。 用户承担某个角色,以该角色的权限而非自己的权限执行操作。 使用 RBAC 为一个用户提供多个不同的权限集,这些权限集在显式之间切换,例如,跨临床试验、项目或敏感度层分离访问权限。
- ABAC 控制当前身份可以查看 哪些数据,可按行或按列进行控制。 策略通过 受治理的标记 附着于数据,并适用于执行查询的任何身份。 使用 ABAC 跨数据属性驱动的多个表进行一致的筛选或掩码。
RBAC 为会话设置当前身份,而 ABAC 则根据该身份评估其策略。 本页介绍交互在实践中如何发挥出来、标识相关的 SQL 函数的行为以及组合使用模式。
身份在承担角色时的行为方式
Unity Catalog 中与身份相关的 SQL 函数是基于会话的当前活动身份进行解析的,而不是基于实际进行身份验证的用户。 当用户承担角色时,活动会话标识将成为该角色:
| 函数 | 当用户以自己的用户身份执行操作时 | 用户承担角色时 |
|---|---|---|
current_user() |
返回用户的用户名 | 返回假定角色的名称 |
is_member(group) |
如果该用户是某个组的成员(工作区本地组,或分配给该工作区的账户组),则返回 true |
仅当所承担的角色本身是 true 的成员时,才返回 group。 对于底层用户所属但假设角色不属于的组,返回 false。 |
is_account_group_member(group) |
如果用户是帐户级组的成员,则返回true |
与 is_member 相同:仅根据所承担角色的组成员身份返回 true,而不是根据底层用户的组成员身份。 |
引用这些函数的 ABAC 策略根据 假定的角色而不是用户进行评估。 假定角色是用于 ABAC 策略评估、Unity Catalog 授权解析和审计归因的当前生效身份。 因此,承担某个角色会改变那些围绕按用户身份构建的现有策略和视图的行为。
注释
角色不会自动成为其自身的成员。 当用户承担了角色 G 时,current_user() 返回 G,但 is_member('G') 和 is_account_group_member('G') 都会返回 false,除非已显式将 G 添加为其自身的成员。 若要在策略中匹配被假定的角色,请与 current_user() 进行比较,而不要使用 is_member 或 is_account_group_member 来测试成员资格。
常见陷阱:构建在 current_user() 上的行级安全视图
ABAC 和 表级行筛选器 的常见模式是通过与 预配表 (也称为映射表或访问控制列表)联接来筛选行(也称为映射表或访问控制列表),该表由返回的 current_user()用户名进行键控。 例如:
CREATE OR REPLACE FUNCTION facility_filter(facility_id STRING)
RETURN EXISTS (
SELECT 1
FROM governance.user_facility_provisioning p
WHERE p.user = current_user()
AND p.facility_id = facility_id
);
当同一用户承担角色时, current_user() 不再返回其用户名。 它返回角色的名称。 由于角色不在预配表中,因此筛选器不返回任何行,并且用户似乎失去对已授予数据的访问权限。
将角色添加到预配表
将角色视为预配数据中的另一个主体:使用角色应看到的设施(或其他属性)为每个角色插入一行。 然后,筛选器匹配活动标识是用户还是假定的角色。
组合使用模式
下面是客户如何使用 RBAC 和 ABAC 共同解决真正的访问控制问题的示例。 这些都是起点,不是详尽的食谱。
基于假定角色的按项目划分的行过滤器
按项目筛选行是临床试验研究、合同营销、客户咨询等场景中的常见需求,在这些场景中,一个团队往往需要同时负责多个彼此独立的项目。 以下示例使用临床试验,但模式通用化为任何每个项目的数据隔离。
一个临床试验组织运行多个并发试验,每个试验都有自己的访问角色。 使用项目标识符标记每个表。 用户只能看到其当前所担任角色对应项目的行。
设置:
-
clinical_trials.*下的表包含一个project_id列,该列已使用 governed 标签 键project进行标记。 - 每个项目都有一个名为
role-<project>(例如,role-alpha)role-beta的相应访问角色。 - 用户仅对所处理项目的角色具有“假定”权限。
行筛选器 UDF:
CREATE FUNCTION project_match(project_id STRING) RETURNS BOOLEAN
DETERMINISTIC
RETURN current_user() = CONCAT('role-', project_id);
策略:
CREATE POLICY per_project_row_filter
ON CATALOG clinical_trials
ROW FILTER project_match
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('project') AS project
USING COLUMNS (project);
此 UDF 会将当前身份与每一行的 project 标记值关联起来,因此,像 TO / EXCEPT 这样面向主体的子句无法表达这种关系——它们针对的是主体,而不是行内容。 正如 主体定向指南 所解释的那样,对于简单的主体范围界定,应优先使用 TO / EXCEPT;而像这种单条规则同时依赖当前身份和行内容的情况,才应在 UDF 中使用身份函数。
单个策略涵盖每个项目: USING COLUMNS (project) 将每行的 project 标记值传递到 UDF 中,因此不需要每个项目单独的策略。 有关此方法的一般形式(从查找表驱动行访问而不是角色名称匹配),请参阅 使用映射表进行动态访问控制。
行为:
- 以其用户身份运行的用户在任何 表中都
clinical_trials。current_user()返回其用户名,该用户名永远不会与命名模式匹配role-*。 这就是预设的默认拒绝策略。 - 假定为
role-alpha的用户只能看到其中project_id等于alpha的行。 切换到role-beta时,无需重新查询其他任何内容,即可切换当前可见的数据。
对担任指定角色的用户放宽 PII 屏蔽限制
默认情况下,PII 列(SSN、电子邮件、电话)将针对所有人显示屏蔽。 若要查看原始值,用户必须显式假定指定的 PII 清除角色。 审计日志会记录承担角色的事件,因此,“我需要查看真实的 PII”就变成了一种可审计的主动申请,而不是默认权限。
设置:
- 敏感列使用 governed 标记 键
pii进行标记(允许的值例如ssn、email、phone)。 - 名为
role-pii-cleared的访问角色会将 Assume 权限授予获准查看原始 PII 的用户。
列掩码 UDF(静态——策略指定要进行掩码处理的主体):
CREATE FUNCTION mask_pii(val STRING) RETURNS STRING
DETERMINISTIC
RETURN '***';
策略:
CREATE POLICY pii_default_mask
ON CATALOG customer_data
COLUMN MASK mask_pii
TO `account users`
EXCEPT `role-pii-cleared`
FOR TABLES
MATCH COLUMNS has_tag('pii') AS pii_col
ON COLUMN pii_col;
EXCEPT 子句将 role-pii-cleared 完全排除在该策略之外,因此当该角色是当前活动身份时,绝不会调用 UDF。 有关通过 TO / 进行主体定向的一般指导,请参阅 EXCEPT。
行为:
- 以其用户身份操作的用户会在每个 PII 列中看到
***。 这是所有人的默认状态,包括对role-pii-cleared具有 Assume 权限的用户。 - 假设
role-pii-cleared策略不再应用于会话,并且同一用户会看到原始值。 - 该会话记录
identity_metadata.run_as = role-pii-cleared的审计日志条目会记录相关信息,以便审阅者准确查看 PII 何时被解除遮蔽以及由谁解除遮蔽。
随所承担的角色而变化的敏感度层级策略
数据分类为敏感度层(internal、、confidentialrestricted)。 每个层都有相应的访问角色,restricted这意味着也具有访问权限confidentialinternal。 单行过滤 UDF 通过将每一行的层级与用户的假设角色进行比较来控制行的可见性。
设置:
- 表有一个使用
sensitivity_level键标记的sensitivity列(允许的值:internal、confidential、restricted)。 - 三个访问角色:
role-sens-internal、、role-sens-confidentialrole-sens-restricted。
行筛选器 UDF:
CREATE FUNCTION sensitivity_allowed(row_sensitivity STRING) RETURNS BOOLEAN
DETERMINISTIC
RETURN CASE
WHEN current_user() = 'role-sens-restricted' THEN TRUE
WHEN current_user() = 'role-sens-confidential' THEN row_sensitivity IN ('internal', 'confidential')
WHEN current_user() = 'role-sens-internal' THEN row_sensitivity = 'internal'
ELSE FALSE
END;
策略:
CREATE POLICY sensitivity_filter
ON CATALOG corp_data
ROW FILTER sensitivity_allowed
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('sensitivity') AS sens
USING COLUMNS (sens);
由于角色不是其自身的成员,因此此 UDF 将 current_user() 与每个角色名称进行比较,而不是使用 is_account_group_member() 测试成员资格。 请参阅 上述说明 ,了解成员身份测试为何与假定角色不匹配。 有关 UDF 中标识函数的性能特征,请参阅 行筛选器和列掩码策略的性能注意事项 。
行为:
- 以其用户身份运行的用户会看不到任何行数据。
ELSE FALSE分支匹配任何不属于这三种角色之一的内容。 与上面的每项目示例一样,这是预期的默认拒绝。 - 假设
role-sens-internal仅显示internal行。 - 假设
role-sens-confidential显示internal和confidential行。 - 假设
role-sens-restricted显示所有行。
用户假设会话所需的最高层;筛选器会自动排除该层上方的所有内容,而无需用户知道哪些表包含哪些分类。
审计归属
ABAC 策略评估和基础查询都遵循 RBAC run_as / run_by 属性。 审核日志条目将 identity_metadata.run_by 记录为进行身份验证的用户,将 identity_metadata.run_as 记录为所承担的角色,而不受评估期间应用了哪些 ABAC 策略的影响。 有关完整的 审核日志架构,请参阅审核日志系统表参考 。
后续步骤
- 模型独占访问权限:采用以下模式,使用账户本地组或从 Microsoft Entra ID 同步的组来设置独占访问权限。 请参阅 模型独占访问权限。
- 切换角色:使用角色切换器、专用访问模式群集、CLI、API 或第三方 BI 工具承担角色。 请参阅 “切换角色”。
- 管理假设权限:授予或撤销对组的假设,以便用户可以承担相应的角色。 请参阅 对组的管理权限。
- 查看 ABAC 核心概念:了解受治理的标记、策略和策略评估的工作原理。 请参阅 Unity 目录中基于属性的访问控制。