感度階層を用いた複数ドメイン列マスキングを実装する
このチュートリアルでは、ドメイン認識型の列マスキングと感度階層を、領域ベースの行フィルタリングと組み合わせて実装する方法を示します。MATCH COLUMNSの AND 条件を使用してドメインと機密レベルの両方でカラムをターゲットにし、 EXCEPT句を使用して各ドメインを所有するグループを対応するマスク ポリシーから免除します。
前提条件
- Databricks Runtime 16.4 以降、またはサーバレス コンピュート。
- アカウント管理者またはワークスペース管理者権限(管理タグを作成するため)。
MANAGE対象のカタログまたはスキーマに対する権限。EXECUTEUDFについて。- アカウントグループ:
hr_team、finance_team、marketing_team、us_team、eu_team。
必要なグループを作成するには、 [ワークスペース設定] > [ID とアクセス] > [グループ] に移動し、 [グループの追加] をクリックして、それぞれを作成します。 ステップ 7 の HR + US の視点に従うには、少なくともhr_teamとus_teamに自分自身を追加してください。
シナリオ
貴社では、人事、財務、マーケティング部門で共有される中央テーブルemployee_recordsを管理しています。各チームは特定の列を所有しており、自分たちのデータはマスク解除された状態で閲覧できるが、他のチームの機密データは閲覧できないようにすべきである。
このチュートリアルでは、 domainという管理タグを使用して、各列をどのチームが所有しているかを表します。その名称は任意である。team 、 department 、またはbusiness_unitを使用することもできます。重要な考え方は、各列が正確に 1 つの所有グループに割り当てられ、2 番目のsensitivityタグによって、そのグループ外のユーザーに対してデータがどの程度積極的にマスクされるかが制御されるということです。
列 |
|
| 承認されたグループ |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
マスキング動作は感度レベルによって異なります。
- 内部 : 所有グループ外のユーザーには部分的なマスク (最初の文字 +
***) が表示されます。 - 機密情報 :所有グループ以外のユーザーは
***REDACTED***を参照してください。
複数のドメイングループに属するユーザーは、自分のドメインのすべての列がマスク解除された状態で表示されます。
ステップ 1: 管理タグを作成する
カタログ エクスプローラー UI で次の管理タグを作成します ( [カタログ] > [管理] > [管理タグ] > [管理タグの作成] )。
タグキー | 許容値 |
|---|---|
| (キーのみのタグ) |
|
|
|
|
タグデータはプレーンテキストとして保存され、グローバルに複製される可能性があります。リソースのセキュリティを損なう可能性のあるタグ名、値、または記述子を使用しないでください。例えば、個人情報や機密情報を含むタグ名、値、記述子は使用しないでください。
ステップ 2: サンプルデータを構築する
人事、財務、マーケティング部門で共有される単一の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: 管理タグを適用する
機密性の高い各列には、 domainとsensitivityの両方の値をタグ付けしてください。これら2つのタグを組み合わせることで、各ポリシーはMATCH COLUMNSのAND条件を使用して特定のドメインと感度の組み合わせをターゲットにすることができます。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をシンプルかつ再利用性の高いものにすることができます。各行フィルタポリシーは1つのグループを対象とし、そのグループが閲覧を許可されている領域を渡します。
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: 行フィルターを作成する
地域ごとに1つの行フィルタポリシーを作成します。各ポリシーは特定のグループを対象とし、許可された領域を定数として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: ドメイン列マスクを作成する
ドメインと機密性の組み合わせごとに、ポリシーを1つ作成してください。各ポリシーは、特定のdomainおよびsensitivityレベルの列を照合するために AND を使用し、 EXCEPT所有ドメイングループを除外します。
内部( | 機密情報( | |
|---|---|---|
HR |
|
|
財務 |
|
|
マーケティング |
|
|
各列にはdomain値が1つとsensitivityの値が1つずつ含まれているため、各列はユーザーごとに正確に1つのポリシーに一致します。紛争はありません。
内部列(部分マスク)
所有ドメイン外のユーザーに対して、内部レベルの列に部分的なマスクを適用します。
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: 結果を確認する
7つのポリシー(行フィルター2つと列マスク6つ)すべてが現在有効になっています。以下のクエリを実行し、結果がグループメンバーシップで許可されている内容と一致することを確認してください。
SELECT * FROM abac_tutorial.domain_demo.employee_records;
米国地域の人事チームメンバー ( hr_team + us_team ):
| ID | 従業員名 | 社会保障番号 | Eメール | 顧客リスト | コストセンター | 給与バンド | 従業員地域 | 部署 |
| -- | -------------- | ----------- | ------ | -------------------- | ------------ | -------------------- | ----------- | ----------- |
| 1 |アリス・ジョンソン | 123-45-6789 | a*** | ***編集済み*** | C*** | ***編集済み*** |私たち | エンジニアリング |
| 2 | ボブ・スミス | 234-56-7890 | b*** | ***編集済み*** | C*** | ***編集済み*** | us | 営業 |
| 5 | エヴァ・マルティネス | 567-89-0123 | e*** | ***編集済み*** | C*** | ***編集済み*** | us | HR |
HR列( employee_name 、 ssn )はマスク解除されています。マーケティング内部情報( email )は部分的にマスクされ、機密情報( customer_list )は編集されています。財務内部( cost_center )は部分的にマスクされており、機密( salary_band )は編集されています。
EU地域における財務チームメンバー ( finance_team + eu_team ):
| ID | 従業員名 | 社会保障番号 | Eメール | 顧客リスト | コストセンター | 給与バンド | 従業員地域 | 部署 |
| -- | -------------- | -------------------- | ------ | -------------------- | ------------ | ------------ | ----------- | ----------- |
| 3 | C*** | ***編集済み*** | c*** | ***編集済み*** | CC-5010 |バンド8 | EU | エンジニアリング |
| 4 | D*** | ***編集済み*** | d*** | ***編集済み*** | CC-2010 |バンド4 | EU | マーケティング |
財務関連の列( cost_center 、 salary_band )はマスク解除されています。その他のドメイン列はすべてマスクまたは編集されています。
hr_team + marketing_team + us_teamのユーザー:
| ID | 従業員名 | 社会保障番号 | Eメール | 顧客リスト | コストセンター | 給与バンド | 従業員地域 | 部署 |
| -- | -------------- | ----------- | ---------------------------------------- | ----------------- | ------------ | -------------------- | ----------- | ----------- |
| 1 |アリス・ジョンソン | 123-45-6789 | alice@acme.com |ティア 1 エンタープライズ | C*** | ***編集済み*** |私たち | エンジニアリング |
ユーザーは両方のグループに属しているため、HR 列とマーケティング列の両方がマスク解除されます。 金融コラムは引き続き非公開のままです。
このパターンが機能する理由
各列には、 domain値が1つとsensitivityの値が1つずつ含まれているため、各列はユーザーごとに正確に1つのポリシーに一致します。ポリシーの矛盾はありません。
EXCEPT句が鍵となる。各ポリシーは、それらの列を所有するドメイングループを除くaccount usersに適用されます。あなたが所有グループに属している場合、このポリシーは適用されず、生データが表示されます。そうでない場合は、ポリシーが適用され、データはマスキングされます。複数のグループに所属するユーザーは、当然ながらメリットを享受できます。 hr_teamとmarketing_team両方に所属するユーザーは、人事ポリシーとマーケティングポリシーの両方の適用対象から除外されます。
新しいドメイン(例:Legal)を追加するには、以下のものが必要です。
- 新しいグループ(
legal_team)。 domainタグに新たに許可される値legal。- 2つの新しいポリシー(
mask_internal_legal、mask_confidential_legal)。 - 新しい列にタグを付ける。
既存のポリシーを変更する必要はありません。
掃除
このチュートリアルで作成したすべてのオブジェクトを削除するには、次のコマンドを実行します。
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;
region 、 domain 、およびsensitivity管理タグ、およびアカウント グループ ( hr_team 、 finance_team 、 marketing_team 、 us_team 、 eu_team ) を削除するには、それぞれカタログ エクスプローラー UI とワークスペース設定を使用します。