メインコンテンツまでスキップ

行フィルタリングと列マスキングの一般的なパターン

このページでは、ABAC の行フィルターおよび列マスクポリシーを実装するための一般的なパターンについて説明します。

キャスト対応のマスキング機能​

Databricks 、ターゲットカラムのデータ型に一致するようにマスキング関数の出力を自動的にキャストします。 列マスクの自動型変換を参照してください。

以下のパターンは、キャストに対応したマスキング関数を設計するのに役立ちます。

キャスト可能な型を返します​

列をマスクする場合、同じデータ型、またはそれにキャスト可能な型を返します。ポリシーの対象となる列のデータ型を確認し、関数の各分岐が互換性のある値を返すことを確認してください。

SQL
-- Succeeds: Masks a DOUBLE column, returns DOUBLE in every branch
CREATE FUNCTION mask_salary(salary DOUBLE, user_role STRING)
RETURNS DOUBLE
RETURN CASE
WHEN user_role IN ('admin', 'hr') THEN salary
WHEN user_role = 'manager' THEN ROUND(salary / 1000) * 1000
ELSE 0.0
END;

-- Fails: 'CONFIDENTIAL' cannot be cast to a DOUBLE column type
CREATE FUNCTION mask_salary_as_text(salary DOUBLE, user_role STRING)
RETURNS STRING
RETURN CASE
WHEN user_role IN ('admin', 'hr') THEN CAST(salary AS STRING)
ELSE 'CONFIDENTIAL'
END;

数値オーバーフローを回避する​

マスク関数がターゲットカラムよりも広い数値型を受け入れて返す場合、結果は自動的に列の型にキャスト バックされます。 返された値がより狭い型の範囲を超えると、キャストがオーバーフローし、クエリが失敗します。 。

SQL
-- The target column is TINYINT (max 127). The input is upcast to BIGINT
-- for the function. Adding 1000 produces a BIGINT result that overflows
-- when cast back to TINYINT.
CREATE FUNCTION mask_score(score BIGINT)
RETURNS BIGINT
RETURN score + 1000;

複数の列タイプにはVARIANTを使用します​

単一の関数で複数の列の型をマスクするを参照してください。

キャスト適合性テスト​

異なるデータパターンを用いてマスキング機能をテストする。

SQL
SELECT CAST(mask_salary(salary, 'admin') AS DOUBLE) FROM employees;
SELECT CAST(mask_salary(salary, 'manager') AS DOUBLE) FROM employees;
SELECT CAST(mask_salary(salary, 'viewer') AS DOUBLE) FROM employees;

単一の関数で複数の列タイプをマスクする​

VARIANTを受け入れて返す単一のマスキングUDFでさまざまなデータ型の列をマスクできるため、保守が必要なUDFやポリシーの数を減らすことができます。Databricksは、関数の実行前に列の値をVARIANTにキャストし、その後ANSI SQLのルールに従って戻り値を列の型にキャストし直します。

関数内で schema_of_variant() を使用して、値を検査し、その型に基づいてBranchします。各Branchで、ターゲットカラムの型にキャスト可能な値を返します。

複数の数値型をマスクする​

最も単純な VARIANT マスクは、Databricks が各列の型にキャストする単一の定数を返します。この関数を使用する 1 つのポリシーで、精度ごとに個別の関数を使用することなく、INT、DOUBLE、および DECIMAL の各列をマスクできます。

SQL
CREATE FUNCTION mask_numeric(val VARIANT)
RETURNS VARIANT
DETERMINISTIC
RETURN 0::VARIANT;

タイプによってマスクされた値を変更するには、schema_of_variant() で Branch し、それぞれに適した値を返します。

SQL
CREATE FUNCTION flexible_mask(data VARIANT)
RETURNS VARIANT
RETURN CASE
WHEN schema_of_variant(data) = 'BIGINT' THEN 0::VARIANT
WHEN schema_of_variant(data) = 'DATE' THEN DATE'1970-01-01'::VARIANT
WHEN schema_of_variant(data) = 'DOUBLE' THEN 0.00::VARIANT
ELSE NULL::VARIANT
END;

Integer型は VARIANT 内で BIGINT に拡張されるため、INT や TINYINT ではなく BIGINT で Branch を作成します。

STRUCT、ARRAY、およびMAP列をマスクする​

VARIANT アプローチは複雑な型のカラムもマスクし、上記の数値の例をネストされたデータに拡張します。STRUCT、ARRAY、または MAP 列は VARIANT として関数に渡され、Databricks は関数が返す値を列の宣言された型にキャストし直します。返される値は入力と同じスキーマを持っている必要があります。そうでない場合、キャストが失敗し、クエリーでエラーが発生します。

注記

STRUCT 列は Databricks Runtime 18.1 以降でサポートされています。ARRAY および MAP 列は、Databricks Runtime 19 以降でサポートされています。このキャストは、一般的な SQL やテーブルレベルのマスクではなく、ABAC 列マスクおよび行フィルターのポリシー内でのみ機能します。

次の例の関数は、特定のSTRUCT、ARRAY、およびMAPの型をマスクします。マスクする必要がある各スキーマの WHEN Branch を追加します:

SQL
CREATE OR REPLACE FUNCTION generic_mask(val VARIANT)
RETURNS VARIANT
RETURN CASE
-- STRUCT<id: INT, ssn: STRING>: keep id, redact ssn
WHEN schema_of_variant(val) = 'OBJECT<id: BIGINT, ssn: STRING>' THEN
to_variant_object(named_struct('id', val:id, 'ssn', 'xxx-xx-xxxx'))
-- ARRAY<STRING>: return a single redacted element
WHEN schema_of_variant(val) = 'ARRAY<STRING>' THEN
to_variant_object(array('redacted'))
-- MAP<STRING, STRING>: redact every value
WHEN schema_of_variant(val) = 'OBJECT<key1: STRING, key2: STRING>' THEN
to_variant_object(map('key1', 'redacted', 'key2', 'redacted'))
ELSE NULL::VARIANT
END;

それぞれの WHEN Branch では、次のセクションで説明する 2 つの処理が行われます。

  1. VARIANT スキーマを特定する。各 VARIANT スキーマには独自のマスキングロジックが必要であるため、関数は schema_of_variant(val) が返すスキーマの文字列で分岐し、それぞれに適切な機密情報の除外を適用します。
  2. マスクされた値を再構築します。カラムの型で編集された値を構築し、それを to_variant_object() でラップして VARIANT を返します。

スキーマがいずれの Branch とも一致しない値は、ELSE にフォールスルーします。

VARIANT スキーマを特定する​

列の宣言された型ではなく、値の VARIANT スキーマに対して一致させます。VARIANT にキャストするとデータが正規化されるため、スキーマが列の定義と異なる場合があります。一般的な例を次に示します:

列のタイプ

schema_of_variant() 結果

注

ARRAY<STRING>

ARRAY<STRING>

ARRAY<INT>

ARRAY<BIGINT>

Integer型は BIGINT に拡張されます。

STRUCT<id: INT, name: STRING>

OBJECT<id: BIGINT, name: STRING>

STRUCT およびMAP列の両方がOBJECTになります。

STRUCT<name: STRING, id: INT>

OBJECT<id: BIGINT, name: STRING>

フィールドは、宣言順ではなく、キーのアルファベット順に並べ替えられます。

ARRAY<STRUCT<id: INT, name: STRING>>

ARRAY<OBJECT<id: BIGINT, name: STRING>>

MAP<STRING, STRING> 保持 {a: 'x'}

OBJECT<a: STRING>

行によって異なります:各行のキーによってスキーマが決まります。

MAP<STRING, STRING> 保持 {a: 'x', b: 'y'}

OBJECT<a: STRING, b: STRING>

同じ列の異なる行によって、異なるスキーマが生成されます。

MAP<STRING, STRING> 保持 {a: null}

OBJECT<a: VOID>

null値は VOID になります。

MAP<STRING, STRUCT<id: INT, name: STRING>> 保持 {a: ...}

OBJECT<a: OBJECT<id: BIGINT, name: STRING>, ...>

列のタイプ

schema_of_variant() 結果

注

ARRAY<STRING>

ARRAY<STRING>

ARRAY<INT>

ARRAY<BIGINT>

Integer型は BIGINT に拡張されます。

STRUCT<id: INT, name: STRING>

OBJECT<id: BIGINT, name: STRING>

STRUCT およびMAP列の両方がOBJECTになります。

STRUCT<name: STRING, id: INT>

OBJECT<id: BIGINT, name: STRING>

フィールドは、宣言順ではなく、キーのアルファベット順に並べ替えられます。

ARRAY<STRUCT<id: INT, name: STRING>>

ARRAY<OBJECT<id: BIGINT, name: STRING>>

MAP<STRING, STRING> 保持 {a: 'x'}

OBJECT<a: STRING>

行によって異なります:各行のキーによってスキーマが決まります。

MAP<STRING, STRING> 保持 {a: 'x', b: 'y'}

OBJECT<a: STRING, b: STRING>

同じ列の異なる行によって、異なるスキーマが生成されます。

MAP<STRING, STRING> 保持 {a: null}

OBJECT<a: VOID>

null値は VOID になります。

MAP<STRING, STRUCT<id: INT, name: STRING>> 保持 {a: ...}

OBJECT<a: OBJECT<id: BIGINT, name: STRING>, ...>

マスクされた値を再構築する​

一致するスキーマごとに、同じ構造を持つ機密情報除外済みの値を構築し、それを to_variant_object() でラップします。

  • named_struct() を使用して STRUCT を再構築し、必要なフィールドを残して残りを置き換えます。
  • array()を使用してARRAYを再構築します。
  • map() を使用して、除外された値を持つ MAP を再構築します。

Databricks は返された VARIANT をカラムの宣言された型にキャストし直すため、再構築された値はそれぞれその型にキャスト可能である必要があります。

VARIANT マスクをテストする​

関数をポリシーにアタッチする前に、プレーンクエリーでテストしてマスクされた出力を確認できます。次の関数は ARRAY<STRUCT<id: BIGINT, value: FLOAT>> 列をマスクし、その他のスキーマに対してエラーを発生させます。

SQL
CREATE OR REPLACE FUNCTION mask_points(v VARIANT)
RETURNS VARIANT
RETURN CASE
WHEN schema_of_variant(v) = 'ARRAY<OBJECT<id: BIGINT, value: FLOAT>>' THEN
to_variant_object(array(named_struct('id', 1, 'value', 2.1)))
ELSE raise_error('Unexpected VARIANT schema: ' || schema_of_variant(v))
END;

to_variant_object() で列を変換し、マスキング関数を適用し、variant_get() を使用してマスクされた VARIANT を元の列の型にキャストし直します。これは、ポリシーがランタイムで実行する処理を反映しています:

SQL
SELECT variant_get(mask_points(to_variant_object(points)), '$', typeof(points)) AS masked
FROM my_catalog.my_schema.my_table;

制限事項​

  • CHAR、VARCHAR、GEOMETRY、GEOGRAPHY、または TIME を含む複雑な列は、VARIANT でマスクできません。
  • MAP キーはSTRINGである必要があります。MAP<INT, ...>型、MAP<DATE, ...>型などの列は変換されません。

機密性の高い列にタグが付けられるまでアクセスを禁止する​

一般的なガバナンスパターンとしては、データが機密指定されているかどうかに基づいてアクセスを制御する方法がある。これは、デフォルトの制限タグと、分類ステータスに応じて異なるレベルの保護を適用するポリシーを使用して実装できます。

  1. 自動化またはカタログまたはスキーマレベルでタグを適用してタグを継承することにより、デフォルトですべての新しいオブジェクトにclassification : unverifiedのようなタグを適用します。これにより、カタログまたはスキーマに追加された新しいテーブルは自動的にタグを継承します。
  2. タグclassification : unverifiedが付いたテーブルへのアクセスをブロックする行フィルタポリシーを作成します。
  3. classification : unverifiedタグが存在しなくなったテーブル上の機密性の高い列をマスクする列マスクポリシーを作成します。
  4. データスチュワードは分類が完了するとタグを更新します。 ブロッキングポリシーが一致しなくなったため、マスキングポリシーが適用されます。
SQL
-- Block access to unverified tables for all non-admin users
CREATE FUNCTION catalog.schema.block_all() RETURNS BOOLEAN
RETURN FALSE;

CREATE POLICY block_unverified
ON CATALOG my_catalog
ROW FILTER catalog.schema.block_all
TO `account users` EXCEPT `data_admins`
FOR TABLES
WHEN has_tag_value('classification', 'unverified');

機密データが分類された後も保護するために、 classification : unverifiedタグが存在しなくなったときに有効になる列マスクポリシーを定義します。

SQL
CREATE FUNCTION catalog.schema.mask_pii(val STRING)
RETURNS STRING
RETURN '***';

CREATE POLICY mask_reviewed_pii
ON CATALOG my_catalog
COLUMN MASK catalog.schema.mask_pii
TO `account users`
EXCEPT `data_admins`
FOR TABLES
WHEN NOT has_tag_value('classification', 'unverified')
MATCH COLUMNS (has_tag_value('pii', 'name') OR has_tag_value('pii', 'address')) AS m
ON COLUMN m;

正規表現なしの部分的な表示​

正規表現ではなく文字列操作を使用して、機密値の一部を明らかにする。正規表現に基づくマスキングは、行ごとに値全体をスキャンするため、大きなテキストフィールドではコストが高くなります( 「大きなテキストフィールドでの正規表現マスキングを避ける」を参照)。

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

一貫性ハッシュ(決定論的匿名化)​

一貫性ハッシュ(決定論的匿名化とも呼ばれる)は、機密データを複数のテーブル間で同じハッシュ値に置き換える。関数をDETERMINISTICとマークすることで、その関数が同じ入力に対して常に同じ結果を返すことをエンジンに伝えることができ、クエリの最適化に役立ちます。決定論的でエラーのない式を使用するを参照してください。

次の関数は一貫して文字列値をハッシュし、 versionを使用してキーのローテーションをサポートします。 ポリシーのUSING COLUMNS節を通じてversion数値をインクリメントし、以前のバージョンを使用していた履歴データを壊さずに新しいハッシュを生成します。 この関数は、ハッシュ化する前に元の値とバージョン番号を連結するため、同じ入力値で同じバージョンであれば、常に同じハッシュ値が生成されます。

SQL
CREATE FUNCTION pseudonymize(val STRING, version INT) RETURNS STRING
DETERMINISTIC
RETURN SHA2(CONCAT(val, CAST(version AS STRING)), 256);

クエリーを実行するユーザーの属性に基づいて列をマスクする​

備考

ベータ版

ABAC ポリシーの ID 属性は Beta 版です。これらを使用するには、アカウント管理者は次の操作を行う必要があります:

  • アカウント コンソールの Previews ページから、 Identity Attributes in ABAC ポリシー のプレビューを有効にします。See Manage アカウント-level previews.
  • アカウントのID属性プロビジョニングを構成します。ID属性を参照してください。

列マスクポリシーでは、クエリーを実行するユーザーのID属性を使用して、専用のグループを必要とせずに機密データをマスキングできます。例えば、department = HRを持つユーザーに対してはデータをマスキングせずに保持し、それ以外のユーザーに対してはマスキングすることができます。

これらのパターンでは、IDプロバイダーからユーザーにプロビジョニングされたID属性が必要であり、その関数はタグのみの条件とは異なる動作をするため、ポリシーの記述方法に影響します。これらを使用する前に、ID属性関数 および ID属性 を確認してください。

重要

ユーザーがその属性の値を持っていない場合、または属性キーが存在しない場合、関数は false に解決されます。この false の結果がアクセスを許可するのではなく制限するように条件を記述します。属性が一致しない場合にマスクが適用されるように、NOT で一致を否定します。例えば、WHEN NOT has_identity_attribute_value('department', 'HR') は部門が HR であるユーザーを除く全員に対して列をマスクします。また、欠落している値も false となるため、部門属性を持たないユーザーもマスクされます。逆のケースは避けてください。属性が一致する場合のみマスクする条件を設定すると、その属性に値を持たないユーザーはマスクされません。

評価の動作については、ID属性の条件をご覧ください。制限事項については、ポリシー条件におけるID属性 を参照してください。

固定値と一致させる​

部署がHRではないすべてのユーザーに対してssnをマスクします:

SQL
CREATE FUNCTION hr_catalog.people.mask_ssn(s STRING) RETURNS STRING RETURN '***-**-****';

CREATE OR REPLACE POLICY mask_ssn_non_hr
ON SCHEMA hr_catalog.people
COLUMN MASK hr_catalog.people.mask_ssn
TO `account users`
FOR TABLES
WHEN NOT has_identity_attribute_value('department', 'HR')
MATCH COLUMNS has_tag_value('pii', 'ssn') AS ssn_col
ON COLUMN ssn_col;

この例では、部門がHRであるユーザーは実際の値を確認します。他の部門のユーザーと、部門属性を持たないユーザーは、どちらもマスクされた値を確認します。

管理タグと照合する​

前の例ではポリシー内で特定の属性値 (HR) を指定しているため、複数の部門をカバーするには部門ごとに個別のポリシーを作成する必要があります。すべての部門を単一のポリシーでカバーするには、各テーブルに所有する部門のタグを付け、クエリーを実行するユーザーの department 属性をそのタグと比較します。この列は、ユーザーの部門がテーブルのdept_tag値と一致する場合にのみ表示されます:

SQL
CREATE FUNCTION prod.sales.mask_ssn(s STRING) RETURNS STRING RETURN '***-**-****';

CREATE OR REPLACE POLICY mask_unless_dept_matches
ON SCHEMA prod.sales
COLUMN MASK prod.sales.mask_ssn
TO `account users`
FOR TABLES
WHEN NOT has_identity_attribute_tag_match('department', 'dept_tag')
MATCH COLUMNS has_tag_value('pii', 'ssn') AS ssn_col
ON COLUMN ssn_col;

属性のキーと値はどちらも大文字と小文字が区別され、値は厳密に比較されます。Financeとfinanceは一致しません。

ユーザーに代わって行動する外部エージェントのアクセスを制限する​

備考

ベータ版

ABACポリシーのコンテキスト属性はベータ版です。これらを使用するには、アカウント管理者がアカウント コンソールの [プレビュー] ページから [UC ABAC Context Attributes] プレビューを有効にする必要があります。「アカウント レベルのプレビューを管理する」を参照してください。

Context attributes can be used to restrict data access for requests made on a user's behalf through an OAuth application (user-to-machine (U2M) authorization).OAuth経由で接続されているエージェントの場合、ユーザーがワークスペースで直接クエリーを実行した際にはデータを読み取ることができる場合でも、この設定を使用して、ユーザーに代わって動作するときにデータにアクセスするのを防ぐことができます。

Databricks の CLI、SDK、または SQL Statement Execution API を介した OAuth 認証によるアクセスは、ユーザーが手動でクエリを実行している場合でも、request.is_on_behalf_of を 'true' に設定します。個人用アクセストークン (PAT) で認証されたアクセスでは設定されません。Genie アクセスはこのメカニズムでは取得できません。

これらのパターンは、コンテキスト属性関数を使用します。利用可能な属性と動作については、コンテキスト属性関数 (ベータ版) を参照してください。

エージェントをDatabricksに接続する​

コンテキスト属性を使用するには、カスタム OAuth アプリケーションを使用してエージェントを接続します。

  1. アカウント管理者は、アカウント コンソールから UC ABAC Context Attributes プレビューを有効にします。「Databricks プレビューの管理」を参照してください。
  2. アカウント管理者は、アカウントコンソールでカスタム OAuth アプリケーションを登録するし、そのクライアント ID を記録します。
  3. エージェントを、そのOAuthアプリケーションを介してDatabricks管理MCPに接続します。カスタムOAuthクライアントの設定を参照してください。

組み込みの databricks-cli クライアントを使用するエージェントも OAuth 経由で認証されるため、request.is_on_behalf_of は 'true' を読み取ります。ただし、どちらも databricks-cli クライアント ID を共有しているため、そのリクエストを手動による CLI の使用と区別することはできません。特定のアプリケーションを管理するには、カスタム OAuth アプリケーションを登録し、それを通じてエージェントを接続します。

警告

ポリシーでカバーされていないパスを通じてエージェントがデータにアクセスできないことを確認してください:

  • request.is_on_behalf_of に基づいてアクセスを制限する場合は、エージェントが PAT で認証できないようにしてください。PAT は request.is_on_behalf_of を 'true' に設定しないため、その属性に対する条件はそれを制限しません。
  • request.client_idに基づいてアクセスを制限する場合は、汎用的なdatabricks-cliクライアントなど、条件でカバーされていないクライアント経由でエージェントが接続できないようにしてください。

代理リクエストの列をマスクする​

登録済みの OAuth アプリケーションを通じて動作するエージェントなど、ユーザーに代わって実行されるリクエストについては ssn をマスクし、直接クエリーを実行する場合はマスクを解除したままにします:

SQL
CREATE FUNCTION hr_catalog.people.mask_ssn(s STRING) RETURNS STRING RETURN '***-**-****';

CREATE OR REPLACE POLICY mask_ssn_for_agents
ON SCHEMA hr_catalog.people
COLUMN MASK hr_catalog.people.mask_ssn
TO `account users`
FOR TABLES
WHEN has_context_attribute_value('request.is_on_behalf_of', 'true')
MATCH COLUMNS has_tag_value('pii', 'ssn') AS ssn_col
ON COLUMN ssn_col;

この例では、直接クエリーを実行すると実際の値が返され、代理リクエストではマスクされた値が表示されます。CLIおよびSQLステートメント実行APIを使用すると、request.is_on_behalf_ofも'true'を読み取るため、このポリシーはそれらのリクエストに対しても列をマスクします。代わりに特定のアプリケーションをターゲットにするには、request.client_id をそのアプリケーションのクライアント ID と照合します。

列を承認済みアプリケーションに制限する​

OAuth クライアント ID によって識別される承認済みアプリケーションからのリクエストを除く、すべての外部リクエストに対して ssn をマスクします:

SQL
CREATE OR REPLACE POLICY mask_ssn_unapproved_apps
ON SCHEMA hr_catalog.people
COLUMN MASK hr_catalog.people.mask_ssn
TO `account users`
FOR TABLES
WHEN NOT has_context_attribute_value('request.client_id', '<your-app-client-id>')
MATCH COLUMNS has_tag_value('pii', 'ssn') AS ssn_col
ON COLUMN ssn_col;

どのアプリケーションがリクエストを行ったかを確認するには、監査Logsの identity_metadata.acting_resource フィールドを調査してください。

列のみの述語による行フィルタリング​

テーブルの列のみを参照する単純なブール論理を使用して行をフィルタリングします。 列のみの述語を使用すると述語プッシュダウンが有効になり、エンジンはスキャン中に無関係なデータをスキップできます(保護されたテーブルでの述語プッシュダウンについて理解するを参照)。

SQL
CREATE FUNCTION filter_by_region(region STRING, allowed STRING)
RETURNS BOOLEAN
DETERMINISTIC
RETURN array_contains(split(allowed, ','), lower(region));

許可された地域を定数として渡すポリシーと組み合わせて使用します。

SQL
CREATE POLICY regional_access
ON CATALOG analytics
ROW FILTER filter_by_region
TO 'emea_team'
FOR TABLES
MATCH COLUMNS has_tag('region') AS rgn
USING COLUMNS (rgn, 'emea,apac');

複数の関連列にわたる行フィルタリング​

テーブルに、関連する属性を表す複数の列(たとえば、 ship_to_countryとbill_to_country )がある場合、それらを個別のタグ条件で照合し、両方を単一のUDFに渡すことができます。これにより、列ごとに個別のポリシーを作成する必要がなくなります。ポリシーには、 MATCH COLUMNS句に最大 3 つの列式を含めることができます (ポリシー クォータを参照)。

SQL
CREATE FUNCTION filter_by_countries(ship_country STRING, bill_country STRING, allowed STRING)
RETURNS BOOLEAN
DETERMINISTIC
RETURN array_contains(split(allowed, ','), lower(ship_country))
OR array_contains(split(allowed, ','), lower(bill_country));

CREATE POLICY regional_orders
ON SCHEMA prod.orders
ROW FILTER filter_by_countries
TO analysts
FOR TABLES
WHEN has_tag_value('sensitivity', 'high')
MATCH COLUMNS
has_tag('ship_country') AS ship,
has_tag('bill_country') AS bill
USING COLUMNS (ship, bill, 'us,ca,mx');

アナリストは、配送国または請求国のいずれかが許可リストに含まれている注文のみを閲覧できます。

ABAC ポリシー UDF のルックアップ テーブル​

アクセスルールがユーザーごとに異なり、ポリシーのTO / EXCEPT条項だけでは表現できない場合は、小さなルックアップテーブルに対してアクセス権限を確認できます。可能であればTO / EXCEPTを使用してください。これはプリンシパルをターゲットにするための推奨されるアプローチです(プリンシパルをターゲットにするためのアプローチを参照)。オプティマイザがサブクエリをブロードキャストハッシュ結合に変換するように、ルックアップテーブルを小さく保ってください( 「ルックアップテーブルを小さく保つ」を参照)。

SQL
CREATE TABLE access_rules (
principal VARCHAR(255),
priority VARCHAR(64)
);

INSERT INTO access_rules VALUES
('alice@company.com', '1-URGENT'),
('alice@company.com', '2-HIGH'),
('bob@company.com', '1-URGENT');

CREATE FUNCTION priority_allowed(o_priority STRING) RETURNS BOOLEAN
RETURN EXISTS (
SELECT 1 FROM access_rules
WHERE principal = session_user() AND priority = o_priority
);

CREATE POLICY priority_filter
ON CATALOG operations
ROW FILTER priority_allowed
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('priority') AS pri
USING COLUMNS (pri);