行アクセスポリシーを使用する¶
このトピックでは、行アクセスポリシーの概要を説明します。
このトピックの内容:
行アクセスポリシーを実装する¶
次のサブセクションでは、行アクセスポリシーを実装する方法の例を示します。
マッピングテーブルルックアップを使用した一般的な行アクセスポリシーを使用します。
既存の行アクセスポリシーのサブクエリをメモ化可能な関数に置き換えて、クエリのパフォーマンスを向上させます。
行アクセスポリシーで保護されたマッピングテーブルを、別の行アクセスポリシーで参照します。
例: マッピングテーブルルックアップ¶
次のステップは、行アクセスポリシー権限を設定し、テーブルとビューに行アクセスポリシーを追加するための代表的なガイドです。
これらのステップでは、次を前提としています。
管理アプローチは集中型です。
行アクセスポリシーのユースケースにハイブリッド型または分散型の管理アプローチが含まれている場合のロールと権限の代表的な分布については、 行アクセスポリシーを管理する をご参照ください。
代表的な使用例: マッピングテーブルを使用してクエリ結果をフィルターする と同様に、マッピングテーブルが必要です。
次のステップでは、 CURRENT_ROLE コンテキスト関数を使用して、ユーザーにクエリ結果に行が表示されるかどうかを判断します。一方、代表的なユースケースでは、ユーザーの名(つまり、 CURRENT_USER)に焦点を当てます。
ロールのアクティブ化とロール階層が重要な場合、Snowflake では、ポリシー条件でアカウントロールには IS_ROLE_IN_SESSION 関数を使用し、データベースロールには IS_DATABASE_ROLE_IN_SESSION 関数を使用することをお勧めします。詳細については、 アクティブロール階層およびマッピングテーブル をご参照ください。
コンテキスト関数が異なっていても、マッピングテーブルを使用して行アクセスポリシーを実装するための全体的なプロセスは同様です。
SECURITYADMIN システムロールは、行アクセスポリシーを管理および実装するための権限をカスタムロールに付与します。
実稼働環境で下位の権限のカスタムロール(例:
database_admin
、finance_admin
)を優先して、上位の権限のロール(つまり、 SECURITYADMIN または ACCOUNTADMIN)を使用したくない場合は、下位の権限のロールに、行アクセスポリシーを管理および実装するために必要な権限があるかどうかを確認します。詳細については、 行アクセスポリシーの権限 および DDL コマンド、操作、および権限の概要 をご参照ください。
行アクセスポリシーによって保護されるテーブルを作成するための個別のステップ(ステップ1)と、行アクセスポリシーをテーブルに追加するステップ(ステップ5)があります。行アクセスポリシーがすでに存在することを前提として、テーブルの作成時に行アクセスポリシーをテーブルに追加することができます。構文の詳細については、 CREATE TABLE をご参照ください。
例:
販売データのテーブルを作成します。
CREATE TABLE sales ( customer varchar, product varchar, spend decimal(20, 2), sale_date date, region varchar );
security
スキーマで、 代表的な例 に示すようにマッピングテーブルを作成します。このテーブルは、営業部長が表示できるsales
テーブルの行を定義します。CREATE TABLE security.salesmanagerregions ( sales_manager varchar, region varchar );
次に、セキュリティ管理者が
mapping_role
カスタムロールを作成し、カスタムロールに SELECT 権限を付与します。この付与により、カスタムロールを持つユーザーはマッピングテーブルをクエリできます。USE ROLE SECURITYADMIN; CREATE ROLE mapping_role; GRANT SELECT ON TABLE security.salesmanagerregions TO ROLE mapping_role;
スキーマ所有者のロールを使用して、次の2つの条件で行アクセスポリシーを作成します。
sales_executive_role
カスタムロールを持つユーザーは、すべての行を表示できます。sales_manager
カスタムロールを持つユーザーは、salesmanagerregions
マッピングテーブルに基づいて行を表示できます。
スキーマ所有者のロールには、自動的に CREATE ROW ACCESS POLICY 権限が付与されます。他のロールにより行アクセスポリシーを作成する必要がある場合、スキーマ所有者ロールは、他のロールに CREATE ROW ACCESS ポリシー権限を付与できます。
USE ROLE schema_owner_role; CREATE OR REPLACE ROW ACCESS POLICY security.sales_policy AS (sales_region varchar) RETURNS BOOLEAN -> 'sales_executive_role' = CURRENT_ROLE() OR EXISTS ( SELECT 1 FROM salesmanagerregions WHERE sales_manager = CURRENT_ROLE() AND region = sales_region ) ;
条件:
security.sales_policy
security
スキーマの行アクセスポリシーの名前。AS (sales_region varchar)
行アクセスポリシーの署名。
署名は、マッピングテーブルの属性とデータ型を指定します。戻り値は、行アクセスポリシーが追加されたテーブルまたはビューの特定の行に、ユーザーがアクセスできるかどうかを決定します。
'sales_executive_role' = CURRENT_ROLE()
行アクセスポリシー内の
body
の先頭。sales_executive_role
カスタムロールを持つユーザーがデータを表示できるようにする、行アクセスポリシー式の最初の条件。OR EXISTS (select 1 from salesmanagerregions WHERE sales_manager = CURRENT_ROLE() AND region = sales_region)
サブクエリを使用する行アクセスポリシー式の2番目の条件。
サブクエリでは、
{salesmanagerregions}
マッピングテーブルにリストされているリージョンを指定するために、データに対して実行されたクエリで CURRENT_ROLE がsales_manager
カスタムロールである必要があります。Tip
ポリシーで保護されたテーブルでクエリのパフォーマンスを向上させるには、
EXISTS
句のマッピングテーブルルックアップのサブクエリを メモ化可能な関数 に置き換えます。詳細については、 メモ化可能な関数の例 (このトピック内)をご参照ください。
SECURITYADMIN システムロールを使用して、次の2つのステートメントを実行します。
GRANT OWNERSHIP ON ROW ACCESS POLICY security.sales_policy TO mapping_role; GRANT APPLY ON ROW ACCESS POLICY security.sales_policy TO ROLE sales_analyst_role;
これらの2つの GRANT <権限> ステートメントには次の効果があります。
ポリシーの所有権は、 SECURITYADMIN システムロールに依存しません。ポリシーは 所有者の権限 で実行され、より権限のある SECURITYADMIN システムロールではないため、クエリの実行時にSnowflakeはカスタムロールに付与された権限を使用します。このアプローチは、最小権限の原則をサポートします。
sales_analyst_role
カスタムロールは、必要に応じてテーブルから行アクセスポリシーを追加またはドロップできます。
行アクセスポリシーを
sales
データテーブルのリージョン列に追加(バインド)します。USE ROLE SECURITYADMIN; ALTER TABLE sales ADD ROW ACCESS POLICY security.sales_policy ON (region);
保護された
sales
データに対する SELECT 権限をsales_manager_role
カスタムロールに付与します。GRANT SELECT ON TABLE sales TO ROLE sales_manager_role;
販売データが
sales
データに入力されたら、行アクセスポリシーをテストします。USE ROLE sales_manager_role; SELECT product, SUM(spend) FROM sales WHERE YEAR(sale_date) = 2020 GROUP BY product;
例: ポリシーのサブクエリをメモ化可能な関数に置き換える¶
この例の手順では、行アクセスポリシー条件のマッピングテーブルルックアップごとに メモ化可能な関数 を作成します。各 EXISTS
句のサブクエリは、マッピングテーブルルックアップを指定します。テーブルにはそれぞれ regions
、 customers
、および products
という名前が付けられます。
CREATE OR REPLACE ROW ACCESS POLICY rap_NO_memoizable_function AS (region_id number, customer_id number, product_id number) RETURNS BOOLEAN -> EXISTS(SELECT 1 FROM regions WHERE id = region_id) OR EXISTS(SELECT 1 FROM customers WHERE id = customer_id) OR EXISTS(SELECT 1 FROM products WHERE id = product_id) ;
次の手順では、 rap_admin
カスタムロールが行アクセスポリシーを作成できる(つまり、SCHEMA に対する CREATE ROW ACCESS POLICY 権限がある)と仮定します。
次の手順を実行して、それぞれの行アクセスポリシーのマッピングテーブルルックアップをメモ化可能な関数に置き換えます。
メモ化可能な関数を管理するために、
functions_admin
という名前のカスタムロールを作成します。USE ROLE USERADMIN; CREATE ROLE functions_admin;
次の権限を
functions_admin
ロールに付与して、governance.functions
という名前の既存のスキーマにメモ化可能な関数を作成できるようにします。USE ROLE SECURITYADMIN; GRANT USAGE ON DATABASE governance TO ROLE functions_admin; GRANT USAGE ON SCHEMA governance.functions TO ROLE functions_admin; GRANT CREATE FUNCTION ON SCHEMA governance.functions TO ROLE functions_admin;
行アクセスポリシーの
EXISTS
サブクエリ句ごとにメモ化可能な関数を作成します。メモ化可能な各関数定義は、同じ形式を取ります。簡潔にするために、関数の例を1つだけ示します。USE ROLE functions_admin; USE SCHEMA governance.functions; CREATE OR REPLACE function allowed_regions() RETURNS array memoizable AS 'SELECT ARRAY_AGG(id) FROM regions';
CREATE ROW ACCESS POLICY ステートメントを使用して、サブクエリをメモ化可能な関数に置き換える新しい行アクセスポリシーを定義します。
新しい行アクセスポリシーを使用すると、ポリシーがメモ化可能な関数を使用する場合と使用しない場合に、保護されたテーブルでクエリをテストして、ポリシー条件でメモ化可能な関数を使用した場合のパフォーマンスへの影響を定量化できます。
USE ROLE rap_admin; CREATE OR REPLACE ROW ACCESS POLICY rap_with_memoizable_function AS (region_id number, customer_id number, product_id number) RETURNS BOOLEAN -> ARRAY_CONTAINS(region_id, allowed_regions()) OR ARRAY_CONTAINS(customer_id, allowed_customers()) OR ARRAY_CONTAINS(product_id, allowed_products()) ;
例: 行アクセスポリシーでマッピングテーブルを保護する¶
この例では、行アクセスポリシーで保護されているマッピングテーブルを、別の行アクセスポリシーで参照する方法を示します。マッピングテーブルを保護する行アクセスポリシーは、ロール階層を考慮するために IS_ROLE_IN_SESSION コンテキスト関数を呼び出します。異なる行アクセスポリシーにより、ユーザーがクエリするテーブルは保護されます。この行アクセスポリシーは、サブクエリを使用してマッピングテーブルの検索を実行します。例:
地理的な販売地域に基づいて許可されるロールを定義するマッピングテーブルを作成し、テーブルにデータを挿入します。
CREATE OR REPLACE TABLE sales.tables.regional_managers ( allowed_regions varchar allowed_roles varchar );
INSERT INTO sales.tables.regional_managers (allowed_regions, allowed_roles) VALUES ('na', 'NA_MANAGER'), ('eu', 'EU_MANAGER'), ('apac', 'APAC_MANAGER');
マッピングテーブルの ALLOWED_ROLES 列を指定する行アクセスポリシーを作成します。
CREATE OR REPLACE ROW ACCESS POLICY governance.policies.rap_map_exempt AS (allowed_roles varchar) RETURNS BOOLEAN -> IS_ROLE_IN_SESSION(allowed_roles);
ALTER TABLE ステートメントを使用して、マッピングテーブルに行アクセスポリシーを追加します。
ALTER TABLE sales.tables.regional_managers ADD ROW ACCESS POLICY governance.policies.rap_map_exempt ON (allowed_roles);
保護されたマッピングテーブルのマッピングテーブルルックアップを指定する新しい行アクセスポリシーを作成します。
CREATE OR REPLACE ROW ACCESS POLICY governance.policies.rap_map_lookup AS (allowed_regions varchar) RETURNS BOOLEAN -> EXISTS ( SELECT * FROM sales.tables.regional_managers WHERE REGION = allowed_regions );
ALTER TABLE ステートメントを使用して、
governance.policies.rap_map_lookup
という行アクセスポリシーをsales.tables.data
というテーブルに追加します。ALTER TABLE sales.tables.data ADD ROW ACCESS POLICY governance.policies.rap_map_lookup ON (allowed_regions);
マッピングテーブルのロールに権限を付与し、これらのロールを持つユーザが保護されたデータをクエリできるようにします。たとえば、これらの付与は
na_manager
カスタムロールのためのものです。USE ROLE SECURITYADMIN; GRANT USAGE ON DATABASE sales TO ROLE na_manager; GRANT USAGE ON SCHEMA sales.tables TO ROLE na_manager; GRANT SELECT ON TABLE sales.tables.regional_managers TO ROLE na_manager; GRANT SELECT ON TABLE sales.tables.data TO ROLE na_manager;
必要に応じて、マッピングテーブルの各ロールに対してこのステップのコマンドを繰り返します。