行フィルターと列マスクを手動で適用する
このページでは、行フィルター、列マスク、マッピング テーブルを使用してテーブル内の機密データをフィルター処理するためのガイダンスと例を示します。これらの機能には Unity Catalog が必要です。
フィルタリングとマスキングのための集中型のタグベースのアプローチをお探しの場合は、 Unity Catalog の属性ベースのアクセス制御 (ABAC)を参照してください。ABAC を使用すると、管理されたタグを使用してポリシーを管理し、多くのテーブルにわたって一貫してポリシーを適用できます。
始める前に
テーブルに行フィルターと列マスクを追加するには、次のものが必要です。
- Unity Catalog が有効になっているワークスペース。
- Unity Catalogに登録されている関数。この関数は、SQL UDF、または Unity Catalog に登録され SQL UDF にラップされた Python または Scala UDF にすることができます。詳細については、 「ユーザー定義関数 (UDF) とは」 、 「列
mask
句」 、およびROW FILTER
句」を参照してください。UDF のベスト プラクティスと制限については、 「行フィルターと列マスク」を参照してください。
また、次の要件を満たす必要があります。
- 行フィルターまたは列マスクをテーブルに追加する関数を割り当てるには、関数の
EXECUTE
権限、スキーマのUSE SCHEMA
権限、親カタログのUSE CATALOG
権限が必要です。 - 新しい テーブルの作成時にフィルターまたはマスクを追加する場合は、スキーマに対する
CREATE TABLE
権限が必要です。 - 既存の テーブルにフィルターまたはマスクを追加する場合は、テーブルの所有者であるか、テーブルに対する
MANAGE
権限を持っている必要があります。
行フィルターや列マスクのあるテーブルにアクセスするには、コンピュートリソースが次の要件のいずれかを満たしている必要があります。
- SQLウェアハウス。
- Databricks Runtime 12.2 LTS 以降の標準アクセス モード (以前の共有アクセス モード)。
- Databricks Runtime 15.4 LTS 以降の専用アクセス モード (以前のシングル ユーザー アクセス モード)。
Databricks Runtime 15.3以下では、専用コンピュートを使用して行フィルターや列マスクを読み込むことはできません。
Databricks Runtime 15.4 LTS以降で提供されているデータフィルタを利用するには、行フィルタと列マスクをサポートするデータフィルタ機能がサーバレスコンピュートで実行されるため、ワークスペースがサーバレスコンピュートに対して有効になっていることも確認する必要があります。専用アクセスモードとして設定されたコンピュートを使用して、行フィルタまたは列マスクを使用するテーブルを読み取る場合、サーバレス コンピュート リソースに対して課金されることがあります。 これらのテーブルへの書き込み操作は、DBR 16.3 以降でのみサポートされ、 MERGE INTO
などのサポートされているパターンを使用する必要があります。専用コンピュートのきめ細かなアクセス制御を参照してください。
行フィルターと列マスクは、テーブルを置き換えるときに保持されます。
REPLACE TABLE
を実行すると、スキーマの変更に関係なく、既存の行フィルターが保持されます。新しいテーブルに、元のテーブルにマスクがあった列と同じ名前の列が含まれている場合も、列マスクは保持されます。どちらの場合も、ポリシーは明示的に再定義されていなくても保持されます。これにより、データ アクセス ポリシーが誤って失われるのを防ぎます。
ただし、保持ポリシーが削除または変更された列を参照している場合、後続のクエリは失敗する可能性があります。これを解決するには、 を使用してポリシーを更新または削除します ALTER TABLE
。
行フィルターを適用する
行フィルターを作成するには、フィルターポリシーを定義する関数 (UDF) を記述し、それをテーブルに適用します。各テーブルに設定できる行フィルターは1つだけです。行フィルターは0個以上の入力パラメーターを受け入れます。各入力パラメーターは対応する表の1つの列にバインドされます。
行フィルターは、カタログ エクスプローラーまたは SQL コマンドを使用して適用できます。カタログ エクスプローラーの手順では、関数を既に作成し、Unity Catalog に登録していることを前提としています。SQL 命令には、行フィルター関数を作成してテーブルに適用する例が含まれています。
Lakeflow 宣言型パイプラインを使用している場合は、Lakeflow 宣言型パイプライン Python APIを使用して、行フィルターと列マスクを使用するストリーミングテーブルまたはマテリアライズドビューを作成できます。行フィルターと列マスクを使用したテーブルのパブリッシュを参照してください。
- Catalog Explorer
- SQL
- Databricks ワークスペースで、
カタログ をクリックします。
- フィルタリングするテーブルを参照または検索します。
- [ 概要 ] タブの [行フィルター] で、[ フィルターの追加 ] をクリックします。
- [ 行フィルターを追加 ] ダイアログで、フィルター機能を含むカタログとスキーマを選択し、関数を選択します。
- 展開されたダイアログで関数定義を表示して、関数ステートメントに含まれる列と一致するテーブル列を選択します。
- [ 追加 ] をクリックします。
テーブルからフィルターを削除するには、[ fx行フィルター ] をクリックして [ 削除 ] をクリックします。
行フィルターを作成して既存のテーブルに追加するには、 CREATE FUNCTION
を使用し、 を使用して関数を適用 ALTER TABLE
。を使用してテーブルを作成するときに関数を適用することもできます CREATE TABLE
。
-
行フィルターを作成します。
SQLCREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
RETURN {filter clause whose output must be a boolean}; -
列名を使用してテーブルに行フィルターを適用します。
SQLALTER TABLE <table_name> SET ROW FILTER <function_name> ON (<column_name>, ...);
その他の構文の例 :
-
関数パラメーターと一致する定数リテラルを使用して、行フィルターをテーブルに適用します。
SQLALTER TABLE <table_name> SET ROW FILTER <function_name> ON (<constant_literal>, ...);
-
テーブルから行フィルターを削除する
SQLALTER TABLE <table_name> DROP ROW FILTER;
-
行フィルターを変更する
SQLRun a DROP FUNCTION statement to drop the existing function, or use CREATE OR REPLACE FUNCTION to replace it.
-
行フィルターを削除する
SQLALTER 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 コマンドを使用して適用できます。カタログ エクスプローラーの手順では、関数を既に作成し、Unity Catalog に登録していることを前提としています。SQL 命令には、列マスク関数を作成し、それをテーブル列に適用する例が含まれています。
Lakeflow 宣言型パイプラインを使用している場合は、Lakeflow 宣言型パイプライン Python APIを使用して、行フィルターと列マスクを使用するストリーミングテーブルまたはマテリアライズドビューを作成できます。行フィルターと列マスクを使用したテーブルのパブリッシュを参照してください。
- Catalog Explorer
- SQL
- Databricks ワークスペースで、
カタログ をクリックします。
- テーブルを参照または検索します。
- [ 概要 ] タブで、列マスクを適用する行を見つけて、[
マスク ] 編集アイコンをクリックします。
- [ 列マスクを追加 ] ダイアログで、フィルター関数を含むカタログとスキーマを選択し、関数を選択します。
- 展開されたダイアログで、関数定義を表示します。マスクされる列に加えて、関数にパラメーターが含まれている場合は、それらの追加関数パラメーターをキャストするテーブル列を選択します。
- [ 追加 ] をクリックします。
テーブルから列マスクを削除するには、テーブル行の fx列マスク をクリックし、[ 削除 ] をクリックします。
列マスクを作成して既存のテーブル列に追加するには、CREATE FUNCTION
を使用し、ALTER TABLE
を使用してマスキング関数を適用します。CREATE TABLE
を使用してテーブルを作成するときに関数を適用することもできます。
SET MASK
を使用してマスキング機能を適用します。MASK
句内では、Databricks の組み込みランタイム関数のいずれかを使用するか、他のユーザー定義関数を呼び出すことができます。一般的なユースケースには、 を使用して関数を実行している呼び出し元ユーザーの ID を検査したり、 current_user( )
を使用してメンバーであるグループを取得したりすることが含まれます is_account_group_member( )
。詳細については、「 列 mask
句 」および 「組み込み関数」を参照してください。
-
列マスクを作成します。
SQLCREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
RETURN {expression with the same type as the first parameter}; -
既存のテーブルの列に列マスクを適用する
SQLALTER TABLE <table_name> ALTER COLUMN <col_name> SET MASK <mask_func_name> USING COLUMNS <additional_columns>;
その他の構文の例 :
-
関数パラメーターと一致する定数リテラルを使用して、既存のテーブルの列に列マスクを適用します。
SQLALTER TABLE <table_name> ALTER COLUMN <col_name> SET MASK <mask_func_name> USING COLUMNS (<constant_name>, ...);
-
テーブル内の列から列マスクを削除する
SQLALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK;
-
既存の関数
DROP
か、CREATE OR REPLACE TABLE
を使用して列マスクを変更します。 -
列マスクを削除する
SQLALTER 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_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 (column);
を使用します。詳細については、「 パラメーター」を参照してください。
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);