基于标签的掩码策略

本主题提供有关标签的掩码策略的概念,以及基于标签的掩码策略保护列数据的示例。

本主题内容:

概述

基于标签的掩码策略结合了对象标记和掩码策略功能,允许使用 ALTER TAG 命令在标签上设置掩码策略。当掩码策略签名中的数据类型与列的数据类型匹配时,标记的列将自动受到掩码策略中条件的保护。这简化了数据保护工作,因为应受保护的列数据不再需要对列手动应用掩码策略来保护数据。您可以在数据库、架构或表上设置基于标签的掩码策略。

对于 Snowflake 支持的每种 数据类型,标签可以支持一种掩码策略。为了简化最初的列数据保护工作,请为每种数据类型(例如 STRING、 NUMBER、 TIMESTAMP_LTZ)创建通用掩码策略,允许授权角色查看原始数据,允许未授权角色查看固定掩码值。

可以编写掩码策略条件,以根据分配给标签的策略来保护列数据,或者根据分配给列的标签的标签字符串值来保护列数据,具体取决于策略管理员、标签管理员和数据管理员的决定。

选择数据库、架构或表来分配策略

数据工程师和数据管理员可以选择将基于标签的掩码策略分配给数据库、架构、表或列。

数据库和架构:

在数据库或架构上设置基于标签的掩码策略时,可以利用 标签沿袭 来保护架构或数据库中的表和视图列。当列的数据类型与在架构上设置的掩码策略的数据类型匹配时,在数据库或架构上设置基于标签的掩码策略可以保护该数据库或架构中的列。

在数据库或架构上设置基于标签的掩码策略的主要好处是,当列数据类型与掩码策略数据类型匹配时,所有新添加的表和视图中的列都会自动受到保护。这种方法简化了数据保护管理,因为不再需要在每个表上设置标签。结果是该策略会保护 Snowflake 中的新数据,直到数据保护官员决定直接向列分配掩码策略或向表或视图分配行访问策略。

:

当您在表上设置基于标签的掩码策略时,会在表中的所有列上设置标签。当列的数据类型与掩码策略的数据类型匹配时,掩码策略会保护列数据。

可以通过直接分配给列的掩码策略和基于标签的掩码策略来保护列。如果某个列同时引用了这两种掩码策略,则直接分配给该列的掩码策略优先于基于标签的掩码策略。

有关基于标签的掩码策略的示例,请参考 使用基于标签的掩码策略 一节(本主题内容)。

优势

使用方便:

向标签分配一个或多个掩码策略很简单。策略管理员可以在不破坏现有工作流程的情况下添加或替换策略。

可扩展:

基于标签的策略允许策略管理员编写一次策略,将策略分配给标签一次,并根据标签的设置 级别 将策略应用于许多对象。这样可以大大减少每次创建或替换新列时手动将单个策略分配给单个列的情况。

综合:

策略管理员可以为每种数据类型创建策略并将这些策略全部分配给单个标签。一旦在表级别应用标签,表中的所有列都会受到保护,前提是列数据类型与策略中指定的数据类型匹配。

保护未来的对象:

将基于标签的掩码策略分配给表会自动将该掩码策略应用到任何新的表列。这种行为类似于 未来授权

灵活性:

基于标签的掩码策略提供了在 CREATE TABLE 语句中指定掩码策略的替代方法,这有助于简化表 DDL 管理。管理员可以选择在创建表时分配掩码策略,或者将策略分配给使用 标签沿袭 的标签。

注意事项

  • 对于基于标签的掩码策略,如果标签存储在与掩码策略和表不同的架构中,克隆包含掩码策略和表的架构,会导致克隆的表受源架构中的掩码策略的保护,而不是受克隆架构中的掩码策略的保护。

    但是,对于标签、掩码策略和表全部存在于架构中的基于标签的掩码,克隆架构会导致表受克隆架构中的掩码策略的保护,而不是受源架构中的掩码策略的保护。

    如果对表进行克隆,或将表移至其他架构或数据库,并且该表最初受架构或数据库上设置的基于标签的掩码策略的保护,则该表将不受在源架构或数据库上设置的基于标签的掩码策略的保护。如果目标架构或数据库上设置了基于标签的掩码策略,则该表将受到在目标架构或数据库上设置的基于标签的掩码策略的保护。

限制

所有现有的 掩码策略限制 都适用于基于标签的掩码策略。

使用基于标签的掩码策略时请注意以下附加限制:

数据类型:

对于每种数据类型,标签可以支持一种掩码策略。例如,如果某个标签已经具有 NUMBER 数据类型的掩码策略,则不能将另一个 NUMBER 数据类型的掩码策略分配给同一标签。

系统标签:

不能将掩码策略分配给 系统标签

弃用对象:

如果掩码策略分配给标签,则掩码策略和标签都无法弃用。同样,如果将策略分配给标签,则无法弃用包含标签和掩码策略的父架构和数据库。有关更多信息,请参阅 为标签分配掩码策略 (本主题内容)。

物化视图:

如果基础表受基于标签的掩码策略保护,则无法创建物化视图。有关更多详细信息,请参阅 掩码策略和物化视图

如果物化视图存在,且后续在基础表中添加了基于标签的掩码策略,则无法查询该物化视图;物化视图现已失效。要继续使用物化视图,请取消设置基于标签的掩码策略,重新创建或 恢复,然后查询物化视图。

行访问策略:

给定的表或视图列可以在掩码策略签名或行访问策略签名中指定。换句话说,同一列不能同时在掩码策略签名和行访问策略签名中指定。

条件列:

掩码的列不能用作掩码策略中的条件列。

映射表:

包含受基于标签的掩码策略保护的列的表不能用作映射表。

Snowflake Native App Framework:

有关将基于标签的掩码策略与 Snowflake Native App 一起使用的详细信息,请参阅:

管理基于标签的掩码策略

掩码策略和标签的现有权限以及管理掩码策略和标签的命令适用于基于标签的掩码策略。

权限

根据您是否选择在数据库、架构或表上设置基于标签的掩码策略,有不同的权限要求。

通过对数据库或架构进行基于标签的掩码,当前角色或当前角色层次结构中的角色必须继承以下两个选项之一中所示的权限。

选项 1:

该角色必须同时拥有全局 APPLY MASKING POLICY 和全局 APPLY TAG 权限。例如,将这些权限授予 data_engineer 自定义角色:

USE ROLE ACCOUNTADMIN;

GRANT APPLY MASKING POLICY ON ACCOUNT TO ROLE data_engineer;

GRANT APPLY TAG ON ACCOUNT TO ROLE data_engineer;
Copy

这是在架构或数据库中使用基于标签的掩码策略保护列的 最集中的方法

选项 2:

架构所有者(即拥有架构 OWNERSHIP 权限的角色)可以拥有全局 APPLY MASKING POLICY 权限和标签的 APPLY 权限。例如,如果标签名为 governance.tags.schema_mask,并且拥有架构的自定义角色为 schema_owner

USE ROLE ACCOUNTADMIN;

GRANT APPLY MASKING POLICY ON ACCOUNT TO ROLE schema_owner;

GRANT APPLY ON TAG governance.tags.schema_mask TO ROLE schema_owner;
Copy

此方法通过将列保护委派给架构所有者来提供更大的灵活性。

通过对表和视图进行基于标签的掩码,具有全局 APPLY MASKING POLICY 权限的角色可以分配和替换标签上的掩码策略。

例如,将全局 APPLY MASKING POLICY 权限授予 tag_admin 自定义角色:

USE ROLE SECURITYADMIN;

GRANT APPLY MASKING POLICY ON ACCOUNT TO ROLE tag_admin;
Copy

为标签分配掩码策略

在架构或数据库上分配基于标签的掩码策略与在表上设置基于标签的掩码策略遵循相同的过程:

  1. 使用 CREATE TAG 命令创建标签。

  2. 使用 CREATE MASKING POLICY 命令创建掩码策略。

    您可以选择在掩码策略条件中使用 SYSTEM$GET_TAG_ON_CURRENT_COLUMNSYSTEM$GET_TAG_ON_CURRENT_TABLE 系统函数。

  3. 使用 ALTER TAG 命令在标签上设置掩码策略。

  4. 使用以下命令之一根据您想要保护数据的方式设置对象上的标签:

小技巧

为了避免在架构或数据库上设置基于标签的掩码策略时与标签和掩码策略发生冲突,在分配基于标签的掩码策略之前,请执行以下操作:

  • 查询 TAG_REFERENCES 视图以验证表或表中的列上的现有标签集。

  • 查询 POLICY_REFERENCES 视图以确定是否对表或列设置了基于标签的掩码策略。有关详细信息,请参阅 标签和策略发现

除了 ALTER TAG 使用注意事项,请注意以下几点:

  • 一个标签对于每种数据类型只能有一个掩码策略。例如,一个策略用于 STRING 数据类型,一个策略用于 NUMBER 数据类型,等等。

  • 如果掩码策略已经保护了一列,并且在同一列上设置了具有掩码策略的标签,则 直接 分配给该列的掩码策略优先于分配给该标签的掩码策略。

  • 如果将标签分配给掩码策略,则无法 弃用 该标签。

  • 如果将掩码策略分配给标签,则无法 弃用 该策略。

有关管理掩码策略和标签的更多信息,请参阅:

替换标签上的掩码策略

在标签上设置掩码策略后,有两种不同的途径可以将标签上的掩码策略替换为不同的掩码策略。ALTER TAG 语句必须指定掩码策略名称,如以下选项所示。

选项 1:

在一条语句中取消设置标签上的策略,然后在另一条语句中为该标签设置新策略:

ALTER TAG security UNSET MASKING POLICY ssn_mask;

ALTER TAG security SET MASKING POLICY ssn_mask_2;
Copy
选项 2:

使用 FORCE 关键字在单个语句中替换策略。

请注意,当标签上已经设置了相同 数据类型 的策略时,使用 FORCE 关键字将替换该策略。

ALTER TAG security SET MASKING POLICY ssn_mask_2 FORCE;
Copy

如果需要替换或取消设置数据库或架构中的标签,您在 权限 部分中选择的选项以及 为标签分配掩码策略 部分中的操作顺序会影响标签管理。

如果架构所有者在架构上设置了标签,然后不同的角色在同一标签上设置了掩码策略,则架构所有者无法从架构中取消设置标签,除非授予架构所有者全局 APPLY MASKING POLICY 权限。Snowflake 无法对架构所有者执行 ALTER SCHEMA ...UNSET TAG 操作。此方案可确保受基于标签的掩码策略保护的列数据保持受保护状态。要避免这种情况,请使用 权限 部分中的选项 1。

重要

替换标签上的掩码策略时请务必小心。

根据替换的时间和对列的查询,选择在两个单独的语句中替换策略可能会导致数据泄漏,因为在 UNSET 和 SET 操作之间的时间间隔内,列数据不受保护。

但是,如果替换策略中的策略条件不同,则指定 FORCE 关键字可能导致缺乏访问权限,因为(以前)用户可以访问数据,而替换策略不再允许访问。

在替换策略之前,请咨询内部数据管理员,以协调使用基于标签的掩码策略保护数据的最佳方法,并根据需要替换掩码策略。

更新标签值

如果架构所有者(即 sch_role)在架构上设置了标签,然后不同的角色在同一标签上设置了掩码策略(即 masking_admin_role),则架构所有者不能更改标签值。Snowflake 无法对架构所有者执行 ALTER SCHEMA ...SET TAG 操作。

要更改标签值:

  1. 使用 masking_admin_role,从标签中取消设置掩码策略。

  2. 使用 sch_role,修改标签值。

  3. 使用 masking_admin_role 将掩码策略重新分配给标签。

父数据库和架构

在以下情况下,不能对数据库和架构执行 DROP 和 REPLACE 操作:

  • 标签和掩码策略处于同一架构中。

  • 表或视图处于不同的架构中。

  • 表或视图中受保护的列存在于与包含掩码策略和标签的架构不同的架构中。

这四个命令涉及对数据库和架构的 DROP 和替换操作:

  • DROP DATABASE

  • DROP SCHEMA

  • CREATE OR REPLACE DATABASE

  • CREATE OR REPLACE SCHEMA

条件实参

可以将 条件掩码策略 分配给标签。将标签分配给列后,如果实参的数据类型与列的数据类型匹配,则条件实参将按名称映射到表中的列。

如果在以下情况下将条件掩码策略分配给列,查询将失败:

  • 该表没有与策略的条件实参同名的列。

  • 该表有一列与策略的条件实参名称匹配,但数据类型不匹配。

有关这些错误的更多信息,请参阅 对基于标签的掩码策略进行故障排除 (本主题内容)。

标签沿袭

可以将带有掩码策略的标签分配给所有 基表 对象,也可以将标签分配给基表中的列。将基于标签的掩码策略分配给基表时,只要列数据类型与掩码策略签名中的数据类型匹配,这些列就会受到该策略的保护。

由于掩码策略保护基表列,因此根据表和视图掩码策略的当前 限制注意事项行为,从基础基表列派生的视图列也受到保护。

数据共享

在提供商账户中的共享架构或共享数据库上设置的基于标签的掩码策略将在使用者账户中强制执行。此方案可确保共享的受保护数据仍然受到保护,即使使用者从共享创建新数据库也是如此。

此外,请注意以下事项:

  • 标签沿袭保留在使用者账户中。

    当提供商在其数据库上设置基于标签的掩码策略并共享该数据库时,Snowflake 会根据包含标签的数据库引用使用者账户中的共享提供商数据库。

  • 当标签和基于标签的掩码策略源自使用者账户时,Snowflake 不支持共享对象的标签沿袭。

    来自使用者账户的标签和基于标签的掩码策略不会在任何共享对象上强制执行。

Snowsight

您可以在 Snowsight 中监控和分配基于标签的掩码策略。有关详细信息,请参阅:

使用基于标签的掩码策略

以下小节提供以下信息:

  • 与基于标签的掩码策略一起使用以进行数据保护和验证的常见过程。

  • 实施基于标签的掩码策略之前需要完成的前提步骤。

  • 示例的常见假设列表。

  • 基于标签的掩码策略使用的代表性示例,包括以下系统函数的使用:

标签和策略发现

Information Schema 表函数 POLICY_REFERENCES 和Account Usage POLICY_REFERENCES 视图可以通过查看以下各列来帮助确定掩码策略和标签是否相互引用:

  • TAG_DATABASE

  • TAG_SCHEMA

  • TAG_NAME

  • POLICY_STATUS

POLICY_STATUS 列可以有四个可能的值:

ACTIVE

指定列(即 REF_COLUMN_NAME)仅通过标签与单个策略相关联。

MULTIPLE_MASKING_POLICY_ASSIGNED_TO_THE_COLUMN

指定将多个掩码策略分配给同一列。

COLUMN_IS_MISSING_FOR_SECONDARY_ARG

指定策略(即 POLICY_NAME)是条件掩码策略,并且表(即 REF_ENTITY_NAME)没有同名的列。

COLUMN_DATATYPE_MISMATCH_FOR_SECONDARY_ARG

指定策略是条件掩码策略,并且该表有一列与掩码策略签名中的数据类型同名但数据类型不同。

有关 POLICY_STATUS 列中可能值的相关错误消息的详细信息,请参阅 对基于标签的掩码策略进行故障排除 (本主题内容)。

数据保护和验证步骤

一般来说,Snowflake 在使用基于标签的掩码策略时建议采用以下方法:

  1. 创建基于标签的掩码策略所需的任何标签。

  2. 根据您打算使用基于标签的掩码策略保护的表列,为每种数据类型创建一个掩码策略。

  3. 将掩码策略分配给标签。

  4. 将具有掩码策略的标签直接分配给表列或分配给表。

  5. 检查 Information Schema 以验证基于标签的策略是否已分配给列。

  6. 查询数据以验证基于标签的掩码策略是否按预期保护数据。

前提步骤

  1. 识别 Snowflake 账户中的现有标签及其字符串值。

    • 查询 Account Usage TAG REFERENCES 视图以获取所有标签及其分配的字符串值。

    • 可选:

      • 查询 Account Usage TAGS 视图(即 标签目录)以获取标签列表,从而确保以后在使用基于标签的掩码策略时不会出现重复的标签命名。

      • 比较 TAG_REFERENCES 和 TAGS 查询的输出,以确定是否有任何未分配的标签可以在以后使用。

      • 使用 CREATE TAG 命令创建以后需要的标签。否则,根据需要创建标签。

  2. 确定 Snowflake 账户中的现有策略及其定义。

    • 执行 SHOW MASKING POLICIES 命令获取现有掩码策略的列表。

    • 决定是否可以将当前形式的这些策略分配给标签。如有必要,执行 DESCRIBE MASKING POLICY 命令以获取策略定义。否则,计划创建新策略以分配给标签。

  3. 根据策略条件是否应评估在表列上设置的标签字符串值,确定如何使用掩码策略保护列数据。

常见假设与示例

这些示例做出以下假设:

  • 前提步骤已完成。

  • tag_admin 自定义角色具有以下权限:

    • 架构级别 CREATE TAG 权限。

    • 全局 APPLY TAG 权限。

    有关更多信息,请参阅 标签权限

  • masking_admin 自定义角色具有以下权限:

    • 架构级别 CREATE MASKING POLICY 权限。

    • governance 数据库和 governance.masking_policies 架构的 USAGE 权限。

    • 全局 APPLY MASKING POLICY 权限可将掩码策略分配给标签(请参阅本主题中的 权限)。

    • 全局 APPLY TAG 权限,用于将标签(和掩码策略)分配给对象。

    有关详细信息,请参阅 标签权限

  • row_access_admin 自定义角色具有以下权限:

    • 架构级别 CREATE ROW ACCESS POLICY 权限。

    • governance 数据库和 governance.row_access_policies 架构的 USAGE 权限。

    • 全局 APPLY ROW ACCESS POLICY 权限。

    有关更多信息,请参阅 行访问策略权限

  • accounting_admin 自定义角色具有以下权限:

    • finance 数据库和 finance.accounting 架构的 USAGE 权限。

    • finance.accounting 架构中表的 SELECT 权限。

  • analyst 自定义角色具有以下权限:

    • finance 数据库和 finance.accounting 架构的 USAGE 权限。

    • finance.accounting.name_number 表的 SELECT 权限。

  • 上述自定义角色被授予适当的用户。

    有关详细信息,请参阅 配置访问控制

示例 1:根据直接分配给标签的掩码策略保护列数据

此示例将两个掩码策略分配给一个标签,然后将同一标签分配给一个表。结果是掩码策略保护数据类型与策略中的数据类型匹配的所有表列。

以下步骤将创建基于标签的掩码策略来对会计数据应用掩码。例如,考虑名为 finance.accounting.name_number 的表,该表有两列: ACCOUNT_NAMEACCOUNT_NUMBER。这些列中的数据类型分别是 STRING 和 NUMBER。

---------------+----------------+
  ACCOUNT_NAME | ACCOUNT_NUMBER |
---------------+----------------+
  ACME         | 1000           |
---------------+----------------+

创建基于标签的掩码策略来保护 ACCOUNT_NAME 和 ACCOUNT_NUMBER 列,如下所示:

  1. 在名为 governance.tags 的架构中创建一个名为 accounting 的标签。

    USE ROLE tag_admin;
    USE SCHEMA governance.tags;
    CREATE OR REPLACE TAG accounting;
    
    Copy
  2. 创建不同的掩码策略来保护 ACCOUNT_NAME 和 ACCOUNT_NUMBER 列。在每个策略中,只有 ACCOUNTING_ADMIN 自定义角色可以查看原始数据。

    账户名称策略:

    USE ROLE masking_admin;
    USE SCHEMA governance.masking_policies;
    
    CREATE OR REPLACE MASKING POLICY account_name_mask
    AS (val string) RETURNS string ->
      CASE
        WHEN CURRENT_ROLE() IN ('ACCOUNTING_ADMIN') THEN val
        ELSE '***MASKED***'
      END;
    
    Copy

    账户编号策略:

    CREATE OR REPLACE MASKING POLICY account_number_mask
    AS (val number) RETURNS number ->
      CASE
        WHEN CURRENT_ROLE() IN ('ACCOUNTING_ADMIN') THEN val
        ELSE -1
      END;
    
    Copy
  3. 将两种掩码策略分配给 accounting 标签。请注意,这两个策略都可以在单个语句中分配给标签。

    ALTER TAG governance.tags.accounting SET
      MASKING POLICY account_name_mask,
      MASKING POLICY account_number_mask;
    
    Copy
  4. accounting 标签分配给 finance.accounting.name_number 表。

    ALTER TABLE finance.accounting.name_number
      SET TAG governance.tags.accounting = 'tag-based policies';
    
    Copy
  5. 通过调用 Information Schema POLICY_REFERENCES 表函数,验证 ACCOUNT_NAMEACCOUNT_NUMBER 表列是否受基于标签的掩码策略保护。

    对于每个受保护的列,查询结果中的行应为列名称、策略名称和标签名称指定适当的值:

    USE ROLE masking_admin;
    SELECT *
    FROM TABLE (governance.INFORMATION_SCHEMA.POLICY_REFERENCES(
      REF_ENTITY_DOMAIN => 'TABLE',
      REF_ENTITY_NAME => 'governance.accounting.name_number' )
    );
    
    Copy

    返回(注意更新的列):

    -------------+------------------+---------------------+----------------+-------------------+-----------------+-----------------+-------------------+-----------------+----------------------+--------------+------------+------------+---------------+
      POLICY_DB  | POLICY_SCHEMA    | POLICY_NAME         | POLICY_KIND    | REF_DATABASE_NAME | REF_SCHEMA_NAME | REF_ENTITY_NAME | REF_ENTITY_DOMAIN | REF_COLUMN_NAME | REF_ARG_COLUMN_NAMES | TAG_DATABASE | TAG_SCHEMA | TAG_NAME   | POLICY_STATUS |
    -------------+------------------+---------------------+----------------+-------------------+-----------------+-----------------+-------------------+-----------------+----------------------+--------------+------------+------------+---------------+
      GOVERNANCE | MASKING_POLICIES | ACCOUNT_NAME_MASK   | MASKING_POLICY | FINANCE           | ACCOUNTING      | NAME_NUMBER     | TABLE             | ACCOUNT_NAME    | NULL                 | GOVERNANCE   | TAGS       | ACCOUNTING | ACTIVE        |
      GOVERNANCE | MASKING_POLICIES | ACCOUNT_NUMBER_MASK | MASKING_POLICY | FINANCE           | ACCOUNTING      | NAME_NUMBER     | TABLE             | ACCOUNT_NUMBER  | NULL                 | GOVERNANCE   | TAGS       | ACCOUNTING | ACTIVE        |
    -------------+------------------+---------------------+----------------+-------------------+-----------------+-----------------+-------------------+-----------------+----------------------+--------------+------------+------------+---------------+
    
  6. 使用已授权和未授权角色查询表列,以确保 Snowflake 返回正确的查询结果。

    已授权:

    USE ROLE accounting_admin;
    SELECT * FROM finance.accounting.name_number;
    
    Copy

    返回:

    ---------------+----------------+
      ACCOUNT_NAME | ACCOUNT_NUMBER |
    ---------------+----------------+
      ACME         | 1000           |
    ---------------+----------------+
    

    未授权:

    USE ROLE analyst;
    SELECT * FROM finance.accounting.name_number;
    
    Copy

    返回:

    ---------------+----------------+
      ACCOUNT_NAME | ACCOUNT_NUMBER |
    ---------------+----------------+
      ***MASKED*** | -1             |
    ---------------+----------------+
    

示例 2:根据列标签字符串值保护列数据

此示例使用基于标签的掩码策略来确定是否应根据分配给列的标签的标签字符串值来对数据应用掩码。掩码策略通过将系统 SYSTEM$GET_TAG_ON_CURRENT_COLUMN 函数调用到掩码策略条件中并写入掩码策略条件以匹配标签字符串值来动态评估标签字符串值。

以下步骤将创建基于标签的掩码策略来对会计数据应用掩码。为了简洁起见,表列有两种数据类型,分别是 STRING 和 NUMBER。例如,一个名为 finance.accounting.name_number 的表:

---------------+----------------+
  ACCOUNT_NAME | ACCOUNT_NUMBER |
---------------+----------------+
  ACME         | 1000           |
---------------+----------------+

创建基于标签的掩码策略来保护 ACCOUNT_NAMEACCOUNT_NUMBER 列,如下所示:

  1. 在名为 governance.tags 的架构中创建一个名为 accounting_col_string 的标签。

    USE ROLE tag_admin;
    USE SCHEMA governance.tags;
    CREATE TAG accounting_col_string;
    
    Copy
  2. 创建不同的掩码策略来保护 ACCOUNT_NAME 和 ACCOUNT_NUMBER 列。在每个策略中,只有当列上的当前标签字符串值设置为 'visible' 时,原始数据才可见。

    账户名称策略:

    USE ROLE masking_admin;
    USE SCHEMA governance.masking_policies;
    
    CREATE MASKING POLICY account_name_mask_tag_string
    AS (val string) RETURNS string ->
      CASE
        WHEN SYSTEM$GET_TAG_ON_CURRENT_COLUMN('tags.accounting_col_string') = 'visible' THEN val
        ELSE '***MASKED***'
      END;
    
    Copy

    账户编号策略:

    CREATE MASKING POLICY account_number_mask_tag_string
    AS (val number) RETURNS number ->
      CASE
        WHEN SYSTEM$GET_TAG_ON_CURRENT_COLUMN('tags.accounting_col_string') = 'visible' THEN val
        ELSE -1
      END;
    
    Copy

    备注

    这些策略在函数实参中使用 schema_name.tag_name 对象名称格式,因为 tags 架构和 masking_policies 架构都存在于 governance 数据库中。或者,您也可以在函数实参中使用标签的完全限定名称。

    如果策略条件中的系统函数实参包含不充分限定的标签名称,则 Snowflake 在查询运行时对受基于标签的掩码策略保护的列返回错误。例如,该实参仅将标签名用 accounting_col_string,而不指定架构名或数据库名。

    有关更多信息,请参阅 对象名称解析

  3. 将两种掩码策略分配给 accounting_col_string 标签。请注意,这两个策略都可以在单个语句中分配给标签。

    ALTER TAG accounting_col_string SET
      MASKING POLICY account_name_mask_tag_string,
      MASKING POLICY account_number_mask_tag_string;
    
    Copy
  4. accounting_col_string 标签分配给每个表列。在此示例中, ACCOUNT_NAME 列上的标签字符串值为 'visible',但是 ACCOUNT_NUMBER 列上的标签字符串值设置为 'protect'

    ALTER TABLE finance.accounting.name_number MODIFY COLUMN
      account_name SET TAG governance.tags.accounting_col_string = 'visible',
      account_number SET TAG governance.tags.accounting_col_string = 'protect';
    
    Copy
  5. 通过调用 Information Schema POLICY_REFERENCES 表函数,验证 ACCOUNT_NAMEACCOUNT_NUMBER 表列是否受基于标签的掩码策略保护。

    对于每个受保护的列,查询结果中的行应为列名称、策略名称和标签名称指定适当的值。

    SELECT *
    FROM TABLE(
     governance.INFORMATION_SCHEMA.POLICY_REFERENCES(
       REF_ENTITY_DOMAIN => 'TABLE',
       REF_ENTITY_NAME => 'finance.accounting.name_number'
       )
    );
    
    Copy

    返回(注意更新的列):

    ------------+----------------+--------------------------------+----------------+-------------------+-----------------+-----------------+-------------------+-----------------+----------------------+--------------+------------+-----------------------+---------------+
     POLICY_DB  | POLICY_SCHEMA  | POLICY_NAME                    |  POLICY_KIND   | REF_DATABASE_NAME | REF_SCHEMA_NAME | REF_ENTITY_NAME | REF_ENTITY_DOMAIN | REF_COLUMN_NAME | REF_ARG_COLUMN_NAMES | TAG_DATABASE | TAG_SCHEMA | TAG_NAME              | POLICY_STATUS |
    ------------+----------------+--------------------------------+----------------+-------------------+-----------------+-----------------+-------------------+-----------------+----------------------+--------------+------------+-----------------------+---------------+
     GOVERNANCE | MASKING_POLICY | ACCOUNT_NAME_MASK_TAG_STRING   | MASKING_POLICY | FINANCE           | ACCOUNTING      | NAME_NUMBER     | TABLE             | ACCOUNT_NAME    | NULL                 | GOVERNANCE   | TAGS       | ACCOUNTING_COL_STRING | ACTIVE        |
     GOVERNANCE | MASKING_POLICY | ACCOUNT_NUMBER_MASK_TAG_STRING | MASKING_POLICY | FINANCE           | ACCOUNTING      | NAME_NUMBER     | TABLE             | ACCOUNT_NUMBER  | NULL                 | GOVERNANCE   | TAGS       | ACCOUNTING_COL_STRING | ACTIVE        |
    ------------+----------------+--------------------------------+----------------+-------------------+-----------------+-----------------+-------------------+-----------------+----------------------+--------------+------------+-----------------------+---------------+
    
  6. 查询表列以确保 Snowflake 返回正确的查询结果,该结果应仅对 ACCOUNT_NUMBER 列中的值应用掩码。

    USE ROLE accounting_admin;
    SELECT * FROM finance.accounting.name_number;
    
    Copy

    返回:

    ---------------+----------------+
      ACCOUNT_NAME | ACCOUNT_NUMBER |
    ---------------+----------------+
      ACME         | -1             |
    ---------------+----------------+
    

示例 3:根据表标签字符串值保护表

此示例使用行访问策略来根据分配给表的标签字符串值来保护表,并使用基于标签的掩码策略来保护表中的列。为简单起见,此示例使用一个标签,将掩码策略分配给该标签,并将该标签分配给表。由于 标签沿袭,表中的列将自动具有相同的标签及其字符串值。

行访问策略通过在行访问策略条件中调用 SYSTEM$GET_TAG_ON_CURRENT_TABLE 函数来动态评估分配给表的标签的标签字符串值。与前面的示例一样,掩码策略条件调用系统 SYSTEM$GET_TAG_ON_CURRENT_COLUMN 函数来评估表列上的标签字符串值。

重要

请注意,您 不能 将行访问策略分配给标签。

相反,使用 ALTER TABLE 命令将行访问策略直接分配给表。

finance.accounting.name_number 有两列,数据类型分别为 STRING 和 NUMBER:

---------------+----------------+
  ACCOUNT_NAME | ACCOUNT_NUMBER |
---------------+----------------+
  ACME         | 1000           |
---------------+----------------+

使用行访问策略和基于标签的掩码策略保护表及其列,如下所示:

  1. 在策略条件中 创建一个调用系统 :doc:/sql-reference/functions/system_get_tag_on_current_table` 函数的行访问策略 </sql-reference/sql/create-row-access-policy>`:

    USE ROLE row_access_admin;
    USE SCHEMA governance.row_access_policies;
    
    CREATE ROW ACCESS POLICY rap_tag_value
    AS (account_number number)
    RETURNS BOOLEAN ->
    SYSTEM$GET_TAG_ON_CURRENT_TABLE('tags.accounting_row_string') = 'visible'
    AND
    'accounting_admin' = CURRENT_ROLE();
    
    Copy

    该策略指定 只有accounting_row_string 标签分配给 具有 字符串值 'visible' 的表 并且 对表或其列执行查询的角色是 accounting_admin 自定义角色时,Snowflake 才会在查询结果中返回行。

    如果满足以下任一条件,Snowflake 不会在查询结果中返回行:

    • 未在表上设置 accounting_row_string 标签。

    • 在表上设置了 accounting_row_string 标签,但使用了不同的字符串值。

    • 对表或其列执行查询的角色不是 accounting_admin 自定义角色。

  2. 将行访问策略 分配 给表:

    ALTER TABLE finance.accounting.name_number
      ADD ROW ACCESS POLICY rap_tag_value ON (account_number);
    
    Copy

    请注意,在过程的此时,对表的查询 应返回 Snowflake 中任何角色的查询结果中的任何行,因为 accounting_row_string 标签没有分配给表。因此,对表进行查询的预期结果应该是:

    USE ROLE accounting_admin;
    SELECT * FROM finance.accounting.name_number;
    
    Copy

    返回:

    ---------------+----------------+
      ACCOUNT_NAME | ACCOUNT_NUMBER |
    ---------------+----------------+
                   |                |
    ---------------+----------------+
    

    通过选择在将基于标签的掩码策略分配给表之前将行访问策略分配给表,可以尽早保护所有表数据。

  3. 在名为 governance.tags 的架构中创建一个名为 accounting_row_string 的标签。

    USE ROLE tag_admin;
    USE SCHEMA governance.tags;
    CREATE TAG accounting_row_string;
    
    Copy
  4. 创建不同的掩码策略来保护 ACCOUNT_NAME 和 ACCOUNT_NUMBER 列。在每个策略中,只有当列上的当前标签字符串值设置为 'visible' 时,原始数据才可见。

    账户名称策略:

    USE ROLE masking_admin;
    USE SCHEMA governance.masking_policies;
    
    CREATE MASKING POLICY account_name_mask AS (val string) RETURNS string ->
      CASE
        WHEN SYSTEM$GET_TAG_ON_CURRENT_COLUMN('tags.accounting_row_string') = 'visible' THEN val
        ELSE '***MASKED***'
      END;
    
    Copy

    账户编号策略:

    CREATE MASKING POLICY account_number_mask AS (val number) RETURNS number ->
      CASE
        WHEN SYSTEM$GET_TAG_ON_CURRENT_COLUMN('tags.accounting_row_string') = 'visible' THEN val
        ELSE -1
      END;
    
    Copy
  5. 将两种掩码策略分配给 accounting_row_string 标签。请注意,这两个策略都可以在单个语句中分配给标签。

    ALTER TAG governance.tags.accounting_row_string SET
      MASKING POLICY account_name_mask,
      MASKING POLICY account_number_mask;
    
    Copy
  6. accounting_row_string 标签分配给标签字符串值为 'visible' 的表:

    ALTER TABLE finance.accounting.name_number
      SET TAG governance.tags.accounting_row_string = 'visible';
    
    Copy

    现在,标签被分配给字符串值为 visible 的表,只有 accounting_admin 自定义角色可以查看表数据;具有任何其他角色的用户执行的查询应该不会返回任何行,如本例前面所示。换句话说,行访问策略的条件现在评估为 true。

    类似地,表列也具有 visible 标签的标签字符串值,因为列通过标签沿袭继承标签及其字符串值。结果是,当具有 accounting_admin 自定义角色的用户查询该表时,Snowflake 将返回未掩码的数据:

    USE ROLE accounting_admin;
    SELECT * FROM finance.accounting.name_number;
    
    Copy

    返回:

    ---------------+----------------+
      ACCOUNT_NAME | ACCOUNT_NUMBER |
    ---------------+----------------+
      ACME         | 1000           |
    ---------------+----------------+
    
  7. 要对任一列中的数据应用掩码,请直接更新该列的标签字符串值。例如,要对 ACCOUNT_NUMBER 列中的数据应用掩码:

    ALTER TABLE finance.accounting.name_number MODIFY COLUMN
      account_number SET TAG governance.tags.accounting_row_string = 'protect';
    
    Copy

    现在,当具有 accounting_admin 自定义角色的用户查询表或 ACCOUNT_NUMBER 列时,Snowflake 将返回掩码数据:

    USE ROLE accounting_admin;
    SELECT * FROM finance.accounting.name_number;
    
    Copy

    返回:

    ---------------+----------------+
      ACCOUNT_NAME | ACCOUNT_NUMBER |
    ---------------+----------------+
      ACME         | -1             |
    ---------------+----------------+
    

对基于标签的掩码策略进行故障排除

下表列出了使用基于标签的掩码策略时 Snowflake 可能返回的一些错误消息:

行为

错误消息

故障排除操作

无法查询列:策略太多。

SQL 执行错误:列 <col_name> 通过标签映射到多个掩码策略。请联系您的本地管理员解决该问题。

给定的列只能受一种掩码策略的保护。

调用 POLICY_REFERENCES 函数来标识对该列设置的掩码策略。通过取消标签中的掩码策略来修改标签,以便该列仅受一项策略的保护。

无法查询列:没有条件列。

SQL 执行错误:列 <col_name> 映射到掩码策略,其中该表没有策略的辅助实参名称列。请联系您的本地管理员解决该问题。

使用 条件实参 的掩码策略必须在同一表或视图中包含所有指定的列。执行以下操作之一来保护列数据:

  • 直接 为该列分配不同的策略。

  • 通过为标签 分配 不同的掩码策略来修改标签。

由于列和策略的数据类型不匹配,列数据未被掩码。

SQL 执行错误:列 <col_name> 映射到掩码策略,其中表有一列具有不同数据类型的辅助实参名称。请联系您的本地管理员解决该问题。

要对列数据应用掩码,列的数据类型和掩码策略签名中的数据类型必须匹配。执行以下操作之一来保护列数据:

  • 直接 为该列分配不同的策略。

  • 为标签 分配 掩码策略,确保策略的数据类型和列的数据类型匹配。

语言: 中文