行フィルターと列マスク
行フィルターと列マスクは、ユーザーがクエリ時に表示できる行と列の値を制限する Unity Catalog のアクセス制御です。このページでは、SQL を使用して個々のテーブルで直接設定され、テーブル所有者によって管理される、これらのコントロールの テーブルレベル の形式について説明します。多数のテーブルにわたる一貫した行フィルターと列マスクには、ABAC ポリシーが推奨されるアプローチです。これらはカタログまたはスキーマレベルで関連付けられ、管理タグに基づいて自動的に適用されます。
Databricks ABACを推奨します 複数のテーブルにわたって一貫した行フィルタリングと列マスキングが必要な場合。 ABAC ポリシーはカタログまたはスキーマ レベルで付加され、テーブルごとの構成を必要とするのではなく、管理タグに基づいて自動的に適用されます。
行フィルターとは何ですか?
行フィルターは、ユーザーがテーブルで見られる行を制限します。フィルターは、クエリ時に各行を評価する SQL ユーザー定義関数 (UDF) です。関数がFALSEを返す行はクエリー結果から除外されます。これは一般的に行レベルのセキュリティに利用されます。たとえば、ユーザーを特定のリージョン、部署、またはアカウントのレコードに制限できます。
テーブルレベルの行フィルターは、ALTER TABLE ... SET ROW FILTER を使用して単一のテーブルにバインドされ、テーブル所有者によって管理されます。複数のテーブル間で一貫した行フィルタリングを行うには、ABAC ポリシーを使用してください。
列マスクとは何ですか?
列マスクは、特定の列に対してユーザーに表示される値を制御します。マスクは、列値を入力として受け取り、元の値またはマスクされたバージョンを返す SQL UDF です。戻り値の型は列のデータ型に一致するか、またはキャスト可能である必要があります。各列には、マスクを1つ設定できます。列マスクは、複数の属性に基づいて動作を変化させるために、他の列を入力として受け取ることができます。
テーブルレベルの列マスクは、 ALTER TABLE ... ALTER COLUMN ... SET MASKを使用して列にバインドされ、テーブルの所有者によって管理されます。そのテーブルのその列にのみ適用されます。複数のテーブルにわたって一貫した列マスキングを行うには、代わりにABACポリシーを使用してください。
動的ビューの代わりにABACポリシーを使用するタイミング
Unity Catalog は、行レベルおよび列レベルのアクセス制御に、2つの関連する仕組みを提供しています。
- ABAC ポリシー は、カタログまたはスキーマレベルでアタッチされ、管理タグに基づいてテーブルと列に自動的に適用されます。ABAC は、多くのテーブル間で一貫したルール、ポリシー作成者とデータスチュワード間での職務の分離、またはタグ付けされた新しいテーブルへの自動的な適用が必要な場合に活用できます。テーブルレベルの行フィルターおよび列マスクとの並列比較については、「ABACとテーブルレベルの行フィルターおよび列マスクの使い分け」を参照してください。
- 動的ビュー は、1つ以上の基底テーブルをSQLビューとしてラップし、行をフィルターし、列をマスクし、またはデータを再構築します。通常、
is_account_group_member()のようなグループメンバーシップ関数によって制御されます。基になるテーブルにアクセス権を持たないユーザーに、キュレートされた、変換された、または結合されたバージョンのデータを公開したい場合は、動的ビューを使用してください。使用例としては、ファクトテーブルの編集済みスライスをアナリストグループと共有する、または複数のテーブルの列を単一のセキュアなレイヤーに結合する、などが挙げられます。
アプローチ | 適用対象 | 管理 | 最適な用途 |
|---|---|---|---|
テーブルレベルの行フィルターと列マスク | 個別のテーブルと列 |
| テーブルのロジック |
ABACポリシー | タグの条件に一致するテーブルと列 |
| 多数のテーブルにわたって、一元管理されたルールが自動的に適用されます。 |
動的ビュー | 1つ以上のベーステーブルから構築されたビュー | ビューの定義内のSQLロジック | キュレーションまたは変換されたデータの共有 |
動的ビューおよびABACポリシーとの詳細な比較については、 「ABACとテーブルレベルの行フィルターおよび列マスクをいつ使用するか」を参照してください。
行フィルターと列マスクを適用する方法
次のいずれかの方法で、行フィルターと列マスクを適用します。
- **ABAC ポリシーの使用**(推奨):管理タグと再利用可能なポリシーを使用して、フィルターとマスクを一元的に適用します。ABACはカタログとスキーマ全体にわたって拡張され、上位の管理者によって定義できます。そのため、テーブル所有者がそれらをオーバーライドしたり削除したりすることはできません。ポリシーロジックも、テーブル固有の UDF よりも効率的に評価されます。Unity Catalog の属性ベースのアクセス制御を参照してください。
- テーブルごとの手動割り当て :UDF を個々のテーブルと列に直接割り当てて、フィルターとマスクを適用します。これにより、きめ細かなテーブルごとの制御が可能となりますが、スケーリングや保守がより困難になります。「行フィルターと列マスクを手動で適用する」を参照してください。
パフォーマンスに関する推奨事項
行フィルターと列マスクは、フィルタリングやマスキング操作の前にユーザーがベーステーブルの値の内容を閲覧できないようにすることで、データの可視性を制御します。クエリエンジンが最適化と、フィルタリングまたはマスクされた値からの情報漏洩防止のどちらかを選択する必要がある場合、常に安全な選択を行います。その結果、クエリのパフォーマンスに影響を与えることがあります。その影響を最小限に抑えるには:
- シンプルな UDF を使用してください。 式の少ない関数は、より優れたパフォーマンスを発揮します。マッピングテーブルや式サブクエリよりも、シンプルな
CASE式の使用を推奨します。 - 大規模なテーブルでは、異なる列マスクの数を制限する。 個別のマスクはクエリの実行中に評価されます。マスクは非常に機密性の高い列にのみ適用し、可能な場合はマスク機能を再利用してください。
- UDF引数の数を削減します。 Databricks は、UDF 引数に由来する列参照を最適化できません。それらの列がクエリで使用されていない場合でも同様です。可能な限り、引数の少ない UDF を使用してください。
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プロバイダーは、テーブルレベルの行フィルターまたは列マスクを使用してテーブルを共有することはできません。ABACベースの行フィルターまたは列マスクが設定されたテーブルは、共有所有者がポリシーの適用除外対象である場合に限り共有できます。ABAC ポリシーを含む Delta Sharing テーブル、またはそれらを参照するビューを参照してください。
- Delta Sharing 受信者は、ストリーミングテーブルやマテリアライズドビューではなく、共有テーブルやフォーリンテーブルにのみ行フィルターと列マスクを適用できます。
- ポリシーを持つテーブル内のファイルへの、パスベースのアクセスはサポートされていません。
MERGEステートメントは、ネスト、集計、ウィンドウ、制限、または非決定論的関数を含む行フィルターまたは列マスク ポリシーを持つテーブルをサポートしません。- 17.2 より前のバージョンの Databricks Runtime では、パーティション列に行フィルターまたは列マスク ポリシーが定義されているパーティション テーブル上の
DELETE、UPDATE、およびMERGEはサポートされません。 - 元のポリシーに戻る循環依存性を持つ行フィルターまたは列マスクポリシーはサポートされていません。
- 行フィルターと列マスクは、アクティブな行フィルターまたは列マスクを持つテーブルを参照することはできません。ABAC 構成では、参照されるテーブルのポリシーからポリシー関数の所有者を除外することで、この問題を回避できます。
- タイムトラベルは、行レベルのセキュリティまたは列マスクでは機能しません。 ABAC 構成では、ポリシーから明示的に除外されているユーザーでも、基礎となるデータに対してタイムトラベル クエリを実行できます。
- 行レベルのセキュリティまたは列マスクを持つテーブルでは、ディープ クローンおよびシャロー クローンはサポートされません。ABAC 構成では、ポリシーから明示的に除外されているユーザーでも、基礎となるデータに対してクローン操作を実行できます。
- 行フィルターまたは列マスクが適用されているテーブルからは、AI Search インデックスを作成できません。
- 列マスクは、生成された列によって参照される列には適用できません。生成された列と列マスクを参照してください。
専用アクセスモードの制限
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 バケットのバージョン管理に関する考慮事項を参照してください。