行フィルターと列マスクを使用した機密性の高いテーブルデータのフィルタリング
この記事では、行フィルター、列マスク、マッピングテーブルを使用してテーブル内の機密データをフィルターするためのガイダンスと例を紹介します。これらの機能を利用するには、Unity Catalogが必要です。
行フィルターとは何ですか?
行フィルタを使用すると、テーブルにフィルタを適用して、クエリがフィルタ条件を満たす行のみを返すようにすることができます。 行フィルターは、 SQL ユーザー定義関数 (UDF) として実装します。 Python と Scala の UDFs もサポートされていますが、SQL UDFs でラップされている場合に限ります。
列マスクとは
列マスクを使用すると、テーブル列にマスキング機能を適用できます。 マスキング関数は、クエリの実行時に評価され、ターゲットカラムの各参照をマスキング関数の結果で置き換えます。 ほとんどのユースケースでは、列マスクは、呼び出し元のユーザーの ID に基づいて、元の列値を返すか、編集するかを決定します。 列マスクは、SQL UDFs、またはSQL UDFsにラップされたPythonまたはScala UDFsとして記述された式です。
各テーブル列には、マスキング関数を 1 つだけ適用できます。 マスキング関数は、列のマスクされていない値を入力として受け取り、マスクされた値を結果として返します。 マスキング関数の戻り値は、マスキングされる列と同じ型である必要があります。 マスキング関数は、追加の列を入力パラメーターとして受け取り、それらをマスキング ロジックで使用することもできます。
これらのフィルターと動的ビューの違いは何ですか?
ダイナミックビュー、行フィルター、列マスクを使用すると、複雑なロジックをテーブルに適用し、クエリーのランタイムにフィルタリングの決定を処理できます。
動的ビューは、1 つ以上のソーステーブルの抽象化された読み取り専用ビューです。ユーザーは、ソース・テーブルに直接アクセスしなくても、動的ビューにアクセスできます。 動的ビューの作成では、新しいテーブル名を定義しますが、この名前は、同じスキーマに存在するソース・テーブルや他のテーブルおよびビューの名前と一致してはなりません。
一方、行フィルターまたは列マスクをターゲット テーブルに関連付けると、新しいテーブル名を導入することなく、対応するロジックがテーブル自体に直接適用されます。後続のクエリでも引き続き、元の名前を使用してターゲット テーブルを直接参照できます。
動的ビューは、フィルターやマスクなどの変換ロジックを読み取り専用テーブルに適用する必要がある場合、およびユーザーが異なる名前を使用して動的ビューを参照することが許容される場合に使用します。 Delta Sharing を使用してデータを共有するときにデータをフィルター処理する場合は、動的ビューを使用する必要があります。 特定のデータに対してフィルターまたはコンピュート式を行いながら、ユーザーが元の名前を使用してテーブルにアクセスできるようにする場合は、行フィルターと列マスクを使用します。
始める前に
テーブルに行フィルターと列マスクを追加するには、次のものが必要です。
- Unity Catalog が有効になっているワークスペース。
- Unity Catalogに登録されている関数。この関数は、SQL UDF、または Unity Catalog に登録され、SQL UDF にラップされた Python または Scala UDF にすることができます。 詳細については、「ユーザー定義関数 (UDF) とは」、「列
mask
句」、および「ROW FILTER
句」を参照してください。
また、次の要件を満たす必要があります。
- 行フィルターまたは列マスクをテーブルに追加する関数を割り当てるには、関数の
EXECUTE
権限、スキーマのUSE SCHEMA
権限、親カタログのUSE CATALOG
権限が必要です。 - 新しい テーブルを作成するときにフィルターまたはマスクを追加する場合は、スキーマに対する
CREATE TABLE
権限が必要です。 - 既存の テーブルにフィルターまたはマスクを追加する場合は、テーブルの所有者である必要があります。
行フィルターや列マスクのあるテーブルにアクセスするには、コンピュートリソースが次の要件のいずれかを満たしている必要があります。
- A SQLウェアハウス.
- Databricks Runtime 12.2 LTS 以降の標準アクセス モード (以前の共有アクセス モード)。
- Databricks Runtime 15.4 LTS 以降の専用アクセス モード (旧称シングル ユーザー アクセス モード)。
Databricks Runtime 15.3以下では、専用のコンピュートを使用して行フィルターや列マスクを読み取ることはできません。
Databricks Runtime 15.4 LTS 以降で提供されているデータ フィルタリングを利用するには、 ワークスペースがサーバレス コンピュートに対して有効になっている ことも確認する必要があります。これは、ロー フィルタとカラム マスクをサポートするデータ フィルタリング機能がサーバレス コンピュートで実行されるためです。行フィルタまたは列マスクを使用するテーブルを読み取るために、専用アクセスモードとして設定されたコンピュートを使用する場合、サーバレス コンピュート リソースに対して料金が発生する場合があります。 「専用コンピュート (旧称 single user コンピュート) のきめ細かなアクセス制御」を参照してください。
行フィルターを適用する
行フィルターを作成するには、フィルターポリシーを定義する関数 (UDF) を記述し、それをテーブルに適用します。各テーブルに設定できる行フィルターは1つだけです。行フィルターは0個以上の入力パラメーターを受け入れます。各入力パラメーターは対応する表の1つの列にバインドされます。
行フィルタは、カタログエクスプローラまたは SQL コマンドを使用して適用できます。 Catalog Explorer の手順では、関数を既に作成し、Unity Catalog に登録していることを前提としています。 SQL 命令には、行フィルタ関数を作成し、それをテーブルに適用する例が含まれています。
- Catalog Explorer
- SQL
- In your Databricks workspace, click
Catalog.
- Browse or search for the table you want to filter.
- On the Overview tab, click Row filter: Add filter.
- On the Add row filter dialog, select the catalog and schema that contain the filter function, then select the function.
- On the expanded dialog, view the function definition and select the table columns that match the columns included in the function statement.
- Click Add.
To remove the filter from the table, click fx Row filter and click Remove.
To create a row filter, and then add it to an existing table, use CREATE FUNCTION
and apply the function using ALTER TABLE
. You can also apply a function when you create a table using CREATE TABLE
.
-
Create the row filter:
SQLCREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
RETURN {filter clause whose output must be a boolean}; -
Apply the row filter to a table using a column name:
SQLALTER TABLE <table_name> SET ROW FILTER <function_name> ON (<column_name>, ...);
Additional syntax examples:
-
Apply the row filter to a table using a constant literal that matches a function parameter:
SQLALTER TABLE <table_name> SET ROW FILTER <function_name> ON (<constant_literal>, ...);
-
Remove a row filter from a table:
SQLALTER TABLE <table_name> DROP ROW FILTER;
-
Modify a row filter:
SQLRun a DROP FUNCTION statement to drop the existing function, or use CREATE OR REPLACE FUNCTION to replace it.
-
Delete a row filter:
SQLALTER TABLE <table_name> DROP ROW FILTER;
DROP FUNCTION <function_name>;
You must perform the ALTER TABLE ... DROP ROW FILTER
command before you drop the function. If you don’t, the table will be in an inaccessible state.
If the table becomes inaccessible in this way, alter the table and drop the orphaned row filter reference using ALTER TABLE <table_name> DROP ROW FILTER;
.
See also ROW FILTER
clause.
行フィルターの例
この例では、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 命令には、列マスク関数を作成し、それをテーブル列に適用する例が含まれています。
- Catalog Explorer
- SQL
- In your Databricks workspace, click
Catalog.
- Browse or search for the table.
- On the Overview tab, find the row you want to apply the column mask to and click the
Mask edit icon.
- On the Add column mask dialog, select the catalog and schema that contain the filter function, then select the function.
- On the expanded dialog, view the function definition. If the function includes any parameters in addition to the column being masked, select the table columns in which you want to cast those additional function parameters.
- Click Add.
To remove the column mask from the table, click fx Column mask in the table row and click Remove.
To create a column mask and add it to an existing table column, use CREATE FUNCTION
and apply the masking function using ALTER TABLE
. You can also apply a function when you create a table using CREATE TABLE
.
You use SET MASK
to apply the masking function. Within the MASK
clause, you can use any of the Databricks built-in runtime functions or call other user-defined functions. Common use cases include inspecting the identity of the invoking user running the function by using current_user( )
or getting the groups they are a member of using is_account_group_member( )
. For details, see Column mask
clause and Built-in functions.
-
Create a column mask:
SQLCREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
RETURN {expression with the same type as the first parameter}; -
Apply the column mask to a column in an existing table:
SQLALTER TABLE <table_name> ALTER COLUMN <col_name> SET MASK <mask_func_name> USING COLUMNS <additional_columns>;
Additional syntax examples:
-
Apply the column mask to a column in an existing table using a constant literal that matches a function parameter:
SQLALTER TABLE <table_name> ALTER COLUMN <col_name> SET MASK <mask_func_name> USING COLUMNS (<constant_name>, ...);
-
Remove a column mask from a column in a table:
SQLALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK;
-
Modify a column mask, either
DROP
the existing function or useCREATE OR REPLACE TABLE
. -
Delete a column mask:
SQLALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK;
DROP FUNCTION <function_name>;
You must perform the ALTER TABLE
command before dropping the function or the table will be in an inaccessible state.
If the table becomes inaccessible in this way, alter the table and drop the orphaned mask reference using 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_account_group_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_ACCOUNT_GROUP_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);
サポートと制限事項
行フィルターと列マスクは、すべてのDatabricks機能、あるいはすべてのコンピュートリソースでサポートされているとは限りません。このセクションでは、サポートされている機能と制限事項を紹介します。
サポートされている機能と形式
このサポートされている機能のリストは、すべてを網羅しているわけではありません。一部、パブリックプレビュー中にサポートされなかったためにリストされているアイテムもあります。
-
SQL ワークロード用の Databricks SQL および Databricks ノートブックがサポートされています。
-
MODIFY
権限を持つユーザーによる DML コマンドがサポートされています。フィルタとマスクは、UPDATE
ステートメントとDELETE
ステートメントによって読み取られるデータに適用され、書き込まれるデータ (INSERT
を含む) には適用されません。 -
サポートされているデータ形式は以下の通りです。
- マネージドテーブルと外部テーブル用の Delta と Parquet。
- Unity Catalogに登録されているフォーリンテーブルの他の複数のデータ形式は、レイクハウスフェデレーションを使用して登録されています。
-
ポリシーパラメーターには、定数式(文字列、数値、区間、ブーリアン、ヌル)を含めることができます。
-
SQL、Python、Scala UDFs は、Unity Catalog に登録されている場合、行フィルターまたは列マスク関数としてサポートされます。 Python と Scala の UDF は SQL UDF でラップする必要があります。
-
列マスクや行フィルターを参照するテーブルにビューを作成できますが、列マスクや行フィルターをビューに追加することはできません。
-
Delta Lake チェンジデータフィードは、スキーマがターゲットテーブルに適用される行フィルターおよび列マスクと互換性がある場合にサポートされます。
-
フォーリンテーブルがサポートされています。
-
テーブルサンプリングはサポートされています。
-
MERGE
文は、ソース表、ターゲット表、あるいはその両方で行フィルタと列マスクを使用する場合にサポートされます。 これには、単純なサブクエリを含む行フィルタ関数を持つテーブルが含まれます。 制限事項については、次のセクションにリストされています。 -
Databricks SQL マテリアライズド ビュー と Databricks SQL ストリーミング テーブル で行フィルターと列マスクがサポートされるようになりました (パブリック プレビュー)。
- 行フィルターと列マスクは、Databricks SQL マテリアライズド ビューまたはストリーミング テーブルに追加できます。 マスクの追加は、マテリアライズド・ビューまたはストリーミング・テーブルが定義されるときに宣言的に行う必要があります。 CREATE MATERIALIZED VIEW または CREATE STREAMING TABLE を参照してください。
- 行フィルターと列マスクを含むテーブルで、Databricks SQLマテリアライズドビューまたはストリーミングテーブルを定義できます。
-
DLT で宣言および公開されたマテリアライズドビュー とストリーミングテーブルは、行フィルターまたは列マスクをサポートします (パブリック プレビュー)。
- 行フィルタと列マスクを DLT マテリアライズドビューまたはストリーミングテーブルに追加できます。
- DLT マテリアライズドビューまたはストリーミングテーブルは、行フィルタと列マスクを含むテーブルで定義できます。
行フィルターと列マスクを使用したテーブルのパブリッシュを参照してください。
パフォーマンスに関する推奨事項
行フィルタと列マスクは、フィルタ操作とマスキング操作の前にユーザーがベース テーブルの値の内容を表示できないようにすることで、データの可視性を制御します。 これらは、一般的なユースケースでのクエリに対する応答性に優れています。 あまり一般的ではないアプリケーションでは、クエリ エンジンがクエリ パフォーマンスの最適化と、フィルター処理/マスクされた値からの情報の漏洩から保護するかを選択する必要があるため、クエリ エンジンは常に安全な決定を下しますが、クエリ パフォーマンスに多少の影響は生じません。 このパフォーマンスへの影響を最小限に抑えるには、次の推奨事項を適用します。
- シンプルなポリシー関数を使用する: 式が少ないポリシー関数は、多くの場合、より複雑な式よりもパフォーマンスが優れています。 マッピング・テーブルや式のサブクエリの使用は避け、単純な CASE 関数を使用してください。
- 関数の引数の数を減らします。 Databricks は、ポリシー関数の引数の結果としてソース テーブルへの列参照を最適化できません (これらの列がクエリで使用されていない場合でも)。 引数の少ないポリシー関数を使用すると、これらのテーブルからのクエリのパフォーマンスが向上します。
- AND 結合が多すぎる行フィルターを追加しないでください。 各テーブルは最大で 1 つの行フィルターの追加しかサポートしていないため、一般的なアプローチは、複数の必要なポリシー関数を
AND
と組み合わせることです。 ただし、結合ごとに、この表の他の場所に記載されているパフォーマンスに影響を与える可能性のあるコンポーネント (マッピング テーブルなど) が結合に含まれる可能性が高くなります。 パフォーマンスを向上させるために、使用する接続を減らします。 - これらのテーブルからのテーブルポリシーおよびクエリでエラーをスローできない決定論的な式を使用します。 一部の式では、ANSI 除算など、指定された入力が有効でない場合、エラーがスローされる場合があります。 このような場合、SQL コンパイラは、これらの式 (フィルターなど) を使用した操作をクエリ プランの下位にプッシュしすぎないようにして、フィルター処理やマスク操作の前に値に関する情報を明らかにする "ゼロ除算" などのエラーの可能性を回避してはなりません。 エラーをスローしない決定論的な式 (この例では の のように
try_divide
) を使用します。 - テーブルに対してテストクエリを実行してパフォーマンスを測定する: 行フィルタや列マスクを使用して、テーブルに期待される作業負荷を表す現実的なクエリを構築し、パフォーマンスを測定します。フィルタリングとマスキングロジックのパフォーマンスと表現力のバランスが取れるまでポリシー関数を少しずつ修正し、その効果を観察してください。
制限
- 12.2 LTS以前のDatabricks Runtimeバージョンでは、行フィルターまたは列マスクはサポートされません。これらのランタイムは安全に失敗します。つまり、サポートされていないバージョンのランタイムのテーブルにアクセスしようとしても、データは返されません。
- デルタ共有は、行レベルのセキュリティまたは列マスクでは機能しません。
- ビューに行レベルのセキュリティまたは列マスクを適用することはできません。
- タイムトラベルは、行レベルのセキュリティまたは列マスクでは機能しません。
- ポリシーを持つテーブル内のファイルへの、パスベースのアクセスはサポートされていません。
- 元のポリシーに戻る循環依存性を持つ行フィルターまたは列マスクポリシーはサポートされていません。
- ディープクローン、シャロークローンはサポートされていません。
MERGE
ステートメントは、ネスト、集計、ウィンドウ、制限、または非決定論的関数を含む行フィルタまたはカラムマスクポリシーを持つテーブルをサポートしません。- Delta Lake APIsはサポートされていません。
専用アクセスモードの制限
行フィルターまたは列マスクを持つテーブルには、 Databricks Runtime 15.3 以前の専用のアクセス コンピュート リソースからアクセスできません。 Databricks Runtime 15.4 LTS 以降では、 ワークスペースでサーバレス コンピュートが有効になっている場合 、専用アクセスモードを使用できます。詳細については、「 Fine-grained access control on dedicated コンピュート (旧称 single user コンピュート)」を参照してください。