Filter sensitive table data with row filters and column masks | Databricks on AWS [2023/9/11時点]の翻訳です。
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
プレビュー
この機能はパブリックプレビューです。
本書では、お使いのテーブルのセンシティブなデータをフィルタリングするための行フィルター、列マスク、マッピングテーブルを使用するためのガイドと例を説明します。
行フィルターとは?
行フィルターによって、以降のクエリーがフィルター述語がtrueと評価された行のみを返却するとようにテーブルにフィルターを適用することができます。行フィルターはSQLユーザー定義関数(UDF)として実装されています。
行フィルターを作成するには、フィルターポリシーを定義するために最初にSQL UDFを記述し、ALTER TABLE
文でテーブルに適用します。あるいは、初回のCREATE TABLE
文でテーブルで行フィルターを指定することができます。それぞれのテーブルでは一つのみの行フィルターを定義することができます。行フィルターでは、対応するテーブルのあるカラムにバインディングされる0個以上の入力パラメーターを受け入れることができます。
行フィルターとダイナミックビューの違いは?
ダイナミックビューは、1つ以上のソーステーブルに対して抽象化された読み取り専用のビューです。ユーザーはソーステーブルに直接アクセス権を持たなくてもダイナミックビューにアクセスすることができます。ダイナミックビューの作成によって、いかなるソーステーブルや同じスキーマにある他のテーブルやビューと名前が一致しない新たなテーブル名を定義することになります。
一方で、ターゲットテーブルに行フィルターや列マスクを関連づけることで、新たなテーブル名を導入することなしに、同じロジックをテーブル自身に適用します。以降のクエリーはオリジナルの名称を用いて、ターゲットテーブルを直接参照し続けることになります。
ダイナミックビューと行フィルターと列マスクはいずれも、テーブルに複雑なロジックを適用し、クエリーの実行時にフィルタリングの判断基準を処理することができます。
読み取り専用テーブルに対してフィルターやマスクのような変換ロジックを適用する必要がある場合や、ユーザーがダイナミックビューを参照することを許容できる場合にはダイナミックビューを使用しましょう。特定のデータにフィルタリングや計算表現を適用したいが、オリジナル名を用いたテーブルへのアクセスを提供したい場合には、行フィルターや列マスクを使いましょう。
行フィルターの文法
行フィルターを作成し、既存テーブルに追加するには以下の構文を使用します:
行フィルターの作成:
CREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
RETURN {filter clause whose output must be a boolean};
テーブルに行フィルターを適用:
ALTER TABLE <table_name> SET ROW FILTER <function_name> ON (<column_name>, ...);
テーブルから行フィルターの削除:
ALTER TABLE <table_name> DROP ROW FILTER;
行フィルターの編集:
既存の関数を削除するにはDROP FUNCTION
文を実行し、置き換える際にはCREATE OR REPLACE FUNCTION
を使用します。
行フィルターの削除:
ALTER TABLE <table_name> DROP ROW FILTER;
DROP FUNCTION <function_name>;
注意
関数を削除する前にALTER TABLE ... DROP ROW FILTER
コマンドを実行してください。さもないと、テーブルにアクセスできなくなります。
このようにテーブルにアクセスできなくなった際には、ALTER TABLE <table_name> DROP ROW FILTER;
を用いて、テーブルを変更し、関連のなくなった行フィルターの参照を削除してください。
行フィルターの例
リージョンUS
でグループadmin
のメンバーに適用されるSQLユーザー定義関数を作成します。
この関数を用いることで、グループadmin
のメンバーはテーブルのすべてのレコードにアクセスできます。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) USING delta;
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) USING delta
WITH ROW FILTER us_filter ON (region);
列マスクとは?
列マスクによって、テーブルの列にマスキング関数を適用することができます。マスキング関数はクエリー実行時に評価され、ターゲット列のそれぞれの参照をマスキング関数の結果で置き換えます。多くのユースケースにおいては、列マスクはオリジナルの列の値を返却するのか、呼び出したユーザーのアイデンティティに基づいて検閲するのかを判定します。列マスクはSQL UDFで記述されるエクスプレッションです。
それぞれのテーブル列には、任意で一つのマスキング関数を適用することができます。マスキング関数は、入力としてマスクされていない列の値を受け取り、結果としてマスクされた値を返却します。マスキング関数の戻り値は、マスクされる列と同じ型である必要があります。また、マスキング関数は、マスキングのロジックで使用するための追加の列を入力として受け取ることができます。
列マスクを適用するには、関数を作成し、ALTER TABLE
文を用いてテーブル列に適用します。あるいは、テーブルを作成する際にマスキング関数を適用することができます。
列マスクの文法
MASK
句内では、すべてのDatabricksビルトインランタイム関数や他のユーザー定義関数を活用することができます。一般的なユースケースには、current_user( )
を用いて関数を呼び出しているユーザーのアイデンティティの調査を行うことや、is_account_group member( )
を用いてどのグループのメンバーであるかを判定することが含まれます。
列マスクの作成:
CREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...)
RETURN {expression with the same type as the first parameter};
既存テーブルの列に列マスクを適用:
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 ... DROP ROW FILTER
コマンドを実行してください。さもないと、テーブルにアクセスできなくなります。
このようにテーブルにアクセスできなくなった際には、ALTER TABLE <table_name> DROP MASK;
を用いて、テーブルを変更し、関連のなくなった列マスクの参照を削除してください。
列マスクの例
SQLユーザー定義関数を作成します。この関数は、admin
グループのメンバーに対してssn
列をマスクします。
CREATE FUNCTION ssn_mask(ssn STRING)
RETURN IF(IS_ACCOUNT_GROUP_MEMBER('admin'), ssn, '****');
列マスクとしてテーブルに新たな関数を適用します。ssn
列に対する以降のユーザークエリーは変換された値を返却するようになります。
CREATE TABLE users
(region STRING, table_ssn STRING) USING delta;
ALTER TABLE users ALTER COLUMN table_ssn SET MASK ssn_mask;
列マスクを無効化します。以降のssn
列に対するユーザークエリーはオリジナルの値を返却するようになります。
ALTER TABLE users ALTER COLUMN ssn DROP MASK;
CREATE TABLE
文の一部として、1ステップで列マスクとして適用される新たな関数を用いて別のテーブルを作成します。ssn
列に対する以降のユーザークエリーは変換された値を返却するようになります。
CREATE TABLE region_to_ssn (
region STRING,
ssn STRING MASK ssn_mask)
USING delta;
アクセスコントロールリストを作成するためのマッピングテーブルの活用
行レベルのセキュリティを実現するには、マッピングテーブルの定義(あるいはアクセスコントロールリスト)を検討します。それぞれのマッピングテーブルは、特定のユーザーやグループがオリジナルテーブルのどのデータ行にアクセスできるのかをエンコードする包括的なマッピングテーブルです。マッピングテーブルは、お使いのファクトテーブルに対する直接的なjoinを通じたシンプルなインテグレーションを提供するので有用なものです。
この方法論は、カスタム要件に対する数多くのユースケースに取り組む際に有益であることが示されています。例には以下のようなものがあります:
- 特定のユーザーグループに異なるルールを適用しつつも、ログインしたユーザーに基づいた制約を適用する。
- 様々なルールセットを必要とする組織構造のような複雑な階層構造の作成。
- 外部ソースシステムの複雑なセキュリティモデルの複製。
このようにマッピングテーブルを導入することで、これらの困難なシナリオに効果的に取り組むことができ、堅牢な行レベル、列レベルのセキュリティ実装を保証することができます。
テーブルマッピングの例
現在のユーザーがリストにいるのかどうかをチェックするためにマッピングテーブルを活用します:
USE CATALOG main;
新たなマッピングテーブルを作成します:
DROP TABLE IF EXISTS valid_users;
CREATE TABLE valid_users(username string) USING delta;
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)
USING delta
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;
サポート範囲
- Databricks SQLとSQL向けDatabricksノートブックはサポートされています。
- MODIFY権限を持つユーザーによるDatabricks Machine Learningコマンドはサポートされています。フィルターやマスクは、MODIFYやDELETEによって読み込まれるデータに適用されますが、(INSERTされるデータを含み)書き込まれるデータには適用されません。
- サポートされるフォーマット: DeltaとParquet。Parquetはマネージドテーブルあるいは外部テーブルのみがサポートされています。
- カラムマスクや行フィルターを持つテーブルに対するビューはサポートされています。
- スキーマにターゲットテーブルに対して適用される行フィルターや列マスクと互換性のある限り、Delta Lakeのチェンジデータフィードはサポートされます。
- 外部テーブル(Foreignテーブル)はサポートされています。
制限
- Databricksランタイム12.2 LTS以前では、行フィルターや列マスクはサポートされていません。これらのランタイムは安全に処理を失敗します。これは、これらのサポートされていないバージョンのランタイムでテーブルにアクセスしようとすると、データが返却されないことを意味します。
- 行フィルターや列マスクとしてPythonやScala UDFはサポートされていません。しかし、これらの定義がカタログで永続化されている限り、これらの関数を参照することは可能です(言い換えると、これはセッション固有ではありません)。
- Delta Sharingは。行レベルセキュリティや列マスクは動作しません。
- タイムトラベルは、行レベルセキュリティや列マスクとは動作しません。
- テーブルのサンプリングは、行レベルセキュリティや列マスクとは動作しません。
- ポリシーを持つテーブリに対するパスベースのアクセスは現時点ではサポートされていません。
- オリジナルのポリシーに対する循環参照を持つ行フィルターや列マスクのポリシーはサポートされていません。
-
MERGE
やシャロークローンはサポートされていません。
シングルユーザークラスターの制限
シングルユーザークラスターからアクセスするすべてのテーブルには行フィルターや列カラムを追加しないでください。これは一般的にDatabricksジョブの文脈で行われます。このパブリックプレビューでは、フィルターやマスクが適用されるとシングルユーザークラスターからはテーブルにアクセスできなくなります。