行フィルターと列マスクを使用した機密テーブル データのフィルター処理

プレビュー

この機能はパブリックプレビュー段階です。

この記事では、行フィルター、列マスク、およびマッピング テーブルを使用して、テーブル内の機密データをフィルター処理するためのガイダンスと例を示します。 これらの機能には Unity Catalog が必要です。

行フィルターとは

行フィルターを使用すると、テーブルにフィルターを適用して、クエリがフィルター条件を満たす行のみを返すようにすることができます。 行フィルターは、 SQL ユーザー定義関数 (UDF)として実装します。 Python および Scala UDF もサポートされていますが、SQL UDF にラップされている場合に限ります。

列マスクとは

列マスクを使用すると、表の列にマスキング関数を適用できます。 マスキング関数はクエリを評価し、ターゲットカラムの各参照をマスキング関数の結果に置き換えます。 ほとんどのユースケースでは、列マスクは、元の列値を返すか、呼び出し元のユーザーのIDに基づいて編集するかを決定します。 列マスクは、SQL UDF として記述される式、または SQL UDF にラップされた Python または Scala UDF として記述される式です。

各表の列には、マスキング関数を 1 つだけ適用できます。 マスキング関数は、列のマスクされていない値を入力として受け取り、その結果としてマスクされた値を返します。 マスキング関数の戻り値は、マスキングされる列と同じ型である必要があります。 マスキング関数は、追加の列を入力として受け取り、それをマスキング ロジックで使用することもできます。

これらのフィルターと動的ビューの違いは何ですか?

動的ビュー、行フィルター、列マスクを使用すると、テーブルに複雑なロジックを適用し、クエリ時にフィルター処理の決定を処理できます。

動的ビューは、1 つ以上のソース テーブルの抽象化された読み取り専用ビューです。 ユーザーは、ソース テーブルに直接アクセスしなくても動的ビューにアクセスできます。 動的ビューを作成すると、新しいテーブル名が定義されますが、この名前は、同じスキーマ内に存在するソース テーブルや他のテーブルやビューの名前と一致してはなりません。

一方、行フィルターまたは列マスクをターゲット表に関連付けると、新しい表名を導入することなく、対応するロジックが表自体に直接適用されます。 後続の照会は、引き続き元の名前を使用してターゲット表を直接参照できます。

フィルターやマスクなどの変換ロジックを読み取り専用テーブルに適用する必要がある場合、およびユーザーが別の名前を使用して動的ビューを参照できる場合は、動的ビューを使用します。 Delta Sharingを使用してデータを共有するときにデータをフィルター処理する場合は、動的ビューを使用する必要があります。 特定のデータに対してフィルター処理や式の実行を行いながら、ユーザーが元の名前を使用してテーブルにアクセスできるようにする場合は、行フィルターと列マスクを使用します。

始める前に

行フィルターと列マスクを表に追加するには、以下が必要です。

  • Unity Catalog が有効になっているワークスペース。

  • Unity Catalogに登録されている関数。 これは、SQL UDF、または Unity Catalog に登録され、SQL UDF にラップされた Python または Scala UDF になります。 詳しくは、 ユーザー定義関数 (UDF) とは列マスク節、および ROW FILTER 節を参照してください。

また、次の要件も満たしている必要があります。

  • 行フィルターまたは列マスクを表に追加する関数を割り当てるには、その関数に対する EXECUTE 特権、スキーマに対する USE SCHEMA 特権、および親カタログに対する USE CATALOG 特権が必要です。

  • 新しいテーブルの作成時にフィルターまたはマスクを追加するには、スキーマに対する CREATE TABLE 権限も必要です。

  • 既存のテーブルを変更してフィルターまたはマスクを追加するには、テーブルの所有者であるか、テーブルに対する MODIFY 権限を持っている必要があります。

行フィルターまたは列マスクを持つテーブルにアクセスするには、コンピュート リソースが次の要件を満たしている必要があります。

  • Databricks Runtime 12.2 LTS以上の共有アクセス モード クラスター、またはSQLウェアハウス。

行フィルターを適用する

行フィルターを作成するには、フィルター ポリシーを定義する関数 (UDF) を記述し、それをテーブルに適用します。 各テーブルには、行フィルターを 1 つだけ設定できます。 行フィルターは 0 個以上の入力 引数 を受け入れます。各入力 引数 は対応するテーブルの 1 つの列にバインドされます。

カタログ エクスプローラーまたは SQL コマンドを使用して行フィルターを適用できます。 Catalog Explorer の説明では、関数がすでに作成されており、Unity Catalog に登録されていることを前提としています。 SQL の説明には、行フィルター関数を作成し、それをテーブルに適用する例が含まれています。

  1. Databricksワークスペースで、カタログ アイコンカタログ

  2. フィルター処理するテーブルを参照または検索します。

  3. [概要]タブで、 [行フィルター: フィルターの追加]をクリックします。

  4. [ 行フィルターの追加 ] ダイアログで、フィルター関数を含むカタログとスキーマを選択し、関数を選択します。

  5. 展開されたダイアログで、関数定義を表示し、関数ステートメントに含まれる列と一致するテーブル列を選択します。

  6. [追加] をクリックします。

テーブルからフィルターを削除するには、[ fx Row filter ] をクリックし、[ Remove] をクリックします。

行フィルターを作成して既存のテーブルに追加するには、 CREATE FUNCTION を使用し、 ALTER TABLEを使用して関数を適用します。 また、 CREATE TABLEを使用してテーブルを作成するときに関数を適用することもできます。

  1. 行フィルターを作成します。

    CREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
    RETURN {filter clause whose output must be a boolean};
    
  2. 列名を使用して、行フィルターをテーブルに適用します。

    ALTER TABLE <table_name> SET ROW FILTER <function_name> ON (<column_name>, ...);
    

その他の構文例:

  • テーブルから行フィルターを削除します。

    ALTER TABLE <table_name> DROP ROW FILTER;
    
  • 行フィルターを変更します。

    Run a DROP FUNCTION statement to drop the existing function, or use CREATE OR REPLACE FUNCTION to replace it.
    
  • 行フィルターを削除します。

    ALTER TABLE <table_name> DROP ROW FILTER;
    DROP FUNCTION <function_name>;
    

    注:

    関数を削除する前に、 ALTER TABLE ... DROP ROW FILTERコマンドを実行する必要があります。 そうしないと、テーブルはアクセスできない状態になります。

    この方法でテーブルにアクセスできなくなった場合は、テーブルを変更し、 ALTER TABLE <table_name> DROP ROW FILTER;を使用して孤立した行フィルター参照を削除します。

ROW FILTER 句も参照してください。

行フィルターの例

この例では、リージョンUSのグループadminのメンバーに適用される SQL ユーザー定義関数を作成します。

このサンプル関数をsalesテーブルに適用すると、 adminグループのメンバーはテーブル内のすべてのレコードにアクセスできるようになります。 関数が管理者以外によって呼び出された場合、 RETURN_IF 条件は失敗し、 region='US' 式が評価され、 US リージョンのレコードのみを表示するようにテーブルがフィルタリングされます。

CREATE FUNCTION us_filter(region STRING)
RETURN IF(IS_ACCOUNT_GROUP_MEMBER('admin'), true, region='US');

関数を行フィルターとしてテーブルに適用します。 その後、 sales テーブルからの後続のクエリは、行のサブセットを返します。

CREATE TABLE sales (region STRING, id INT);
ALTER TABLE sales SET ROW FILTER us_filter ON (region);

行フィルターを無効にします。 その後、 sales テーブルからのユーザー クエリでは、テーブル内のすべての行が返されます。

ALTER TABLE sales DROP ROW FILTER;

CREATE TABLE ステートメントの一部として行フィルターとして適用された関数を含むテーブルを作成します。その後、 sales テーブルからの今後のクエリは、それぞれ行のサブセットを返します。

CREATE TABLE sales (region STRING, id INT)
WITH ROW FILTER us_filter ON (region);

列マスクの適用

列マスクを適用するには、関数 (UDF) を作成し、それをテーブル列に適用します。

カタログ エクスプローラーまたは SQL コマンドを使用して列マスクを適用できます。 Catalog Explorer の説明では、関数がすでに作成されており、Unity Catalog に登録されていることを前提としています。 SQL の説明には、列マスク関数を作成し、それをテーブル列に適用する例が含まれています。

  1. Databricksワークスペースで、カタログ アイコンカタログ

  2. テーブルを参照または検索します。

  3. 「概要」タブで、列マスクを適用する行を見つけて、編集アイコンマスク編集アイコン。

  4. 列マスクの追加 」ダイアログで、フィルター関数を含むカタログとスキーマを選択し、関数を選択します。

  5. 展開されたダイアログで、関数定義を表示します。 関数に、マスクされる列に加えて 引数 が含まれる場合は、それらの追加の関数 引数 をキャストするテーブル列を選択します。

  6. [追加] をクリックします。

表から列マスクを削除するには、表の行で「 fx 列マスク 」をクリックし、「 除去」をクリックします。

列マスクを作成して既存の表列に追加するには、 CREATE FUNCTION を使用し、 ALTER TABLEを使用してマスキング関数を適用します。 また、 CREATE TABLEを使用してテーブルを作成するときに関数を適用することもできます。

マスキング機能を適用するには、 SET MASK を使用します。 MASK句内では、Databricks の組み込みランタイム関数のいずれかを使用したり、他のユーザー定義関数を呼び出したりすることができます。 一般的な使用例としては、 current_user( )を使用して関数を実行している呼び出しユーザーの ID を検査したり、 is_account_group_member( )を使用してそのユーザーが所属するグループを取得したりすることが挙げられます。 詳細については、 「列マスク句」および「組み込み関数」を参照してください。

  1. 列マスクを作成します。

    CREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
    RETURN {expression with the same type as the first parameter};
    
  2. 列マスクを既存の表の列に適用します。

    ALTER TABLE <table_name> ALTER COLUMN <col_name> SET MASK <mask_func_name> USING COLUMNS <additional_columns>;
    

その他の構文例:

  • 表の列から列マスクを削除します。

    ALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK;
    
  • 列マスクの変更: 既存の関数 DROP か、 CREATE OR REPLACE TABLEを使用します。

  • 列マスクを削除します。

    ALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK;
    DROP FUNCTION <function_name>;
    

    注:

    関数を削除する前にALTER TABLEコマンドを実行する必要があります。そうしないと、テーブルがアクセス不能な状態になります。

    この方法でテーブルにアクセスできなくなった場合は、テーブルを変更し、 を使用して孤立したマスク参照 ALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK;を削除します。

列マスクの例

この例では、 ssn列をマスクするユーザー定義関数を作成し、 HumanResourceDeptグループのメンバーであるユーザーだけがその列の値を表示できるようにします。

CREATE FUNCTION ssn_mask(ssn STRING)
  RETURN CASE WHEN is_member('HumanResourceDept') THEN ssn ELSE '***-**-****' END;

新しい関数を列マスクとして表に適用します。 列マスクは、表の作成時または作成後に追加できます。

--Create the `users` table and apply the column mask in a single step:

CREATE TABLE users (
  name STRING,
  ssn STRING MASK ssn_mask);
--Create the `users` table and apply the column mask after:

CREATE TABLE users
  (name STRING, ssn STRING);

ALTER TABLE users ALTER COLUMN ssn SET MASK ssn_mask;

クエリを実行するユーザーがHumanResourceDeptグループのメンバーでない場合、そのテーブルに対するクエリではマスクされたssn列の値が返されるようになりました。

SELECT * FROM users;
  James  ***-**-****

列マスクを無効にして、クエリが ssn 列の元の値を返すようにするには、次のようにします。

ALTER TABLE users ALTER COLUMN ssn DROP MASK;

マッピング テーブルを使用してアクセス制御リストを作成する

行レベルのセキュリティを実現するには、マッピング テーブル (またはアクセス制御リスト) を定義することを検討してください。 各マッピング テーブルは、元のテーブル内のどのデータ行が特定のユーザーまたはグループにアクセス可能かをエンコードする包括的なマッピング テーブルです。 マッピング テーブルは、直接結合によってファクト テーブルと簡単に統合できるため便利です。

この手法は、カスタム要件を持つ多くのユースケースに対処する上で有益であることが証明されています。 たとえば、次のようになります。

  • ログインしたユーザーに基づいて制限を課し、特定のユーザー グループに対して異なるルールを適用します。

  • 組織構造などの複雑な階層を作成し、多様なルールセットを必要とする。

  • 外部ソース システムから複雑なセキュリティ モデルを複製します。

このようにマッピング テーブルを採用することで、これらの困難なシナリオに効果的に対処し、堅牢な行レベルおよび列レベルのセキュリティ実装を確保できます。

マッピング テーブルの例

マッピングテーブルを使用して、現在のユーザーがリストに含まれているかどうかを確認します。

USE CATALOG main;

新しいマッピングテーブルを作成します。

DROP TABLE IF EXISTS valid_users;

CREATE TABLE valid_users(username string);
INSERT INTO valid_users
VALUES
  ('fred@databricks.com'),
  ('barney@databricks.com');

新しいフィルターを作成します。

注:

呼び出し元として実行されるユーザー コンテキストをチェックする関数 ( CURRENT_USER関数やIS_MEMBER関数など) を除き、すべてのフィルターは定義者の権限で実行されます。

この例では、関数は現在のユーザーが valid_users テーブルにあるかどうかを確認します。 ユーザーが見つかった場合、関数は true を返します。

DROP FUNCTION IF EXISTS row_filter;

CREATE FUNCTION row_filter()
  RETURN EXISTS(
    SELECT 1 FROM valid_users v
    WHERE v.username = CURRENT_USER()
);

次の例では、テーブルの作成時に行フィルターを適用します。 また、後で ALTER TABLE ステートメントを使用してフィルターを追加することもできます。 テーブル全体に適用する場合は、 ON () 構文を使用します。 特定の行には、 ON (row);を使用します。

DROP TABLE IF EXISTS data_table;

CREATE TABLE data_table
  (x INT, y INT, z INT)
  WITH ROW FILTER row_filter ON ();

INSERT INTO data_table VALUES
  (1, 2, 3),
  (4, 5, 6),
  (7, 8, 9);

テーブルからデータを選択します。 これは、ユーザーが valid_users テーブルにいる場合にのみデータを返します。

SELECT * FROM data_table;

列の値に関係なく、テーブル内のすべての行を表示するために常にアクセス権を持つアカウントで構成されるマッピング テーブルを作成します。

CREATE TABLE valid_accounts(account string);
INSERT INTO valid_accounts
VALUES
  ('admin'),
  ('cstaff');

ここで、行内のすべての列の値が 5 未満の場合、または呼び出し元のユーザーが上記のマッピング テーブルのメンバーである場合にtrueを返す SQL UDF を作成します。

CREATE FUNCTION row_filter_small_values (x INT, y INT, z INT)
  RETURN (x < 5 AND y < 5 AND z < 5)
  OR EXISTS(
    SELECT 1 FROM valid_accounts v
    WHERE IS_ACCOUNT_GROUP_MEMBER(v.account));

最後に、SQL UDF を行フィルターとしてテーブルに適用します。

ALTER TABLE data_table SET ROW FILTER row_filter_small_values ON (x, y, z);

サポートされている機能と形式

  • SQL ワークロード用の Databricks SQL および Databricks ノートブックがサポートされています。

  • MODIFY権限を持つユーザーによる DML コマンドがサポートされています。 フィルターとマスクは、 UPDATE ステートメントと DELETE ステートメントによって読み取られるデータに適用され、書き込まれるデータ ( INSERTを含む) には適用されません。

  • サポートされているデータ形式:

    • 管理対象テーブルと外部テーブル用の Delta と Parquet。

    • レイクハウスフェデレーション を使用してUnity Catalog に登録されたフォーリンテーブルのその他の複数のデータ形式。

  • SQL、Python、Scala UDF は、Unity Catalog に登録されている限り、行フィルターまたは列マスク関数としてサポートされます。 Python および Scala UDF は SQL UDF でラップする必要があります。

  • 列マスクまたは行フィルターを持つ表のビューがサポートされています。

  • Delta Lakeチェンジデータ フィードは、スキーマがターゲット テーブルに適用される行フィルターおよび列マスクと互換性がある限りサポートされます。

  • MERGE ソース テーブル、ターゲット テーブル、またはその両方で行フィルターと列マスクが使用されている場合に、ステートメントがサポートされます。 これには、単純なサブクエリを含む行フィルター関数を含むテーブルが含まれますが、次のセクションに示す制限があります。

  • Databricks SQL マテリアライズド ビューと Databricks SQL ストリーミング テーブルは、行フィルターと列マスクをサポートします (パブリック プレビュー)。

    • Databricks SQL マテリアライズド ビューまたはストリーミング テーブルに行フィルターと列マスクを追加できます。

    • 行フィルターと列マスクを含むテーブルに、Databricks SQL マテリアライズド ビューまたはストリーミング テーブルを定義できます。

制限事項

  • 12.2 LTS より前の Databricks Runtime バージョンでは、行フィルターまたは列マスクはサポートされません。 これらのランタイムは安全に失敗するため、これらのランタイムのサポートされていないバージョンからテーブルにアクセスしようとしても、データは返されません。

  • Delta Live Tables で宣言されたマテリアライズド ビューとストリーミング テーブルは、行フィルターまたは列マスクをサポートしていません。

  • Delta Sharing行レベルのセキュリティまたは列マスクでは機能しません。

  • タイムトラベルは、行レベルのセキュリティまたは列マスクでは機能しません。

  • テーブル サンプリングは、行レベルのセキュリティまたは列マスクでは機能しません。

  • ポリシーを持つテーブル内のファイルへのパスベースのアクセスはサポートされていません。

  • 元のポリシーへの循環依存関係を持つ行フィルターまたは列マスク ポリシーはサポートされていません。

  • ディープクローンとシャロークローンはサポートされていません。

  • MERGE ステートメントは、ネスト、集計、ウィンドウ、制限、または非決定論的関数を含む行フィルター ポリシーを持つテーブルをサポートしません。

  • Delta Lake APIsサポートされていません。

  • SHOW CREATE TABLE マテリアライズド ビューおよびストリーミング テーブルでは、行フィルターと列マスクの情報が表示されません。

シングルユーザーコンピュート制限

シングルユーザー クラスターからアクセスするテーブルには、行フィルターや列マスクを追加しないでください。 これは通常、ワークフロー (ジョブ) のコンテキストで実行されます。 パブリック プレビュー中は、フィルターまたはマスクが適用されている場合、単一のユーザー クラスターからテーブルにアクセスすることはできません。