使用敏感层实现多域列掩码

本教程演示如何使用敏感度层实现域感知列掩码,以及基于区域的行筛选。 你在MATCH COLUMNS中使用 AND 条件,根据域和敏感度级别锁定列,并通过EXCEPT子句免除每个域的拥有组不受相应掩码策略的影响。

先决条件

  • Databricks Runtime 16.4 或更高版本,或无服务器计算。
  • 帐户管理员或工作区管理员权限(用于创建受管理标记)。
  • MANAGE 目标目录或架构的权限。
  • EXECUTE 在 UDF 上下功夫。
  • 帐户组:hr_team、、finance_teammarketing_teamus_teameu_team

若要创建所需的组,请转到 工作区设置>标识和访问>,单击“ 添加组”并创建每个组。 至少将自己添加到 hr_teamus_team 中,以在步骤 7 中遵循 HR + US 视角。

Scenario

组织维护一张在人力资源、财务和市场营销中共享的中心 employee_records 表。 每个团队拥有某些列,应看到其自己的数据未掩码,但不应看到其他团队的敏感数据。

本教程使用一个名为 domain 的受治理标记来表示每列由哪个团队拥有。 名称是任意的。 还可以使用 teamdepartmentbusiness_unit。 关键思想是,每个列都准确地分配给一个唯一的拥有组,第二个sensitivity标记用于控制数据对该组之外用户的掩码强度。

domain 标记 sensitivity 标记 授权组
employee_name hr internal hr_team
ssn hr confidential hr_team
email marketing internal marketing_team
customer_list marketing confidential marketing_team
cost_center finance internal finance_team
salary_band finance confidential finance_team

掩码行为取决于敏感度级别:

  • 内部:所有组外部的用户看到部分掩码(第一个字符 + ***)。
  • 机密:不属于拥有组的用户会看到 ***REDACTED***

属于多个域组的用户将看到他们所属的所有域的列未被屏蔽。

步骤 1:创建受管理标记

在目录资源管理器 UI 中,创建以下受治理标记(目录>治理>受治理的标记>创建受治理标记)。

标记键 允许的值
region (仅键标签)
domain hrfinancemarketing
sensitivity internalconfidential

Warning

标记数据以纯文本形式存储,可全局复制。 不要使用标记名称、值或描述符,这些标记名称或描述符可能会损害资源的安全性。 例如,不要使用包含个人或敏感信息的标记名称、值或描述符。

步骤 2:生成示例数据

创建跨 HR、Finance 和 Marketing 共享的单个 employee_records 表。 每个敏感列将在下一步中用一个 domain 级别和一个 sensitivity 级别进行标记。

CREATE CATALOG IF NOT EXISTS abac_tutorial;
USE CATALOG abac_tutorial;

CREATE SCHEMA IF NOT EXISTS domain_demo;
USE SCHEMA domain_demo;
CREATE OR REPLACE TABLE employee_records (
  id INT,
  employee_name STRING,
  ssn STRING,
  email STRING,
  customer_list STRING,
  cost_center STRING,
  salary_band STRING,
  emp_region STRING,
  department STRING
);

INSERT INTO employee_records VALUES
  (1, 'Alice Johnson',  '123-45-6789', 'alice@acme.com',  'Tier-1 Enterprise', 'CC-4010', 'Band 7', 'us', 'Engineering'),
  (2, 'Bob Smith',      '234-56-7890', 'bob@acme.com',    'SMB Accounts',      'CC-3020', 'Band 5', 'us', 'Sales'),
  (3, 'Carol White',    '345-67-8901', 'carol@acme.com',  'Tier-1 Enterprise', 'CC-5010', 'Band 8', 'eu', 'Engineering'),
  (4, 'David Lee',      '456-78-9012', 'david@acme.com',  'Growth Segment',    'CC-2010', 'Band 4', 'eu', 'Marketing'),
  (5, 'Eva Martinez',   '567-89-0123', 'eva@acme.com',    'Mid-Market',        'CC-4020', 'Band 6', 'us', 'HR');

步骤 3:应用受治理的标记

标记每个敏感列及其domainsensitivity值。 这两个标记一起允许每个策略使用 AND 条件 MATCH COLUMNS将特定域和敏感度组合作为目标。 该 emp_region 列被标记为仅包含键的 region 标签,因为策略只需标识列,而无需检查特定的值。

-- HR domain
ALTER TABLE employee_records
  ALTER COLUMN employee_name SET TAGS ('domain' = 'hr', 'sensitivity' = 'internal');
ALTER TABLE employee_records
  ALTER COLUMN ssn SET TAGS ('domain' = 'hr', 'sensitivity' = 'confidential');

-- Marketing domain
ALTER TABLE employee_records
  ALTER COLUMN email SET TAGS ('domain' = 'marketing', 'sensitivity' = 'internal');
ALTER TABLE employee_records
  ALTER COLUMN customer_list SET TAGS ('domain' = 'marketing', 'sensitivity' = 'confidential');

-- Finance domain
ALTER TABLE employee_records
  ALTER COLUMN cost_center SET TAGS ('domain' = 'finance', 'sensitivity' = 'internal');
ALTER TABLE employee_records
  ALTER COLUMN salary_band SET TAGS ('domain' = 'finance', 'sensitivity' = 'confidential');

-- Region tag for row filtering
ALTER TABLE employee_records
  ALTER COLUMN emp_region SET TAGS ('region' = '');

步骤 4:创建 UDF

行筛选器 UDF 接受行的区域值和允许的区域作为静态参数,并在它们匹配时返回 TRUE 。 将允许的区域作为常量传递,使 UDF 简单且可重用。 每行筛选器策略针对一个组,并传递该组有权查看的区域。

CREATE OR REPLACE FUNCTION abac_tutorial.domain_demo.region_filter(region_val STRING, allowed_region STRING)
RETURNS BOOLEAN
RETURN region_val = allowed_region;

为内部列创建部分掩码UDF,并为机密列创建完整遮蔽UDF。

CREATE OR REPLACE FUNCTION abac_tutorial.domain_demo.partial_mask(val STRING)
RETURNS STRING
RETURN CONCAT(LEFT(val, 1), '***');

CREATE OR REPLACE FUNCTION abac_tutorial.domain_demo.redact(val STRING)
RETURNS STRING
RETURN '***REDACTED***';

步骤 5:创建行筛选器策略

为每个区域创建一行筛选器策略。 每个策略以特定组为目标,并通过常量 USING COLUMNS传递允许的区域。

CREATE POLICY region_filter_us
ON SCHEMA abac_tutorial.domain_demo
ROW FILTER abac_tutorial.domain_demo.region_filter
TO `us_team`
FOR TABLES
MATCH COLUMNS has_tag('region') AS region_col
USING COLUMNS (region_col, 'us');

CREATE POLICY region_filter_eu
ON SCHEMA abac_tutorial.domain_demo
ROW FILTER abac_tutorial.domain_demo.region_filter
TO `eu_team`
FOR TABLES
MATCH COLUMNS has_tag('region') AS region_col
USING COLUMNS (region_col, 'eu');

注释

另一种方法是使用标识函数(例如 is_account_group_member())在 UDF 中嵌入组逻辑。 此方法使用没有静态值的单个策略,但会将组到区域映射移动到 UDF。 使用适合组织的方案。

步骤 6:创建域列掩码策略

为每个域和敏感度组合创建一个策略。 每个策略都使用 AND 来匹配具有特定 domain AND sensitivity 级别的列,并 EXCEPT 免除拥有的域组。

内部(partial_mask 机密 (redact
人力资源 mask_internal_hr mask_confidential_hr
Finance mask_internal_finance mask_confidential_finance
Marketing mask_internal_marketing mask_confidential_marketing

由于每个列只有一个 domain 值和一个 sensitivity 值,因此每个列都与每个用户的一个策略完全匹配。 没有冲突。

内部列(部分掩码)

将部分掩码应用于拥有域外部用户访问的内部级列。

CREATE POLICY mask_internal_hr
ON SCHEMA abac_tutorial.domain_demo
COLUMN MASK abac_tutorial.domain_demo.partial_mask
TO `account users` EXCEPT `hr_team`
FOR TABLES
MATCH COLUMNS (
  has_tag_value('domain', 'hr')
  AND has_tag_value('sensitivity', 'internal')
) AS m
ON COLUMN m;

CREATE POLICY mask_internal_finance
ON SCHEMA abac_tutorial.domain_demo
COLUMN MASK abac_tutorial.domain_demo.partial_mask
TO `account users` EXCEPT `finance_team`
FOR TABLES
MATCH COLUMNS (
  has_tag_value('domain', 'finance')
  AND has_tag_value('sensitivity', 'internal')
) AS m
ON COLUMN m;

CREATE POLICY mask_internal_marketing
ON SCHEMA abac_tutorial.domain_demo
COLUMN MASK abac_tutorial.domain_demo.partial_mask
TO `account users` EXCEPT `marketing_team`
FOR TABLES
MATCH COLUMNS (
  has_tag_value('domain', 'marketing')
  AND has_tag_value('sensitivity', 'internal')
) AS m
ON COLUMN m;

机密列(完整修订)

对不属于拥有域的用户,全面编辑机密级列。

CREATE POLICY mask_confidential_hr
ON SCHEMA abac_tutorial.domain_demo
COLUMN MASK abac_tutorial.domain_demo.redact
TO `account users` EXCEPT `hr_team`
FOR TABLES
MATCH COLUMNS (
  has_tag_value('domain', 'hr')
  AND has_tag_value('sensitivity', 'confidential')
) AS m
ON COLUMN m;

CREATE POLICY mask_confidential_finance
ON SCHEMA abac_tutorial.domain_demo
COLUMN MASK abac_tutorial.domain_demo.redact
TO `account users` EXCEPT `finance_team`
FOR TABLES
MATCH COLUMNS (
  has_tag_value('domain', 'finance')
  AND has_tag_value('sensitivity', 'confidential')
) AS m
ON COLUMN m;

CREATE POLICY mask_confidential_marketing
ON SCHEMA abac_tutorial.domain_demo
COLUMN MASK abac_tutorial.domain_demo.redact
TO `account users` EXCEPT `marketing_team`
FOR TABLES
MATCH COLUMNS (
  has_tag_value('domain', 'marketing')
  AND has_tag_value('sensitivity', 'confidential')
) AS m
ON COLUMN m;

步骤 7:验证结果

所有七个策略(两行筛选器和六个列掩码)现在都处于活动状态。 运行以下查询并验证结果是否与组成员身份允许的结果匹配。

SELECT * FROM abac_tutorial.domain_demo.employee_records;

美国区域的人力资源团队成员hr_team + us_team):

id employee_name ssn 电子邮件 客户列表 成本中心 薪资范围 emp_region 部门
1 Alice Johnson 123-45-6789 a*** REDACTED*** C*** REDACTED*** 我们 工程
2 鲍勃·史密斯 234-56-7890 b*** REDACTED*** C*** REDACTED*** 我们 Sales
5 伊娃·马丁内斯 567-89-0123 e*** REDACTED*** C*** REDACTED*** 我们 人力资源

HR 列 (employee_namessn) 已取消屏蔽。 营销内部(email)部分掩码,机密(customer_list)经过修订。 财务内部(cost_center)已部分隐藏,机密信息(salary_band)已删除。

欧盟地区的财务团队成员finance_team + eu_team):

id employee_name ssn 电子邮件 客户列表 成本中心 薪资范围 emp_region 部门
3 C*** REDACTED*** c*** REDACTED*** CC-5010 频段 8 欧盟 工程
4 D*** REDACTED*** d*** REDACTED*** CC-2010 频段 4 欧盟 Marketing

财务列 (cost_centersalary_band) 已取消掩码。 所有其他域列都会被屏蔽或编辑。

用户:hr_team + marketing_team + us_team

id employee_name ssn 电子邮件 客户列表 成本中心 薪资范围 emp_region 部门
1 Alice Johnson 123-45-6789 alice@acme.com 一级企业 C*** REDACTED*** 我们 工程

人力资源和市场营销列均未屏蔽,因为用户属于这两个组。 财务列仍被屏蔽。

为什么此模式有效

每个列只有一个 domain 值和一个 sensitivity 值,因此每个列都与每个用户的一个策略完全匹配。 没有策略冲突。

条款 EXCEPT 是关键。 除拥有这些列的域组外,每个策略都适用于account users。 如果您属于拥有者组,策略将不适用,并且您将看到原始数据。 如果您不是,政策将适用并遮蔽数据。 多组用户能够自然受益:同时属于 hr_teammarketing_team 的用户会被排除在 HR 和市场营销政策之外。

添加新域(例如,法律)需要:

  1. 一个新组(legal_team)。
  2. 一个新的允许值legal用于domain标记。
  3. 两个新策略 (mask_internal_legalmask_confidential_legal) 。
  4. 新列上的标记。

无需更改现有策略。

清理

若要删除在本教程中创建的所有对象,请运行以下命令。

DROP POLICY region_filter_us ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY region_filter_eu ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY mask_internal_hr ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY mask_internal_finance ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY mask_internal_marketing ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY mask_confidential_hr ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY mask_confidential_finance ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY mask_confidential_marketing ON SCHEMA abac_tutorial.domain_demo;
DROP FUNCTION IF EXISTS abac_tutorial.domain_demo.region_filter;
DROP FUNCTION IF EXISTS abac_tutorial.domain_demo.partial_mask;
DROP FUNCTION IF EXISTS abac_tutorial.domain_demo.redact;
DROP TABLE IF EXISTS abac_tutorial.domain_demo.employee_records;
DROP SCHEMA IF EXISTS abac_tutorial.domain_demo CASCADE;

若要删除受regiondomain管理的sensitivity标记,以及帐户组(hr_teamfinance_teammarketing_teamus_teameu_team),请分别使用目录资源管理器 UI 和工作区设置。