MaxCompute テーブル内の特定データに対するユーザーまたはロールのアクセスを制御するために、MaxCompute では行レベルのアクセス制御機能を提供しています。この機能により、ユーザーがアクセスを許可されているデータとマッチするポリシーを定義できます。これらのポリシーをテーブルに直接適用することで、ユーザーおよびロールは認可されたデータのみを参照できるようになり、データセキュリティおよびコンプライアンスが強化されます。
背景情報
MaxCompute テーブルには大量のデータが含まれる場合があります。データ共有のシナリオにおいて、データ管理者は特定のユーザーがアクセスを許可されたデータ行のみを参照できるようにする必要があります。従来、行レベルのアクセス制御を行うには、各ユーザー向けに個別のビューを作成するか、ETL タスクを使用してフィルター処理を行い、別のテーブルにデータをコピーする必要がありました。
行レベルのアクセス制御により、このワークフローが簡素化されます。データの移動やコピー、ビューの作成および保守は不要になります。
行レベルのアクセス制御は、以下のシナリオに適用されます。
SQL クエリ。
MaxCompute Tunnel を使用したテーブルデータのダウンロード。
Spark や Flink などの外部エンジンによるテーブルデータの読み取り。
Hologres など、MaxCompute の行レベルのアクセス制御をサポートしていないエンジンは、保護されたデータにアクセスできません。ただし、ビューまたはコピーされたテーブルを使用してフィルター済みのデータを共有することは可能です。
以下の表は、行レベルのアクセス制御に関するコマンドを示しています。
操作 | 説明 | エントリポイント |
指定されたユーザーまたはロール向けの Row Access Policy を作成または変更します。 | ||
テーブルからポリシーを削除します。 | ||
テーブル上のポリシーの権限詳細を表示します。 | ||
テーブル上のポリシー一覧を表示します。 |
制限事項
行レベルのアクセス制御には、以下の制限事項が適用されます。
管理者(Admin ロールを持つユーザーまたはテーブル所有者)のみが Row Access Policy を構成できます。
トランザクションテーブル、ビュー、マテリアライズドビューには Row Access Policy を構成できません。Row Access Policy が設定されたテーブルに対してマテリアライズドビューを作成することも、マテリアライズドビューのベーステーブルに対して Row Access Policy を追加することもできません。ただし、Row Access Policy が設定されたテーブルに基づいてビューを作成することは可能です。この場合、ビューからのクエリ結果は、ベーステーブルの Row Access Policy とビュー所有者が定義したルールの両方によって決定されます。
Row Access Policy が設定されたテーブルに対してスキーマ進化操作を実行することはできません。
Row Access Policy が設定されたテーブルを UDF テーブルリソースとして追加することはできません。また、UDF テーブルリソースであるテーブルに対して Row Access Policy を構成することもできません。構成時にはエラーは報告されませんが、ランタイムでエラーが発生します。
Row Access Policy が設定されたテーブルに対してマスキングルールを追加することはできません。
行レベルのアクセス制御は現在、パーティションプルーニングをサポートしていません。
dsがパーティションフィールドの場合、filter_expr内でds='20220101'のようなフィルター条件を指定しても、データをフィルターするために全表スキャンが必要になる可能性があります。filter_exprの詳細については、「filter_expr の説明」をご参照ください。
パッケージを使用して Row Access Policy が設定されたテーブルをプロジェクト間で共有する場合、以下の制限事項が適用されます。
現在のテナントの Alibaba Cloud アカウントまたは RAM ユーザーなど、プロジェクト外のユーザーに対して行レベルの権限を構成できます。
Row Access Policy が設定されたテーブルをプロジェクト間で使用する場合、ユーザー向けポリシーまたは DEFAULT ポリシーのみが適用されます。
Row Access Policy が設定されたパッケージ内のテーブルに対して、別の Row Access Policy を追加することはできません。
注意事項
filter_expr内で使用される演算子または関数の動作は、さまざまなフラグパラメーターの影響を受ける場合があります。MaxCompute は、クエリ実行時のパラメーター設定がポリシー作成時と一致しているかどうかをチェックします。一致しない場合は、以下のエラーが発生します。FAILED: ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: java.lang.IllegalArgumentException: Row access policy flag mismatch for: xxxCREATE、DROP、DESC、LIST などの行レベルのアクセス制御コマンドを実行する前に、セッションレベルで以下の GUC パラメーターを設定して、行レベルのアクセス制御を有効にする必要があります。
説明この機能は今後のリリースでセッションレベルでデフォルトで有効になる予定です。詳細については、リリースアナウンスをご参照ください。
SET odps.sql.row.policy.enabled=true;行レベルのアクセス制御が有効なテーブルをクエリする場合、行レベルのアクセス制御がパーティションプルーニングをサポートしていないため、フィルター処理によって従量課金の入力データ量は削減されません。Row Access Policy を持つユーザーは、全表をクエリしてもフィルター済みの結果セットを受け取る可能性があります。ソーステーブルからスキャンされるデータ量は、結果サイズに基づく想定よりも大きくなる場合があります。コストに十分ご注意ください。
異なるユーザー向けにフィルタールールを含む複数のビューまたはテーブルを作成・共有することで、行レベルのアクセス制御を実装することも可能です。この方法では、すでにフィルター済みのデータに対して計算を実行でき、よりシンプルで直感的です。詳細については、「行レベルのアクセス制御」をご参照ください。ユーザー向けの共有オブジェクトを作成する方法と比較して、行レベルのアクセス制御は元のテーブルのクエリ実行計画をより複雑にします。一方で、個別の共有オブジェクトを作成する必要がなく、冗長なストレージを回避でき、多数のユーザー向けにルールを定義するのに適しています。ニーズに最も合う方法を選択してください。
構文
CREATE/REPLACE、DROP、DESC、LIST コマンドを使用して、Row Access Policy の作成(または変更)、削除、または表示を行います。
CREATE/REPLACE
構文
CREATE [OR REPLACE] ROW ACCESS POLICY [IF NOT EXISTS] <policy_name> ON <table_name> TO <authorized_objects> FILTER USING <filter_expr> [AS <clause>];説明
指定されたユーザーまたはロールに権限を付与する Row Access Policy を作成または変更します。
パラメーター
パラメーター
説明
policy_name
Row Access Policy の名前です。任意の名前を指定できます。
table_name
アクセス対象のテーブル名です。
authorized_objects
権限付与対象のオブジェクトです。有効な値は以下のとおりです。
USER <user_list>:権限を付与するユーザー名のリスト(カンマ区切り)。ROLE <role_list>:権限を付与するロール名のリスト(カンマ区切り)。DEFAULT:ユーザー向けルールまたはロール向けルールに該当しない場合に適用されるデフォルトルール。
filter_expr
フィルター式です。詳細については、「filter_expr の説明」をご参照ください。
clause
Row Access Policy の属性です。値は
PERMISSIVEまたはRESTRICTIVEです。詳細については、「PERMISSIVE または RESTRICTIVE 属性の指定」をご参照ください。filter_expr の説明
現行バージョンでは、filter_expr に厳格な制約が課されています。
filter_exprは、BOOLEAN 型を返すスカラー式である必要があります。この式には、サブクエリや SELECT、CREATE、UPDATE などの文を含めることはできません。
filter_exprは、認可対象テーブルの定数またはカラムのみを参照できます。他のテーブルのカラムを参照することはできません。MaxCompute の組み込み演算子(関係演算子、算術演算子、ビット演算子、論理演算子など)を使用できます。詳細については、「演算子」をご参照ください。
組み込みスカラー関数の一部のみが許可されています。ユーザー定義関数 (UDF)、集計関数、ウィンドウ関数はサポートされていません。サポートされている関数は以下のとおりです。
文字列関数:CONCAT、CONCAT_WS、GET_JSON_OBJECT、INSTR、LENGTH、LENGTHB、REGEXP_EXTRACT、REGEXP_REPLACE、REVERSE、SUBSTR、TOLOWER、TOUPPER、TRIM、LTRIM、RTRIM、REPLACE。
数学関数:ABS、ROUND。
日時関数:DATEADD、TO_DATE、TO_CHAR。
その他の関数:SIZE、FIELD、COALESCE、IF、SPLIT。
PERMISSIVE または RESTRICTIVE 属性の指定
特定のユーザーに対して複数のポリシーが適用される場合があります。これらのポリシーは組み合わされて、ユーザーが特定のデータ行に最終的にアクセスできるかどうかが決定されます。Row Access Policy を作成する際、
AS {PERMISSIVE | RESTRICTIVE}を使用して、ポリシー属性をPERMISSIVEまたはRESTRICTIVEとして指定できます。属性を指定しない場合、ポリシーはデフォルトでPERMISSIVEになります。以下に例を示します。ユーザーに複数のポリシーが適用される場合:
すべてのポリシーが PERMISSIVE の場合、それらは OR 条件で結合されます。いずれかのポリシーの
filter_exprが true と評価されれば、ユーザーはその行にアクセスできます。すべてのポリシーが RESTRICTIVE の場合、それらは AND 条件で結合されます。ユーザーはすべてのポリシーを満たす場合にのみ、その行にアクセスできます。
一部のポリシーが PERMISSIVE で、他のポリシーが RESTRICTIVE の場合、ユーザーは以下の両方の条件を満たす場合にのみ、その行にアクセスできます。
少なくとも 1 つの PERMISSIVE ポリシーを満たしていること。
すべての RESTRICTIVE ポリシーを満たしていること。
説明テーブルに新しい Row Access Policy を追加するたびに、そのテーブル上のすべてのポリシーの組み合わせによる影響を評価する必要があります。たとえば、ユーザーが RESTRICTIVE ポリシーと PERMISSIVE ポリシーの両方の対象となる場合、すべての RESTRICTIVE ポリシーの条件を満たし、かつ少なくとも 1 つの PERMISSIVE ポリシーの条件を満たす必要があります。
ユースケース
特定のユーザーへの権限付与
テーブル名が
table01で、STRING 型のカラムregionを含んでいると仮定します。一部のユーザーに対して Row Access Policy を設定し、regionカラムの値がchinaのレコードのみにアクセスできるように制限します。コマンド例は以下のとおりです。CREATE ROW ACCESS POLICY policy01 ON table01 TO USER (aliyun$odps_test01**@aliyun.com,aliyun$odps_test02**@aliyun.com) FILTER USING (region = "china");特定のロールへの権限付与
システムに
role1およびrole2という 2 つのロールがあるとします。これらの 2 つのロールに対して、regionフィールドの値がchinaのレコードのみにアクセスできるように権限を付与します。コマンドは以下のとおりです。CREATE ROW ACCESS POLICY policy02 ON table01 TO ROLE (role1, role2) FILTER USING (region = "china");デフォルトユーザーへの権限付与
テーブルに最初の Row Access Policy を追加すると、アクセスが制限されます。どのポリシーにも該当しないユーザーは、許可リストに含まれていないため、データへのアクセス権を失います。残りのユーザーのアクセスを制御するには、デフォルトポリシーを構成できます。このとき、管理者は以下のコマンドを使用して、デフォルトユーザーのアクセス権限を変更できます。
他のすべてのユーザーへのアクセスをデフォルトで拒否することは、デフォルトユーザーにアクセス権限がないことを指定することと同等です。
CREATE ROW ACCESS POLICY policy03 ON table01 TO DEFAULT FILTER USING (false);regionフィールドの値がotherのレコードのみにデフォルトユーザーがアクセスできるように制限する場合、コマンドは以下のとおりです。CREATE ROW ACCESS POLICY policy04 ON table01 TO default FILTER USING (region = "other");重要テーブルに Row Access Policy を追加する際は、制御対象外のユーザーのアクセス動作を考慮してください。他のユーザーが以前にテーブルにアクセスしていた場合、意図しないアクセス拒否エラーを回避するために、明示的なルールを設定する必要があります。
権限付与ロジック
ユーザーが Row Access Policy が設定されたテーブルにアクセスする際の権限付与プロセスを以下のフローチャートに示します。
DROP
テーブルから特定のポリシーを削除します。
DROP ROW ACCESS POLICY <policy_name> ON <table_name>;テーブルからすべてのポリシーを削除します。
DROP ALL ROW ACCESS POLICY ON <table_name>;
DESC
テーブル上の特定のポリシーの詳細を表示します。
DESC ROW ACCESS POLICY <policy_name> ON <table_name>;LIST
テーブル上のすべてのポリシーを一覧表示します。
LIST ROW ACCESS POLICY ON <table_name>;テーブル上で特定のユーザーに構成されたポリシーを表示します。
LIST ROW ACCESS POLICY ON <table_name> TO USER <user_name>;テーブル上で特定のロールに構成されたポリシーを表示します。
LIST ROW ACCESS POLICY ON <table_name> TO ROLE <role_name>;
サンプルデータ
policy_test という名前のテーブルを作成し、データを挿入します。SQL コマンドは以下のとおりです。
-- テーブルを作成します。
CREATE TABLE policy_test(a bigint, b string);
-- テーブルにデータを挿入します。
INSERT overwrite TABLE policy_test VALUES(1L, "1"), (2L, "2"), (3L, "3"), (4L, "4");
-- 挿入されたデータを確認します。
SELECT * FROM policy_test;
-- 以下の結果が返されます:
+------------+---+
| a | b |
+------------+---+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
+------------+---+例
このセクションでは、デフォルトユーザー向けに行レベルの権限を使用する方法の例を示します。開始する前に、サンプルデータ を準備する必要があります。
例 1:
policy_testテーブルに対して行レベルの権限を付与し、デフォルトユーザーがa=2Lのデータにアクセスできるようにします。policy01 という名前の Row Access Policy を作成します。
CREATE row access policy policy01 ON policy_test TO default filter using (a = 2L);policy_test テーブル上の policy01 の詳細を表示します。
DESC row access policy policy01 on policy_test;以下の結果が返されます。
-- Restrictive プロパティはデフォルト値 false に設定されています。 Authorization Type: Row Access Policy Name: policy01 Objects: acs:odps:*:projects/clone_table_2/tables/policy_test FilterExpr: (a = 2L) NormalizedFilterExpr: (policy_test.a = 2L) Restrictive: false Settings: OKpolicy_test テーブルをクエリして、権限付与が有効であることを確認します。
SELECT * FROM policy_test;以下の結果が返されます。
-- ポリシーが有効であり、レコードのサブセットのみが返されます。 +------------+---+ | a | b | +------------+---+ | 2 | 2 | +------------+---+Logview のサマリーに以下の情報が含まれている場合、行レベルのフィルターがトリガーされています。
WARNING:[1,15] row access policy is enabled on table xxx.xxx_xxx.policy_test resource cost: cpu 0.00 Core * Min, memory 0.00 GB * Min inputs: xxx.xxx_xxx.policy_test: 4 (510 bytes) outputs: ----------------------------------------JOB:SQL_0_0_0_job_0---------------------------------------- Job run time: 1.453 Job run mode: service job 2.0 Job run engine: execution engine M1: bubble: 0 instance count: 1 run time: 1.450 instance time:
例 2:テーブルに 2 つの許容的(permissive)な行レベルの権限を追加し、デフォルトユーザーが policy_test テーブルの
a=2Lまたはa=3Lのデータにアクセスできるようにします。policy02 という名前の Row Access Policy を作成します。
CREATE row access policy policy02 ON policy_test TO default filter using (a = 3L);policy_test テーブル上のすべてのポリシーを一覧表示します。
LIST row access policy ON policy_test;以下の結果が返されます。
Authorization Type: Row Access Policy Name: policy01 Objects: acs:odps:*:projects/clone_table_2/tables/policy_test FilterExpr: (a = 2L) NormalizedFilterExpr: (policy_test.a = 2L) Restrictive: false Settings: Name: policy02 Objects: acs:odps:*:projects/clone_table_2/tables/policy_test FilterExpr: (a = 3L) NormalizedFilterExpr: (policy_test.a = 3L) Restrictive: false Settings: OKpolicy_test テーブルをクエリして、権限付与が有効であることを確認します。
SELECT * FROM policy_test;以下の結果が返されます。
-- 2 つの PERMISSIVE ポリシー policy01 および policy02 が両方とも有効です。2 件のレコードが返されます。 +------------+---+ | a | b | +------------+---+ | 2 | 2 | | 3 | 3 | +------------+---+
例 3: テーブルに行レベルの権限を許可用 2 つと制限用 1 つ追加すると、デフォルトユーザーは、
policy_testテーブル内で (a=2L||a=3L) &&a<3Lを満たすデータにアクセスできます。policy03 という名前の Row Access Policy を作成し、その属性を RESTRICTIVE に設定します。
CREATE row access policy policy03 ON policy_test TO default filter using (a < 3L) as restrictive;policy_test テーブル上の policy03 の詳細を表示します。
DESC row access policy policy03 ON policy_test;以下の結果が返されます。
-- Restrictive プロパティは true に設定されています。 Authorization Type: Row Access Policy Name: policy03 Objects: acs:odps:*:projects/clone_table_2/tables/policy_test FilterExpr: (a < 3L) NormalizedFilterExpr: (policy_test.a < 3L) Restrictive: true Settings: OKpolicy_test テーブルをクエリして、権限付与が有効であることを確認します。
select * from policy_test;以下の結果が返されます。
-- ポリシー policy01、policy02、および policy03 がすべて有効です。 -- policy01 および policy02 は PERMISSIVE であるため、いずれか 1 つを満たせば十分です。 -- policy03 は RESTRICTIVE であるため、必ず満たす必要があります。 +------------+---+ | a | b | +------------+---+ | 2 | 2 | +------------+---+
例 4:テーブルに 1 つの PERMISSIVE ポリシーと 1 つの RESTRICTIVE ポリシーを追加します。デフォルトユーザーは両方の条件を満たす必要があり、テーブルデータにアクセスできます。
policy01 という名前の Row Access Policy を削除します。
SET odps.sql.row.policy.enabled=true; DROP ROW ACCESS POLICY policy01 ON policy_test;policy_test テーブル上の行レベルの権限を表示します。
SET odps.sql.row.policy.enabled=true; LIST ROW ACCESS POLICY ON policy_test;以下の結果が返されます。
Authorization Type: Row Access Policy Name: policy02 Objects: acs:odps:*:projects/clone_table_2/tables/policy_test FilterExpr: (a = 3L) NormalizedFilterExpr: (policy_test.a = 3L) Restrictive: false Settings: Name: policy03 Objects: acs:odps:*:projects/clone_table_2/tables/policy_test FilterExpr: (a < 3L) NormalizedFilterExpr: (policy_test.a < 3L) Restrictive: true Settings: OKpolicy_test テーブルをクエリして、権限付与の結果を確認します。
-- テーブル内のデータを確認します。 SELECT * FROM policy_test;以下の結果が返されます。
-- 結果は空です。a=3 および a<3 の条件を同時に満たすことはできないためです。 +------------+------------+ | a | b | +------------+------------+ +------------+------------+
付録
互換性動作のチェック
MaxCompute がフィルター式を評価する際、その動作はフラグパラメーターの影響を受ける場合があります。ユーザーがある互換性動作の下で Row Access Policy を定義し、その後別の動作の下で他のポリシーを定義した場合、予期しない結果によりデータ漏えいが発生する可能性があります。そのため、行レベルのアクセス制御が適用される際、システムは定義時の互換性動作をチェックします。設定が不整合である場合、エラーが報告され、アクセスが拒否されます。
例:この例では、サンプルデータ を使用して、異なる互換性動作の下でポリシーがどのように適用されるかを示します。
2 番目のパラメーターが 0 の場合の
SUBSTR関数の動作は、Hive 互換モードによって影響を受けます。詳細については、「SUBSTR」をご参照ください。Hive 互換モードでは、
SUBSTR関数の開始位置が 0 の場合、開始位置が 1 の場合と同じ結果になります。SET odps.sql.hive.compatible=true; SELECT substr('abc', 0); -- Hive 互換モードでは、開始位置 0 は開始位置 1 と同じ扱いになります。 +-----+ | _c0 | +-----+ | abc | +-----+Hive 互換モード以外では、開始位置が 0 の場合、空文字列が返されます。
SET odps.sql.hive.compatible=false; SELECT substr('abc', 0); -- Hive 互換モード以外では、開始位置 0 は空文字列を返します。 +-----+ | _c0 | +-----+ | | +-----+
Row Access Policy を作成する際、システムは
filter_expr内で使用される演算子および関数をチェックします。それらの動作が特定のフラグパラメーターに依存する場合、これらのパラメーターがSettingsに記録されます。DESC コマンドを使用して、関連するフラグパラメーターを確認できます。-- テーブル上のすべてのポリシーを削除します。 DROP ALL row access policy ON policy_test; -- Hive 互換モードでポリシーを構成し、filter_expr 内で SUBSTR 関数を使用します。 SET odps.sql.hive.compatible=true; CREATE row access policy policy04 ON policy_test TO default filter using(substr(b, 0)='1'); -- policy_test テーブル上に構成されたポリシーの詳細を表示します。 DESC row access policy policy04 on policy_test;以下の結果が返されます。
Settingsフィールドに、odps.sql.hive.compatibleパラメーターの値が表示されます。Authorization Type: Row Access Policy Name: policy04 Objects: acs:odps:*:projects/sql_optimizer/tables/policy_test FilterExpr: substr(b, 0) = '1' NormalizedFilterExpr: ::substr(policy_test.b, 0) = '1' Restrictive: false Settings: odps.sql.hive.compatible=trueポリシーが後で適用される際、システムは現在の環境の
Settingsがポリシー作成時のSettingsと一致しているかどうかをチェックします。一致しない場合、エラーが報告されます。Hive 互換モードでポリシーを適用します。
SET odps.sql.hive.compatible=true; SELECT * FROM policy_test;以下の結果が返されます。
+------------+---+ | a | b | +------------+---+ | 1 | 1 | +------------+---+Hive 非互換モードでは、
odps.sql.hive.compatibleパラメーターの値がポリシー作成時に指定された値と不一致であるため、クエリの実行に失敗します。SET odps.sql.hive.compatible=false; SELECT * FROM policy_test;以下の結果が返されます。
FAILED: ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: java.lang.IllegalArgumentException: Row access policy flag mismatch for: odps.sql.hive.compatible, flag value when grant this policy is true, while at runtime is false. please set odps.sql.hive.compatible = true or contact your project manager.
MaxCompute Tunnel ダウンロード動作
Row Access Policy が設定されたテーブルから MaxCompute Tunnel を使用してデータをダウンロードする場合でも、行レベルのアクセス制御のルールに従う必要があります。ただし、Tunnel 自体はフィルターロジックを実行できません。代わりに、SQL タスクを開始してデータをフィルター処理し、その結果をダウンロードします。
したがって、Tunnel コマンドまたは Tunnel SDK を使用して Row Access Policy が設定された MaxCompute テーブルからデータをダウンロードする際には、SQL タスクが実行されるまでの待ち時間が発生します。
Row Access Policy の作成無効化
プロジェクト内で新しい Row Access Policy の作成を防止するため、プロジェクト管理者は以下のコマンドを実行してプロジェクトプロパティを変更できます。
管理者のみが setproject コマンドを使用して、このパラメーターをプロジェクトレベルで変更できます。ユーザーはセッションレベルでパラメーター値を変更できません。
setproject odps.sql.create.row.policy.disable=true;有効な値は以下のとおりです。
false(デフォルト):新しい Row Access Policy の作成を許可します。true:新しい Row Access Policy の作成を禁止しますが、既存のポリシーの変更および削除は許可します。