行フィルターと列マスク
このページでは、行フィルターと列マスクを使用してテーブル内の機密データをフィルター処理するためのガイダンスを提供します。
行フィルターとは何ですか?
行フィルターを使用すると、カスタム ロジックに基づいて、ユーザーがテーブル内でアクセスできる行を制御できます。クエリ時に、行フィルターは条件を評価し、それを満たす行のみを返します。これは、行レベルのセキュリティを実装するために一般的に使用されます (たとえば、特定の地域、部門、またはアカウントのレコードにユーザーを制限するなど)。
行フィルターは SQL ユーザー定義関数 (UDF) として定義され、SQL UDF にラップされた場合は Python または Scala ロジックを組み込むこともできます。行フィルターは、テーブルごとに適用することも、管理タグを使用して ABAC ポリシーを通じて一元的に適用することもできます。
列マスクとは何ですか?
列マスクは、ユーザーが誰であるかに応じて、特定の列に表示される値を制御します。クエリ時に、マスクは列への各参照をマスキング関数の結果に置き換えます。これにより、SSN や電子メールなどの機密データを、ユーザーの ID や役割に基づいて編集または変換できます。
各列には 1 つのマスクを設定できます。マスクは、マスクされる列と同じ型の値を返す SQL UDF として定義する必要があります。SQL UDF はオプションでPython または Scala UDF を呼び出して、複雑なマスキング ロジックを実装できます。列マスクは、他の列を入力として受け取ることもできます。たとえば、複数の属性に基づいて動作を変えることができます。
行フィルターと同様に、列マスクはテーブルごとに適用することも、ABAC ポリシーを使用して一元的に管理することもできます。これらはクエリ時に動作し、標準の SQL、ノートブック、ダッシュボードとシームレスに統合されます。
動的ビューとフィルターとマスクのどちらを使用する必要があるか?
動的ビュー、行フィルター、列マスクはすべて、クエリ時にフィルター処理または変換ロジックを適用できますが、管理、スコープ、およびユーザーへの公開方法が異なります。
機能 | 適用対象 | 管理 | 命名の影響 | 最適な用途... |
|---|---|---|---|---|
動的ビュー | ビュー | SQL ロジック | 新しいオブジェクト名を作成します。 | フィルター処理されたデータの共有または複数のテーブルにまたがる |
行フィルター | テーブル | ABAC またはマッピング テーブル | テーブル名は変更されません | ユーザー タグまたはデータ タグに関連付けられた行レベルのアクセス制御 |
列マスク | テーブル/列 | ABAC またはマッピング テーブル | テーブル名は変更されません | ID に基づく機密列データの編集 |
- 動 的ビューは 、1 つ以上のソース テーブルにまたがる読み取り専用レイヤーが必要な場合、特にデータ共有や複数の入力にロジックを適用する場合に使用します。
- 行フィルターと列マスク は、テーブル名を変更したり、新しいオブジェクトを導入したりせずに、ロジックをテーブルに直接適用する場合に使用します。これらは、ABAC ポリシー (推奨) を使用して管理することも、テーブルで手動で管理することもできます。
完全な比較については、「 アクセス制御方法の比較」を参照してください。
フィルターとマスクの適用方法
行フィルターと列マスクは、主に次の 2 つの方法で実装できます。
-
ABAC ポリシーの使用 (パブリック プレビュー): 管理タグと再利用可能なポリシーを使用して、フィルターとマスクを一元的に適用します。 このアプローチはカタログとスキーマ全体に拡張され、テーブルごとの構成の必要性が軽減されます。ABAC ポリシーは、上位レベルの管理者が定義でき、テーブル所有者が上書きできないため、手動のテーブルレベル ポリシーよりも安全であり、集中アクセス制御の適用に役立ちます。また、ABAC ポリシーのフィルタリングおよびマスキング ロジックはテーブル固有の UDF よりも効率的に評価されるため、多くの場合、パフォーマンスも向上します。Databricks では、ほとんどのユースケースで ABAC の使用を推奨しています。ABAC を使用してフィルターとマスクを適用するには、「Unity Catalog 属性ベースのアクセス制御 (ABAC)」を参照してください。
-
テーブルごとの手動割り当て : 個々のテーブルと列に関数を直接割り当てることで、フィルターとマスクを適用します。このメソッドでは、マッピング テーブルまたはその他のカスタム ロジックを使用できます。きめ細かいテーブル固有の制御が可能ですが、スケーリングと保守が困難になります。詳細については 情報、 行フィルターと列マスクを手動で適用するを参照してください。
パフォーマンスに関する推奨事項
行フィルターと列マスクは、フィルター処理およびマスク操作の前にユーザーが基本テーブルの値の内容を表示できないようにすることで、データの可視性を制御します。一般的なユースケースでは、クエリに対する応答のパフォーマンスが良好です。あまり一般的ではないアプリケーションでは、クエリ エンジンがクエリ パフォーマンスを最適化するか、フィルター処理またはマスクされた値からの情報漏洩を防ぐかを選択する必要がある場合、クエリ パフォーマンスに多少の影響を与えることを犠牲にして、常に安全な決定を下します。このパフォーマンスへの影響を最小限に抑えるには、次の推奨事項を適用します。
- 単純なポリシー関数を使用する: 式が少ないポリシー関数は、多くの場合、より複雑な式よりもパフォーマンスが優れています。 マッピング テーブルと式サブクエリの使用を避け、代わりに単純な CASE 関数を使用してください。
- 列マスクとマスキング関数の数を制限する: 大きなテーブルに複数の一意の列マスクがあると、クエリのパフォーマンスが低下する可能性があります。それぞれの個別のマスクはクエリ中に評価を必要とするため、処理のオーバーヘッドが増加します。本当に機密性の高いデータを含む列にのみマスクを適用し、可能な場合はマスク関数を再利用します。
- 関数の引数の数を減らす: これらの列がクエリで使用されていない場合でも、Databricks はポリシー関数の引数によって生成されたソース テーブルへの列参照を最適化できません。これらのテーブルからのクエリのパフォーマンスが向上するため、引数の少ないポリシー関数を使用します。
- AND 結合が多すぎる行フィルターを追加しないでください。 特定のユーザーとテーブルに対して で解決できる行フィルターは 1 つだけであるため、一般的なアプローチは、複数の必要なポリシー関数を
ANDと組み合わせることです。 ただし、接続詞を追加するたびに、この表の他の場所で言及され、パフォーマンスに影響を与える可能性のあるコンポーネント (マッピング テーブルなど) が接続詞に含まれる可能性が高くなります。パフォーマンスを向上させるには、接続詞を少なくします。 - これらのテーブルからのテーブル ポリシーおよびクエリでエラーをスローできない決定論的な式を使用します。ANSI 除算など、一部の式では、提供された入力が有効でない場合、エラーがスローされることがあります。このような場合、SQL コンパイラは、フィルタリングやマスキング操作の前に値に関する情報を明らかにする「ゼロ除算」などのエラーの可能性を回避するために、これらの式 (フィルターなど) を含む操作をクエリ プランのあまり下の方に押し出さないようにする必要があります。
try_divideなど、エラーをスローしない決定論的な式を使用します。 - Python UDF よりも SQL を優先する : Python UDF は通常、SQL よりもパフォーマンスが低く、最適化の機会も少なくなります。Python を使用する必要がある場合は、非決定論的なロジックや依存関係が関係しない UDF を明示的に
DETERMINISTICとしてマークします。 - テーブルに対してテスト クエリを実行してパフォーマンスを測定します。 行フィルターまたは列マスクを使用して、テーブルに予想されるワークロードを表す現実的なクエリを作成し、パフォーマンスを測定します。ポリシー関数に小さな変更を加え、フィルタリングおよびマスキング ロジックのパフォーマンスと表現力のバランスが適切に取れるまで、その効果を観察します。
その他のベスト プラクティスと UDF の例については、 「ABAC ポリシーの UDF のベスト プラクティス」を参照してください。
データ型の不一致動作
行フィルターまたは列マスクを作成する場合、関数に渡される各テーブル列のデータ型は、UDF内の対応するパラメーター型と一致している必要があります。例えば、 STRING列がINT列に渡された場合など、型の不一致があると、 Databricks暗黙的に列の値を型にキャストします。このため、列に変換できない値が含まれている場合、予期しない動作が発生する可能性があります。
ANSI モードが無効になっている場合 ( spark.sql.ansi.enabled = false )、キャストできない値は暗黙的にNULLに変換され、エラーは発生せず、UDF は実際の列値の代わりにNULLを受け取ります。これにより、行フィルターがフィルタリングする代わりにすべての行を返したり、列マスクが間違った値をマスクしたりするなど、誤った結果が生じる可能性があります。Databricks は、ANSI モード ( spark.sql.ansi.enabled = true ) を有効にすることを推奨しています。これにより、キャストが失敗したときにエラーが発生し、問題がすぐにわかるようになります。これは、 NULL黙って返すのではなく、問題がすぐにわかるようになります。
例:型が一致しない行フィルター
STRING列を持つテーブルと、その問題が誤ってSTRINGではなくINTとして宣言されている行フィルターを考えてみましょう。
SET spark.sql.ansi.enabled = false;
CREATE TABLE employees (
id INT,
salary INT,
department STRING
);
INSERT INTO employees VALUES
(91, 200000, null),
(1, 200000, 'exec'),
(2, 50000, 'engineering'),
(3, 150000, 'exec');
-- Bug: parameter type is INT, but the column is STRING
CREATE FUNCTION salary_filter(dept INT) RETURNS BOOLEAN
RETURN dept IS NULL;
ALTER TABLE employees SET ROW FILTER salary_filter ON (department);
クエリを実行すると、 department値'exec'と'engineering' INTにキャストできないため、黙ってNULLに変換されます。入力がNULLの場合、フィルターはtrueを返すため、 departmentが実際にはNULLである行だけでなく、すべての行が返されます。
SELECT * FROM employees;
| ID | 給与 | 部署 | | -- | ------ | ----------- | | 91 | 200000 | null | | 1 | 200000 | 実行 | | 2 | 50000 | エンジニアリング | | 3 | 150000 | エグゼクティブ |
正しいUDF定義では、列と一致させるための分散タイプとしてSTRINGが使用されます。
CREATE FUNCTION salary_filter(dept STRING) RETURNS BOOLEAN
RETURN dept IS NULL;
この修正により、クエリはdepartmentがNULLである行のみを返します。
制限事項
- 12.2 LTS より前の Databricks Runtime バージョンでは、行フィルターまたは列マスクはサポートされません。これらのランタイムは安全に失敗します。つまり、これらのランタイムからテーブルにアクセスしようとしても、データは返されません。
- ビューに行レベルのセキュリティまたは列マスクを適用することはできません。
- カタログ Iceberg REST Unity REST API を使用して、行フィルターや列マスクを持つテーブルにアクセスすることはできません。
- Delta Lake APIはサポートされていません。
- Delta Sharingプロバイダーは、行レベルのセキュリティまたは列マスクを持つテーブルを共有できません。 ただし、 Delta Sharing受信者は、行フィルターと列マスクを共有テーブルとフォーリン テーブルにのみ適用できます。ストリーミング テーブルやマテリアライズドビューには適用できません。
- ポリシーを持つテーブル内のファイルへの、パスベースのアクセスはサポートされていません。
MERGEステートメントは、ネスト、集計、ウィンドウ、制限、または非決定論的関数を含む行フィルターまたは列マスク ポリシーを持つテーブルをサポートしません。- 17.2 より前のバージョンの Databricks Runtime では、パーティション列に行フィルターまたは列マスク ポリシーが定義されているパーティション テーブル上の
DELETE、UPDATE、およびMERGEはサポートされません。 - 元のポリシーに戻る循環依存性を持つ行フィルターまたは列マスクポリシーはサポートされていません。
- 行フィルターと列マスクは、アクティブな行フィルターまたは列マスクを持つテーブルを参照することはできません。ABAC 構成では、参照されるテーブルのポリシーからポリシー関数の所有者を除外することで、この問題を回避できます。
- タイムトラベルは、行レベルのセキュリティまたは列マスクでは機能しません。 ABAC 構成では、ポリシーから明示的に除外されているユーザーでも、基礎となるデータに対してタイムトラベル クエリを実行できます。
- 行レベルのセキュリティまたは列マスクを持つテーブルでは、ディープ クローンおよびシャロー クローンはサポートされません。ABAC 構成では、ポリシーから明示的に除外されているユーザーでも、基礎となるデータに対してクローン操作を実行できます。
- 行フィルターまたは列マスクが適用されたテーブルからベクトル検索インデックスを作成することはできません。
専用アクセスモードの制限
Databricks Runtime 15.3 以前の専用アクセス コンピュート リソースからは、行フィルターまたは列マスクを備えたテーブルにアクセスできません。 ワークスペースでサーバレス コンピュートが有効になっている場合は、 Databricks Runtime 15.4 LTS以降で専用アクセス モードを使用できます。 ただし、Databricks Runtime 15.4 ~ 16.2 では読み取り操作のみがサポートされます。書き込み操作 ( INSERT 、 UPDATE 、 DELETEを含む) には Databricks Runtime 16.3 以上が必要であり、 MERGE INTOなどのサポートされているパターンを使用する必要があります。
専用アクセス モード コンピュートから行フィルターまたは列マスクを使用してテーブルをクエリすると、 Databricksサーバーレス コンピュートを使用して、きめ細かいアクセス制御 (FGAC) を適用します。 その結果、すべての FGAC の制限と考慮事項が適用されます。専用コンピュートのきめ細かいアクセス制御を参照してください。
FGAC はクラウドフェッチを使用して、一時的な結果セットを内部ワークスペースストレージに書き込みます。 S3 バケットのバージョン管理が有効になっている場合、ストレージが急激に増加する可能性があります。設定の推奨事項については、 S3 バケットのバージョン管理に関する考慮事項を参照してください。