基于属性的访问控制的核心概念(ABAC)

基于属性的访问控制(ABAC)是一种访问控制模型,它使用 受治理的标签 和策略,根据对象属性而非逐对象授权来授予权限。 此页面定义构建基块:受管理标记、三种 ABAC 策略类型(行筛选器、列掩码和 GRANT 策略)、配置这些策略所需的权限,以及跨团队实现的 ABAC 职责分离。

有关所有 ABAC 主题(包括教程、策略管理、最佳做法和限制)的概述,请参阅 Unity 目录中基于属性的访问控制

什么是 ABAC?

基于属性的访问控制(ABAC) 是一种动态访问控制模型,其中访问决策基于针对与安全对象关联的属性评估的策略。 在 Unity 目录中,这些属性通过 受治理的标记表示。 这些受治理的标记用于策略条件,以匹配给定范围内的数据对象,例如目录或架构。 这允许单个策略自动应用于满足其条件的多个数据对象。

例如,ABAC 策略可能会屏蔽架构中标记为PII的表格内标记为HR的所有列。 创建新数据对象并标记时,该策略会自动应用,而无需为每个对象单独定义策略。

ABAC 通过 行筛选器策略 和表上的 列掩码策略 、具体化视图和流式处理表支持行和列级安全性。 行筛选器策略限制用户可以看到哪些行。 列掩码策略控制如何向用户显示列值。 有关 表级行筛选器和列掩码的比较,请参阅 何时使用 ABAC 与表级行筛选器和列掩码

管理的标签

在 Unity 目录中,属性作为 受管理标记实现。 受管控标签是在账户级别定义的键值对,可应用于 Unity Catalog 中的可保护对象(如目录、架构、表、列、模型和卷),以及工作区对象。 它们表示敏感度、分类或业务域等特征。

默认情况下,安全对象从其父目录或架构继承标记。 您可以在除列级外的每个级别覆盖继承的标记:列标记不会从父表继承,必须直接应用到列。

受管理的标签层次结构图

可以使用内置函数(例如has_tag())在has_tag_value()条件中引用受治理的标记,这些函数检查给定标记是直接还是通过标记继承存在于目标数据对象上。

治理的标签在账户级别定义。 这意味着,您可以在账户中的整个数据资源库中使用相同的标签分类法,包括在多个元数据存储库之间。

有关详细信息,请参阅 受治理的标记 并将 标记应用于 Unity 目录安全对象

Policies

策略附加到 Unity 目录中 的安全对象 ,以基于标记条件定义访问控制规则。 下面是一个示例:

CREATE FUNCTION mask_pii(val STRING) RETURNS STRING
    RETURN '***';

CREATE POLICY mask_pii_for_hr
ON CATALOG catalog_a
COLUMN MASK mask_pii
TO `account users` EXCEPT `HR admins`
FOR TABLES
WHEN has_tag('HR')
MATCH COLUMNS has_tag('PII') AS pii_col
ON COLUMN pii_col;

每个策略指定:

  • 范围:附加策略的安全对象,由 ON 子句指定。 将策略附加到可保护对象意味着:对于 FOR 子句中指定类型的所有对象,都会在该对象及其所有后代对象范围内评估策略条件。

    • 对于行筛选器和列掩码策略,支持的策略范围是 CATALOGSCHEMATABLE。 对于 GRANT 策略(Beta),支持的策略范围为 CATALOGSCHEMA
    • 表(包括流式表和物化视图)是行筛选策略和列掩码策略唯一受支持的可保护对象类型,并使用 FOR TABLES 子句指定。
    • 在目录中附加的策略会对该目录中的所有表进行评估。 架构中附加的策略针对该架构中的所有表进行评估。 表中附加的策略仅针对该表进行评估。

注释

Databricks 建议将策略附加到最高适用级别(通常是目录)以最大限度地提高治理效率。 请参阅 ABAC 策略的最佳做法

  • 主体:策略的适用对象及豁免对象。 该 TO 子句指定受策略约束的用户、组或服务主体。 可选的EXCEPT条款将特定的责任主体排除在此策略之外。
  • 操作:策略是应用行筛选器、列掩码还是特权授予。 行筛选器和列掩码策略使用 用户定义的函数(UDF) 来实现筛选或屏蔽逻辑。 GRANT 策略 (Beta) 不使用 UDF。 请参阅 策略类型
  • 条件:基于标记的表达式,用于确定策略所面向的表或列。 请参阅 “条件”和“内置函数”。

策略通过 UI 创建和管理,或使用 SQL 语句(例如CREATE POLICYDROP POLICYSHOW POLICIESDESCRIBE POLICYREST APIDatabricks SDKTerraform)以编程方式进行管理。 有关完整语法和示例,请参阅 创建和管理 ABAC 策略

策略类型

ABAC 支持三种策略类型:行筛选器策略、列掩码策略和 GRANT 策略(Beta)。 行筛选器和列掩码策略要求 UDF 实现筛选或屏蔽逻辑。 GRANT 策略不使用 UDF,而是在基于标记的条件与目标对象的属性匹配时授予特权。

行筛选策略

行筛选器策略根据与 “条件”和内置函数匹配的标记标识的列中的值限制用户在表中可以看到哪些行。 该策略引用了一个评估每一行的用户自定义函数(UDF)。 从查询结果中排除函数返回的 FALSE 行。 参数通过 USING COLUMNS 子句传递给 UDF。

示例用例: 对于销售目录,请确保 EMEA 团队只能看到所有有列标记为 region 的表中的 EMEA 销售记录。

CREATE FUNCTION filter_by_region(region STRING, allowed STRING) RETURNS BOOLEAN
    RETURN region = allowed;

CREATE POLICY regional_access_emea
ON CATALOG sales
ROW FILTER filter_by_region
TO `emea team`
FOR TABLES
MATCH COLUMNS has_tag('region') AS rgn
USING COLUMNS (rgn, 'EMEA');

列掩码策略

列掩码策略控制用户看到标记与条件和内置函数匹配的特定列的值。 该策略引用一个 UDF,该 UDF 将列值作为输入,并返回原始值或掩码版本。 掩码列值会作为 ON COLUMN 子句中的第一个参数自动绑定,并且可以通过 USING COLUMNS 传递其他参数。 返回类型必须匹配或可强制转换为列的数据类型。

示例用例: 屏蔽标有 pii : ssn 标记的 SSN 列,以便用户仅看到 ***-**-XXXX (最后四位数字),除非他们在符合性组中不受策略限制。

CREATE FUNCTION mask_ssn(ssn STRING, show_last INT) RETURNS STRING
    RETURN CONCAT('***-**-', RIGHT(ssn, show_last));

CREATE POLICY mask_ssn_columns
ON CATALOG hr_catalog
COLUMN MASK mask_ssn
TO `account users` EXCEPT `compliance team`
FOR TABLES
MATCH COLUMNS has_tag_value('pii', 'ssn') AS ssn_col
ON COLUMN ssn_col
USING COLUMNS (4);

USING COLUMNS 子句将参数传递给 UDF。 它接受与基于标签的表达式匹配的列的别名,或常量值(引号字符串、数字字面量、布尔值(如TRUE/FALSE),或NULL),按照函数预期的顺序提供。 它还接受 标记反省函数,该函数在查询时提取标记的值并将其传递给 UDF。 对于列掩码策略,除了屏蔽列本身之外,这些参数是附加的(屏蔽列将自动从ON COLUMN中绑定)。 这允许跨具有不同参数的策略重复使用单个 UDF。

建议使用 SQL UDF 来提高性能。 注册在 Unity Catalog 中的 Python UDF 也受支持,但查询优化器无法像对 SQL UDF 那样对它们进行内联或优化。 有关 UDF 语言选择的指导,请参阅 性能注意事项

条件和内置函数

条件是基于标签的表达式,用于确定策略在其范围内定位的表和列。

  • 表条件WHEN 子句):根据表标记匹配的布尔表达式。 如果省略,则默认 TRUE为策略,这意味着该策略适用于作用域中的所有表。
  • 列条件MATCH COLUMNS 子句):一个或多个逗号分隔的布尔表达式,用于标识策略所面向的列。 每个表达式可以是单个内置函数,例如 has_tag('pii'),也可以使用逻辑运算符(例如 has_tag_value('pii', 'ssn') AND has_tag('sensitive'))的组合。 可以为每个表达式分配一个别名(在AS后指定),该别名可在ON COLUMNUSING COLUMNS子句中引用。 策略最多可以包含 3 个列表达式,并且所有表达式都必须匹配才能应用策略。

这两种子句都使用以下内置函数,这些函数由 Unity Catalog 根据可安全管理的元数据进行评估:

函数 背景 Description
has_tag('tag_key') 表格和字段 如果资源具有指定的标记,则返回 true。 在表条件(WHEN)中,检查直接在表上设置的标记或从父目录或架构继承的标记。 在列条件(MATCH COLUMNS)中,仅检查直接在列上设置的标记 — 与表标记不匹配。
has_tag_value('tag_key', 'tag_value') 表格和字段 如果资源具有具有指定值的指定标记,则返回 true。 与has_tag()相同的上下文行为。

标记不会从表传播到列。 在 has_tag() 子句中使用 MATCH COLUMNS 仅匹配列级标签,而不是父表或其上级的标签。

注释

has_taghas_tag_value函数使用蛇形命名法(snake_case)。 较旧的 camelCase(hasTaghasTagValue)命名形式仍然可用,但不推荐使用。 Azure Databricks 计划在创建新策略时弃用 camelCase 形式。 现有策略不受影响。

示例:使用两个列条件。 customers 架构具有电子邮件列和同意列标记为pii : emailconsent_to_contact的表。 除非客户已同意联系,否则策略会屏蔽电子邮件地址。 它使用两个列条件:

  1. has_tag_value('pii', 'email') 标识包含电子邮件地址的列(要屏蔽的列)。
  2. has_tag('consent_to_contact') 标识包含同意信息的列(UDF 用于决定是否屏蔽)。
CREATE FUNCTION mask_email_by_consent(email STRING, consent BOOLEAN)
RETURNS STRING
RETURN CASE
  WHEN consent = true THEN email
  ELSE '****@****.***'
END;

CREATE POLICY mask_email_with_consent
ON SCHEMA customers
COLUMN MASK mask_email_by_consent
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag_value('pii', 'email') AS m,
  has_tag('consent_to_contact') AS c
ON COLUMN m
USING COLUMNS (c);

此策略仅适用于同时具有标记为列 pii : email 和标记为列 consent_to_contact 的表。 如果表没有匹配这两个条件的列,则策略不适用,并且将返回未屏蔽的数据。

用户定义函数 (UDF)

行筛选器和列掩码策略使用用户定义的函数(UDF)来实现其筛选或屏蔽逻辑。 请参阅 Unity 目录中的 SQL 和Python用户定义的函数(UDF),了解如何创建和管理 UDF,以及有关行筛选的常见模式和列掩码的示例。

标签自省函数

标签自省函数会提取受管控标签的值,并通过 USING COLUMNS 子句将其传递给 UDF。 由于 UDF 接收标记值作为参数,因此单个策略和 UDF 可以处理多个标记值,而无需为每个标记值单独策略。 这些函数仅适用于行筛选器和列掩码策略,因为 GRANT 策略不使用 UDF。

创建使用这些函数的策略需要 Databricks Runtime 18 LTS 或更高版本。 此要求仅适用于策略创建,不适用于查询受治理表。

注释

Databricks Runtime 18 比 Databricks Runtime 18.0、18.1 和 18.2 更新。 以前会作为后续编号版本发布的功能,现在改为作为 Databricks Runtime 18 的按日期命名更新发布。 有关详细信息,请参阅 关于统一发行说明

在查询时,Unity Catalog 会根据策略匹配到的表或列上的标记来评估这些函数:get_tag_value() 从满足 WHEN 条件的表中读取,而 get_column_tag_value() 从由 MATCH COLUMNS 标识的列中读取。 它们只能出现在USING COLUMNS子句中,而不能出现在WHENMATCH COLUMNS条件中。

函数 背景 Description
get_tag_value('tag_key') Tables 返回应用于要访问的表或从其父架构或目录继承的指定标记的值。 如果该标记未应用于该表或其任何祖先元素,或者该标记没有值,则返回 NULL
get_column_tag_value(column_alias, 'tag_key') 返回直接应用于匹配列的指定标记的值。 与此函数不同 get_tag_value(),此函数不会在父表上查阅标记,因为列标记不会继承。 第一个参数是在子句中 MATCH COLUMNS 定义的别名。 如果 NULL 标记未应用于列或没有值,则返回。

这两个函数均将标记键作为字符串文本。 该标记必须是受治理的标记,并且 get_column_tag_value() 必须引用策略子 MATCH COLUMNS 句中存在的别名。 如果标记不受控制或别名无效,则策略创建将失败。 如果查询运行时不再控制引用的标记,则针对策略的目标表的查询在运行时会失败。

示例:适用于所有 PII 类型的统一策略

如果不进行标记反省,屏蔽每种类型的个人身份信息(电子邮件、SSN、电话)需要针对每个标记值使用单独的策略和 UDF。 使用 get_column_tag_value()时,单个策略会将匹配列的 pii 标记值传递到一个 UDF。 UDF 对该值进行分支:

CREATE FUNCTION mask_pii(col STRING, pii_type STRING)
RETURNS STRING
RETURN CASE
  WHEN pii_type = 'email' THEN regexp_replace(col, '(^[^@]+)', '***')
  WHEN pii_type = 'ssn' THEN '***-**-' || right(col, 4)
  WHEN pii_type = 'phone' THEN '***-***-' || right(col, 4)
  ELSE col
END;

CREATE POLICY mask_all_pii
ON CATALOG main
COLUMN MASK mask_pii
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('pii') AS col
ON COLUMN col
USING COLUMNS (get_column_tag_value(col, 'pii'));

对于每个掩码列,get_column_tag_value(col, 'pii') 会解析为该列的 pii 标记值(emailssnphone 等),而 mask_pii 则应用相应的转换。 新标记值只需要 UDF 中的新分支,而不需要新策略。

职责和权限分离

设置 ABAC 涉及几个步骤,每个步骤都有自己的权限要求。 组织可以跨专用组分配这些任务,具体取决于他们选择如何分离职责。 例如,组织可以集中定义标记分类,然后让数据专员对数据进行分类、治理管理员写入策略、数据创建者在受管理的范围内创建对象,以及数据使用者访问受管理的对象。

ABAC 职责分离

  1. 创建标签分类。 在任何人应用这些标记或写入策略之前,定义受治理的标记键及其允许的值。 例如,创建一个sensitivity标记,其中包含受控值(publicinternalconfidentialrestricted),或一个pii标记,其中的值为ssnemailphone_number。 有关命名约定和分类设计的建议,请参阅 标准化属性和命名

    • 所需权限:帐户管理员或具有 CREATE 帐户级别标记权限的用户。
  2. 标记数据资产。 数据专员、数据创建者或 AI 分类系统将受治理的标记应用于 Unity 目录安全对象,例如目录、架构、表、列、模型和卷。 例如,将包含个人身份识别信息的列标记为 pii : ssn,或者将模型标记为 lifecycle : production。 正确的标记是应用 ABAC 策略的基本第一步。

    • 所需权限:标记上的 ASSIGN 和对象上的 APPLY TAG

Warning

标记是安全边界。 如果用户可以更改数据资产上的标记,他们可以更改应用于它的策略。 组织应控制谁可以应用标记和审核标记更改。

  1. 创建策略。 治理管理员在某个范围(例如目录或模式)创建政策。 该策略指定要应用于的人员、其评估的条件以及要应用的操作,例如行筛选器、列掩码或特权授予。

    • 所需权限:MANAGE 对附加了该策略的安全对象具有权限,或拥有该对象的所有权。 对于行筛选器和列掩码策略,还需要具有对 UDF 的 EXECUTE 权限。
  2. 创建数据对象。 数据创建者可在其被授予访问权限的作用域内创建可保护对象,例如表、模型或卷。 新对象从父目录和架构继承标记。 数据创建者还会自动创建 APPLY TAG 对象,因此可以应用其他标记。 或者,它们可以依赖于 自动数据分类 来处理标记。 如果组织依赖数据创建者来标记自己的对象,则应建立明确的标记做法。 如果策略设置在较高级别,则数据创建者无需配置任何访问控制,Azure Databricks建议这样做。

    • 所需权限: CREATE TABLE 或父对象的其他相关创建权限。
  3. 访问受治理的对象。 当用户尝试访问策略范围内的安全对象时,Unity 目录会自动评估适用的策略。 对于行筛选器和列掩码策略,如果用户的表或列与策略的条件匹配,并且用户不受豁免,则会看到筛选或屏蔽的数据。 对于 GRANT 策略(Beta),如果条件满足,且用户在 EXCEPT 中而不在 TO 中,则用户将获得授予的权限。

    • 所需权限:对于行筛选器和列掩码策略,必须通过直接对象授权向用户授予该表的权限,例如 SELECT。 这些策略会对用户已可访问的表中的记录进行筛选,或对列进行掩码处理。 他们不自行授予权限。 GRANT 策略(Beta)本身会授予该权限,并与对同一安全对象的任何直接授予取并集。

ABAC 的优点

  • 基于属性的可重用策略: 单个策略可以应用于多个与基于属性的条件匹配的数据对象,而不是绑定到一个特定对象。

  • 自动将应用程序应用到新对象: 在范围内创建新数据对象并使用相关属性进行标记时,现有 ABAC 策略将应用而不进行其他配置。 策略类似于将来的授予,这意味着访问控制在创建和标记新数据时自动应用。

  • 在范围内的一致性实施: 在目录或架构级别附加的策略会动态评估该范围内的匹配数据对象,从而消除筛选或屏蔽类似数据时的差异性。

  • 持续维护较低: 可以通过更新策略逻辑或受管理标记进行更改,而不是按照表级行筛选器和列掩码的要求重新访问每个对象。

  • 集中式治理: 由于策略可以定义一次,并跨多个匹配的数据对象应用,因此治理团队可以使用更少的策略定义来管理数据资产中较大部分的控制。

其他资源