行アクセスポリシーの使用

このトピックでは、行アクセスポリシーの概要を説明します。

このトピックの内容:

行アクセスポリシーの実装

次のステップは、行アクセスポリシー権限を設定し、テーブルとビューに行アクセスポリシーを追加するための代表的なガイドです。

これらのステップでは、次を前提としています。

  • 管理アプローチは集中型です。

    行アクセスポリシーのユースケースにハイブリッド型または分散型の管理アプローチが含まれている場合のロールと権限の代表的な分布については、 行アクセスポリシーの管理 をご参照ください。

  • 代表的な使用例: マッピングテーブルを使用してクエリ結果をフィルターする と同様に、マッピングテーブルが必要です。

    次のステップでは、 CURRENT_ROLE コンテキスト関数を使用して、ユーザーにクエリ結果に行が表示されるかどうかを判断します。一方、代表的なユースケースでは、ユーザーの名(つまり、 CURRENT_USER)に焦点を当てます。

    コンテキスト関数が異なっていても、マッピングテーブルを使用して行アクセスポリシーを実装するための全体的なプロセスは同様です。

  • SECURITYADMIN システムロールは、行アクセスポリシーを管理および実装するための権限をカスタムロールに付与します。

    実稼働環境で下位の権限のカスタムロール(例: database_adminfinance_admin)を優先して、上位の権限のロール(つまり、 SECURITYADMIN または ACCOUNTADMIN)を使用したくない場合は、下位の権限のロールに、行アクセスポリシーを管理および実装するために必要な権限があるかどうかを確認します。

    詳細については、 行アクセスポリシーの権限 および DDL コマンド、操作、および権限の概要 をご参照ください。

  • 行アクセスポリシーによって保護されるテーブルを作成するための個別のステップ(ステップ1)と、行アクセスポリシーをテーブルに追加するステップ(ステップ5)があります。行アクセスポリシーがすでに存在することを前提として、テーブルの作成時に行アクセスポリシーをテーブルに追加することができます。構文の詳細については、 CREATE TABLE をご参照ください。

ステップ1: データのテーブルを作成する

販売データのテーブルを作成します。

create table sales (
  customer   varchar,
  product    varchar,
  spend      decimal(20, 2),
  sale_date  date,
  region     varchar
);

ステップ2: マッピングテーブル、カスタムロールを作成し、 SELECT 権限を付与する

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;

ステップ3: 行アクセスポリシーを作成する

スキーマ所有者のロールを使用して、次の2つの条件で行アクセスポリシーを作成します。

  1. sales_executive_role カスタムロールを持つユーザーは、すべての行を表示できます。

  2. 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)

行アクセスポリシーの署名。

署名は、マッピングテーブルの属性とデータ型を指定します。戻り値は、行アクセスポリシーが追加されたテーブルまたはビューの特定の行に、ユーザーがアクセスできるかどうかを決定します。

returns boolean ->

行アクセスポリシーの適用を指定します。

行アクセスポリシーの <expression> は、右矢印(つまり、 ->)の直後にあります。

式には、ブール値の SQL 式を使用できます。Snowflakeは、 UDFs を呼び出す式、外部関数、およびサブクエリを使用する式をサポートしています。

'sales_executive_role' = current_role()

sales_executive_role カスタムロールを持つユーザーがデータを表示できるようにする、行アクセスポリシー式の最初の条件。

or exists (select 1 from salesmanagerregions where sales_manager = current_role() and region = sales_region)

サブクエリを使用する行アクセスポリシー式の2番目の条件。

サブクエリでは、 {salesmanagerregions} マッピングテーブルにリストされているリージョンを指定するために、データに対して実行されたクエリで CURRENT_ROLE が sales_manager カスタムロールである必要があります。

ステップ4: カスタムロールに権限を付与する

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 <権限> ... TO ROLE ステートメントには次の効果があります。

  • ポリシーの所有権は、 SECURITYADMIN システムロールに依存しません。ポリシーは 所有者の権限 で実行され、より権限のある SECURITYADMIN システムロールではないため、クエリの実行時にSnowflakeはカスタムロールに付与された権限を使用します。このアプローチは、最小権限の原則をサポートします。

  • sales_analyst_role カスタムロールは、必要に応じてテーブルから行アクセスポリシーを追加またはドロップできます。

ステップ5: 行アクセスポリシーをテーブルに追加する

Snowflakeの任意のテーブルまたはビューは、一度に最大1つの行アクセスポリシーをサポートできます。

行アクセスポリシーを Sales データテーブルのリージョン列に追加(つまり、バインド)します。

use role securityadmin;

alter table sales add row access policy security.sales_policy on (region);

ステップ6: 保護されたテーブルデータをロールがクエリできるようにする

保護された sales データに対する SELECT 権限を sales_manager_role カスタムロールに付与します。

grant select on table sales to role sales_manager_role;

ステップ7: ポリシーをテストする

販売データが Sales データに入力されたら、行アクセスポリシーをテストします。

use role sales_manager_role;
select product, sum(spend)
from sales
where year(sale_date) = 2020
group by product;