行フィルターと列マスク

行フィルターと列マスクは、ユーザーがクエリ時に表示できる行と列の値を制限する Unity カタログ アクセス制御です。 このページでは、SQL を使用して個々のテーブルで直接構成され、テーブル所有者によって管理される、これらのコントロールのテーブル レベル の形式について説明します。 多くのテーブルで一貫した行フィルター処理と列マスクを行う場合は、 ABAC ポリシー が推奨される方法です。 カタログまたはスキーマ レベルでアタッチし、管理タグに基づいて自動的に適用されます。

Tip

Databricks では、多数のテーブルで一貫した行フィルター処理と列マスクが必要な場合に ABAC ポリシー を推奨します。 ABAC ポリシーは、テーブルごとの構成を必要とするのではなく、カタログまたはスキーマ レベルでアタッチし、管理タグに基づいて自動的に適用されます。

行フィルターとは何ですか?

行フィルターは、ユーザーがテーブルに表示できる行を制限します。 フィルターは、クエリ時に各行を評価する SQL ユーザー定義関数 (UDF) です。 関数が FALSE を返す行は、クエリ結果から除外されます。 これは、行レベルのセキュリティでよく使用されます。 たとえば、特定のリージョン、部署、またはアカウントのレコードにユーザーを制限できます。

テーブル レベルの行フィルターは、 ALTER TABLE ... SET ROW FILTER を使用して 1 つのテーブルにバインドされ、テーブル所有者によって管理されます。 多数のテーブルで一貫した行フィルター処理を行うには、代わりに ABAC ポリシーを 使用します。

コラムマスクとは何ですか?

列マスクは、特定の列に対してユーザーに表示される値を制御します。 マスクは、列の値を入力として受け取り、元の値またはマスクされたバージョンを返す SQL UDF です。 戻り値の型は、列のデータ型と一致するか、キャスト可能である必要があります。 各列は 1 つのマスクを持つことができます。 列マスクは、他の列を入力として受け取り、複数の属性に基づいて動作を変えることができます。

テーブル レベルの列マスクは、 ALTER TABLE ... ALTER COLUMN ... SET MASK を使用して列にバインドされ、テーブル所有者によって管理されます。 これらは、そのテーブルのその列にのみ適用されます。 多数のテーブル間で一貫した列マスクを行うには、代わりに ABAC ポリシーを 使用してください。

代わりに ABAC ポリシーまたは動的ビューを使用する場合

Unity カタログには、行レベルと列レベルのアクセス制御に関連する 2 つのメカニズムが用意されています。

  • ABAC ポリシーは 、カタログまたはスキーマ レベルでアタッチされ、管理タグに基づいてテーブルと列に自動的に適用されます。 ABAC は、多数のテーブル間で一貫したルールが必要な場合、ポリシー作成者とデータ スチュワード間の職務の分離、またはタグ付けされた新しいテーブルの自動カバレッジが必要な場合に使用します。 テーブル レベルの行フィルターと列マスクと並べて比較する場合は、「 ABAC とテーブル レベルの行フィルターと列マスクを使用するタイミング」を参照してください。
  • 動的ビュー は、行のフィルター処理、列のマスク、またはデータの整形を行う SQL ビュー内の 1 つ以上のベース テーブルをラップします。通常は、 is_account_group_member()などのグループ メンバーシップ関数によって制御されます。 基になるテーブルにアクセスできないユーザーに、キュレーション、変換、または結合されたバージョンのデータを公開する場合は、動的ビューを使用します。 ユース ケースの例としては、ファクト テーブルの編集済みスライスをアナリスト グループと共有したり、複数のテーブルの列を 1 つのセキュリティで保護されたレイヤーに結合したりするなどがあります。
アプローチ 対象 を使用して管理する 最適な使用対象
テーブル レベルの行フィルターと列マスク 個別のテーブルと列 ALTER TABLE テーブル所有者、または MANAGE を持つユーザーによって テーブル固有のロジック
ABAC ポリシー タグ条件に一致するテーブルと列 CREATE POLICY が、その所有者または MANAGE 権限を持つユーザーによって、カタログ、スキーマ、またはテーブルに関連付けられている 多数のテーブルに対して自動的に適用される一元化されたルール
動的ビュー 1 つ以上のベース テーブルから構築されたビュー ビュー定義の SQL ロジック キュレーションまたは変換されたバージョンのデータの共有

動的ビューと ABAC ポリシーとのより詳細な比較については、「 ABAC とテーブル レベルの行フィルターと列マスクを使用するタイミング」を参照してください。

行フィルターと列マスクを適用する方法

次のいずれかの方法で行フィルターと列マスクを適用します。

  • ABAC ポリシーの使用 (推奨): 管理されたタグと再利用可能なポリシーを使用して、フィルターとマスクを一元的に適用します。 ABAC はカタログとスキーマにまたがってスケーリングされ、上位レベルの管理者が定義できるため、テーブル所有者はそれらをオーバーライドまたは削除できません。 また、ポリシー ロジックは、テーブル固有の UDF よりも効率的に評価されます。 Unity カタログの属性ベースのアクセス制御を参照してください。
  • テーブルごとの手動割り当て: UDF を個々のテーブルと列に直接割り当てることで、フィルターとマスクを適用します。 これにより、テーブル固有のきめ細かい制御が可能になりますが、スケーリングと保守が困難になります。 「行フィルターと列マスクを手動で適用する」を参照してください。

パフォーマンスに関する推奨事項

行フィルターと列マスクは、フィルター処理またはマスクが適用される前にユーザーがベース テーブルの値を表示できないようにすることで、データの可視性を制御します。 クエリ エンジンは、最適化と、フィルター処理された値またはマスクされた値からの情報漏えいから保護するかを選択する必要がある場合、常にセキュリティで保護された選択を行い、クエリのパフォーマンスに影響を与える可能性があります。 その影響を最小限に抑えるには:

  • 単純な UDF を使用します。 式の数が少ない関数の方がパフォーマンスが向上します。 マッピング テーブルまたは式サブクエリよりも単純な CASE 式を使用します。
  • 大きなテーブルの個別の列マスクの数を制限します。 各個別のマスクは、クエリ中に評価されます。 マスクは真に機密性の高い列にのみ適用し、可能な場合はマスク関数を再利用します。
  • UDF 引数の数を減らします。 Azure Databricksは、UDF 引数から取得された列参照を最適化することはできません。これらの列がクエリで使用されていない場合でもです。 可能な場合は、引数の数が少ない UDF を使用します。
  • AND結合が多すぎる行フィルターは避けてください。 特定のユーザーとテーブルに対して実行時に解決できる個別の行フィルターは 1 つだけであるため、一般的なパターンは、ロジックと ANDを組み合わせることです。 追加する接続が多いほど、結合されたフィルターに上記で警告されたパターンのいずれかが含まれる可能性が高くなります。 可能な場合は、より少ない結合を使用してください。
  • エラーを送出しない確定的な式を使用してください。 エラーをスローする可能性がある式 (ANSI 除算など) では、"0 による除算" などのエラーによってフィルター処理またはマスクの前に値に関する情報が表示される可能性があるため、SQL コンパイラはクエリ プランで操作をプッシュダウンできません。 決定的な式try_divideなど、エラーを発生させないものを使用します。
  • Python UDF よりも SQL を優先してください。 PYTHON UDF は SQL よりもパフォーマンスが低く、最適化の機会が少なくなります。 Pythonを使用する必要がある場合は、必要に応じて UDF を DETERMINISTIC としてマークします。

UDF の完全なパフォーマンス ガイダンス (述語のプッシュダウンとエンジン レベルの最適化の詳細を含む) については、 行フィルターポリシーと列マスク ポリシーのパフォーマンスに関する考慮事項を参照してください。 このガイダンスのほとんどは、手動で適用された行フィルターと列マスクにも同様に適用されます。 UDF の例については、「 行のフィルター処理と列マスクの一般的なパターン」を参照してください。

データ型の不一致の動作

行フィルターまたは列マスクを作成する場合、関数に渡される各テーブル列のデータ型は、UDF 内の対応するパラメーター型と一致する必要があります。 STRING パラメーターに渡されたINT列など、型の不一致がある場合、Databricks は列の値をパラメーター型に暗黙的にキャストします。これにより、変換できない値が列に含まれている場合に予期しない動作が発生する可能性があります。

ANSI モードが無効 (spark.sql.ansi.enabled = false) の場合、キャスト不可能な値はサイレントモードで NULLに変換され、エラーは発生せず、UDF は実際の列値ではなく NULL を受け取ります。 これにより、フィルターではなくすべての行を返す行フィルターや、間違った値をマスクする列マスクなど、正しくない結果が生成される可能性があります。 Databricks では、ANSI モード (spark.sql.ansi.enabled = true) を有効にすることをお勧めします。これにより、キャストが失敗したときにエラーが発生し、問題は自動的に NULL返されるのではなく、すぐに表示されます。

例: 型が一致しない行フィルター

STRING列を持つテーブルと、パラメーターが誤ってINTの代わりにSTRINGとして宣言された行フィルターについて考えてみます。

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に変換されます。 フィルターは入力がtrueされたときにNULLを返すので、departmentが実際にNULLされている行だけでなく、すべての行が返されます。

SELECT * FROM employees;
ID 給料 部署
91 200000 null 値
1 200000 exec
2 50000 工学
3 150000 exec

正しい UDF 定義では、列に一致するパラメーター型として STRING が使用されます。

CREATE FUNCTION salary_filter(dept STRING) RETURNS BOOLEAN
RETURN dept IS NULL;

この修正により、クエリは departmentNULL行のみを返します。

制限事項

  • バージョン 12.2 LTS より前の Databricks Runtime では、行フィルターや列マスクはサポートされていません。 これらのランタイムは安全に失敗します。つまり、これらのランタイムからテーブルにアクセスしようとすると、データは返されません。
  • 行レベル セキュリティや列マスクをビューに適用することはできません。
  • Iceberg REST カタログまたは Unity REST API を使用して、行フィルターまたは列マスクを含むテーブルにアクセスすることはできません。
  • Delta Lake API はサポートされていません。
  • OpenSharing プロバイダーは、テーブル レベルの行フィルターまたは列マスクを使用してテーブルを共有することはできません。 ABAC ベースの行フィルターまたは列マスクを含むテーブルは、共有所有者がポリシーから除外されている場合に共有できます。 ABAC ポリシーまたはそれらを参照するビューが設定された OpenSharing のテーブルを参照してください。
  • OpenSharing 受信者は、行フィルターと列マスクを共有テーブルと外部テーブルにのみ適用でき、ストリーミング テーブルや具体化されたビューには適用できません。
  • ポリシーを含むテーブル内のファイルへのパスベースのアクセスは、サポートされていません。
  • MERGE ステートメントでは、入れ子、集計、ウィンドウ、制限、または非決定関数を含む行フィルターまたは列マスク ポリシーを持つテーブルはサポートされていません。
  • 17.2 より前のバージョンの Databricks Runtime では、パーティション列に対して行フィルターまたは列マスク ポリシーが定義されているパーティション テーブルの DELETEUPDATE、および MERGE はサポートされていません。
  • 元のポリシーに戻る循環依存関係がある行フィルターまたは列マスクのポリシーは、サポートされていません。
  • 行フィルターと列マスクは、アクティブな行フィルターまたは列マスクも含まれるテーブルを参照できません。 ABAC 構成では、参照先テーブルのポリシーからポリシー関数の所有者を除外することで、この問題を回避できます。
  • タイム トラベルは、行レベルのセキュリティや列マスクでは機能しません。 ABAC 構成では、ポリシーから明示的に除外されているユーザーは、基になるデータに対してタイム トラベル クエリを実行できます。
  • 行レベルのセキュリティまたは列マスクを持つテーブルでは、深いクローンと浅いクローンはサポートされません。 ABAC 構成では、ポリシーから明示的に除外されているユーザーは、基になるデータに対してクローン操作を実行できます。
  • 行フィルターまたは列マスクが適用されているテーブルから AI Search インデックスを作成することはできません。
  • 列マスクは、生成された列によって参照される列には適用できません。 「生成された列と列マスク」を参照してください。

専用アクセス モードの制限

Databricks Runtime 15.3 以下の専用アクセス コンピューティング リソースから、行フィルターまたは列マスクを含むテーブルにアクセスすることはできません。 ワークスペースでサーバーレス コンピューティングが有効になっている場合は、Databricks Runtime 15.4 LTS 以降で専用アクセス モードを使用できます。 ただし、Databricks Runtime 15.4 から 16.2 では読み取り操作のみがサポートされます。 書き込み操作 ( INSERTUPDATEDELETEを含む) には Databricks Runtime 16.3 以上が必要であり、 MERGE INTOなどのサポートされているパターンを使用する必要があります。

専用アクセス モード コンピューティングから行フィルターまたは列マスクを使用してテーブルにクエリを実行すると、Azure Databricks はサーバーレス コンピューティングを使用してきめ細かいアクセス制御 (FGAC) を適用します。 その結果、すべての FGAC の制限事項と考慮事項が適用されます。 専用コンピューティングでのきめ細かなアクセス制御を参照してください。