ポリシーで保護されたデータを共有する

このプレビューでは、データ共有コンシューマーが共有データベースロールを使用して、マスキングポリシーまたは行アクセスポリシーで保護された共有データにアクセスできるようにします。

概要

データ共有プロバイダーは、マスキングポリシーまたは行アクセスポリシーの条件で IS_DATABASE_ROLE_IN_SESSION コンテキスト関数を使用して、データ共有コンシューマーがこれらのポリシーのいずれかによって保護されている共有データにアクセスできるようにすることができます。これにより、プロバイダーにはデータ共有の選択肢が増え、コンシューマーはプロバイダーが公開する機密データにアクセスできるようになります。

プロバイダーは、ポリシーと共有オブジェクトを単一のデータベースにグループ化するか、異なるデータベースにグループ化するかを選択できます。ポリシーと保護されたテーブルが異なるデータベースにある場合、プロバイダーは次のことを実行する必要があります。

  • 両方の データベースをコンシューマーアカウントに共有します。

  • ポリシーと同じデータベースにデータベースロールを作成します。

  • ポリシーを含む共有にデータベースロールを付与します。

コンシューマーが共有からデータベースを作成すると、共有内のデータベースロールは、共有からデータベースを作成するロールに付与されます。これにより、コンシューマーアカウントのアカウントロールがデータベースロールを指定するポリシー条件を満たし、共有データにアクセスできるようになります。

ポリシーによって保護された共有データにアクセスするには、コンシューマーは共有データベースロールを含むデータベースを指定して、現在のセッションで共有データベースロールをアクティブにする必要があります。この文脈では、データベースロールをアクティブにするということは、ユーザーが現在のロールのロール階層でデータベースロールを利用できることを意味します。この共有データベースを指定しない場合、コンシューマーアカウントのユーザーは、ポリシーによって保護されている共有データにアクセスできません。このデータベースは、次のいずれかのオプションを使用して指定できます。

  • USE <オブジェクト> コマンドでセッションのデータベースをアクティブにするか、ワークシートでデータベースを選択します。例:

    USE DATABASE mounted_db;
    
    Copy

    mounted_db は、コンシューマーが共有から作成するデータベースの名前です。

  • 特定のクエリには、データベースロールと同じデータベースにあるオブジェクトの完全修飾名を使用してください。例:

    SELECT * FROM mounted_db.myschema.mytable;
    
    Copy

関数を呼び出す

IS_DATABASE_ROLE_IN_SESSION コンテキスト関数の引数の指定方法には、文字列リテラルと非リテラル(列名など)の2種類があります。

  • IS_DATABASE_ROLE_IN_SESSION コンテキスト関数で データベースロールを文字列 として指定する場合、関数の呼び出し結果はその関数の呼び出し方に応じて異なります。例:

    • ワークシートでは、Snowflakeはセッションで使用中のデータベース、またはクエリで指定されたデータベースを参照します。これはプロバイダーアカウントとコンシューマーアカウントの両方に適用されます。

    • ポリシー、 UDF、またはビューで、 ポリシーが共有されている 場合、Snowflakeはポリシーが定義されているデータベースを参照します。ポリシーが共有されていない場合、データベースロール検索の結果、データベースロールが別のデータベースに定義されていると、Snowflakeはエラーを返します。

      A Role Context Function cannot reference a DB Role in another database.
      
      Copy
  • IS_DATABASE_ROLE_IN_SESSION コンテキスト関数の 引数に列名 を指定した場合:

    • テーブルクエリがこの関数を呼び出す場合、列はその列を含むテーブルのテーブル識別子にマップされます。次にSnowflakeは、テーブルを含むデータベースのデータベースロールを調べます。たとえば、 AUTHZ_ROLE 列(つまり認可されたロール)を引数として指定します。

      SELECT * FROM mydb.myschema.t WHERE IS_DATABASE_ROLE_IN_SESSION(AUTHZ_ROLE);
      
      Copy
    • マスキングポリシー、行アクセスポリシー、または UDF が関数を呼び出すと、そのポリシーまたは UDF を含むデータベースで検索が行われます。

一般的なワークフロー

ポリシーで保護されたデータをポリシー内の IS_DATABASE_ROLE_IN_SESSION 関数と共有するには、関数を呼び出してデータを共有するポリシーを作成するのと同じ手順が必要です。まとめ:

  1. プロバイダーはアカウントロールを作成します。

  2. プロバイダーはポリシーを作成し、テーブルまたは列にポリシーを設定します。

  3. プロバイダーは、アカウントロールでポリシーをテストします。

  4. プロバイダーはデータベースロールを作成し、そのデータベースロールを使用してポリシーをテストします。

  5. プロバイダーは共有を作成し、共有にデータベースロールの付与を含む権限を付与します。

  6. コンシューマーは共有からデータベースを作成します(マウントされたデータベース など)。

  7. コンシューマーは、ポリシーによって保護されている共有オブジェクトをクエリします。

例: 同じデータベース内にあるすべてのオブジェクト

この例では、データベースロール、マスキングポリシー、保護されたテーブルはすべて、 mydb という同じデータベース内にあります。

参照情報:

  • データベースロールは mydb.analystmydb.support です。

  • マスキングポリシーは次のように定義されています。

    CREATE OR REPLACE MASKING POLICY mydb.policies.email_mask
      AS (val string) RETURNS string ->
      CASE
        WHEN IS_DATABASE_ROLE_IN_SESSION('MYDB.ANALYST')
          THEN val
        WHEN IS_DATABASE_ROLE_IN_SESSION('MYDB.SUPPORT')
          THEN REGEXP_REPLACE(val,'.+\@','*****@')
        ELSE '********'
      END
      COMMENT = 'use database role for shared data'
      ;
    
    Copy
  • EMAIL 列は、 mydb.tables.empl_info という名前のテーブルにあり、マスキングポリシーはこの列に設定されています。

次の手順を実行して、データベース mydb を共有し、コンシューマーが共有データベースロールを使用して、共有マスキングポリシーによって保護された共有データをクエリできるようにします。これらの手順は、プロバイダーがアカウントロールとデータベースロールを使用して、 EMAIL 列のマスキングポリシーをテスト済みであることを前提としています。

  1. プロバイダーアカウントで、 CREATE SHARE コマンドを実行し、 mydb.analyst_share データベースロールの共有を作成します。

    USE ROLE r1;
    CREATE SHARE analyst_share;
    
    Copy
  2. 共有に権限を付与します。各共有には同じ権限が必要です。

    USE ROLE r1;
    GRANT USAGE ON DATABASE mydb TO SHARE analyst_share;
    GRANT USAGE ON SCHEMA mydb.policies TO SHARE analyst_share;
    GRANT USAGE ON SCHEMA mydb.tables TO SHARE analyst_share;
    GRANT SELECT ON TABLE mydb.tables.empl_info TO SHARE analyst_share;
    GRANT DATABASE ROLE mydb.analyst TO SHARE analyst_share;
    
    Copy
  3. コンシューマーアカウントを共有に追加します。

    ALTER SHARE analyst_share ADD ACCOUNTS = consumer_account;
    
    Copy
  4. コンシューマーアカウントでアカウントロール r1 を作成し、このロールに共有をインポートする権限を付与します。

    USE ROLE ACCOUNTADMIN;
    CREATE ROLE r1;
    
    GRANT USAGE ON WAREHOUSE my_warehouse TO ROLE r1;
    GRANT CREATE DATABASE ON ACCOUNT TO ROLE r1;
    GRANT IMPORT SHARE ON ACCOUNT TO ROLE r1;
    GRANT ROLE r1 TO ROLE ACCOUNTADMIN;
    
    Copy
  5. 共有をインポートします。

    USE ROLE r1;
    CREATE DATABASE mounted_db FROM SHARE provider_account.analyst_share;
    
    Copy
  6. データベースロールがセッションにあることを確認します。

    USE DATABASE mounted_db;
    USE SCHEMA mounted_db.tables;
    
    SELECT IS_DATABASE_ROLE_IN_SESSION('mounted_db.analyst');
    
    Copy

    SELECT ステートメントは True を返す必要があります。

  7. 保護されたテーブルをクエリします。

    SELECT * FROM empl_info;
    
    Copy

    SELECT ステートメントは、マスクされていないメールアドレスを返すはずです。

  8. データベースロールをアカウントロールに付与して、これらのロールを持つユーザーがマスキングポリシー定義に基づいて保護されたテーブルにクエリを実行し、データを表示できるようにします。

    前の2つのステップを繰り返した後、 mydb.support データベースロールが付与されたユーザーには、部分的にマスクされたメールアドレスが表示されるはずです。

例: 異なるデータベースにおけるマスキングポリシーと保護されたデータ

ポリシーと保護テーブルが異なるデータベースにある場合、両方のデータベースをコンシューマーと共有する必要があります。

例:

  • mydb1 にはマスキングポリシーと mydb1.analyst データベースロールが含まれています。ポリシーとデータベースロールを同じデータベースにグループ化する必要があります。

  • mydb2 には mydb2.tables.empl_info というテーブルがあり、 EMAIL 列が含まれます。マスキングポリシーはこの列に設定されます。

プロバイダーが、共有の作成、共有への権限の付与、共有へのデータベースロールの付与を行う場合は、前の例と同じ手順に従います。

コンシューマーが、共有からデータベースを作成する場合は、前の例と同じ手順に従います。ただし、コンシューマーは、データベースロールをアクティブ化するために、ポリシーを含むデータベースを使用する必要があります。その後、コンシューマーはテーブルの完全修飾名を指定することで、保護されたテーブルをクエリできます。

  1. プロバイダーアカウントで CREATE SHARE コマンドを実行し、各データベースの共有を作成します。

    USE ROLE r1;
    CREATE SHARE analyst_policy_share;
    CREATE SHARE analyst_table_share;
    
    Copy
  2. analyst_policy_share という名前の共有に権限を付与します。

    USE ROLE r1;
    GRANT USAGE ON DATABASE mydb1 TO SHARE analyst_policy_share;
    GRANT USAGE ON SCHEMA mydb1.policies TO SHARE analyst_policy_share;
    GRANT DATABASE ROLE mydb1.analyst TO SHARE analyst_policy_share;
    
    Copy
  3. analyst_table_share という名前の共有に権限を付与します。

    USE ROLE r1;
    GRANT USAGE ON SCHEMA mydb2.tables TO SHARE analyst_table_share;
    GRANT SELECT ON TABLE mydb2.tables.empl_info TO SHARE analyst_table_share;
    
    Copy
  4. コンシューマーアカウントを共有に追加します。

    ALTER SHARE analyst_policy_share ADD ACCOUNTS = consumer_account;
    ALTER SHARE analyst_table_share ADD ACCOUNTS = consumer_account;
    
    Copy
  5. コンシューマーアカウントでアカウントロール r1 を作成し、このロールに共有をインポートする権限を付与します。

    USE ROLE ACCOUNTADMIN;
    CREATE ROLE r1;
    
    GRANT USAGE ON WAREHOUSE my_warehouse TO ROLE r1;
    GRANT CREATE DATABASE ON ACCOUNT TO ROLE r1;
    GRANT IMPORT SHARE ON ACCOUNT TO ROLE r1;
    GRANT ROLE r1 TO ROLE ACCOUNTADMIN;
    
    Copy
  6. 各共有をインポートします。

    USE ROLE r1;
    CREATE DATABASE mounted_db1 FROM SHARE provider_account.analyst_policy_share;
    CREATE DATABASE mounted_db2 FROM SHARE provider_account.analyst_table_share;
    
    Copy
  7. データベースロールがセッションにあることを確認します。

    USE DATABASE mounted_db1;
    USE SCHEMA mounted_db1.policies;
    
    SELECT IS_DATABASE_ROLE_IN_SESSION('mounted_db1.analyst');
    
    Copy

    SELECT ステートメントは True を返す必要があります。

  8. 保護されたテーブルをクエリします。

    SELECT * FROM mounted_db2.tables.empl_info;
    
    Copy

    SELECT ステートメントは、マスクされていないメールアドレスを返すはずです。

例: マッピングテーブルを使用しない行アクセスポリシー

この例では、行アクセスポリシーは IS_DATABASE_ROLE_IN_SESSION 関数を呼び出して AUTHZ_ROLE 列(つまり認可されたロール)のロール名を検索します。非リテラル構文と、関数の検索はポリシーを含むデータベースで行われます。このシナリオでは、マッピングテーブルは行アクセスポリシーと同じデータベースにある必要があります。

ポリシーを作成します。

CREATE OR REPLACE ROW ACCESS POLICY rap_authz_role AS (authz_role string)
RETURNS boolean ->
IS_DATABASE_ROLE_IN_SESSION(authz_role);
Copy

ポリシーをテーブルに追加します。

ALTER TABLE allowed_roles
  ADD ROW ACCESS POLICY rap_authz_role ON (authz_role);
Copy

プロバイダーは、マスキングポリシーの例に示すように、オブジェクトを単一のデータベースで共有するか、複数のデータベースで共有するかを選択できます。コンシューマーは、プロバイダーが提供する各データベースについて、同じ手順に従って共有からデータベースを作成します。

例: マッピングテーブルを使用した行アクセスポリシー

この例では、行アクセスポリシーは IS_DATABASE_ROLE_IN_SESSION 関数を呼び出し、 ROLE_NAME というマッピングテーブル列から認可されたロールを検索します。非リテラル構文と、関数の検索はポリシーを含むデータベースで行われます。このシナリオでは、マッピングテーブルは行アクセスポリシーと同じデータベースにある必要があります。ポリシーを作成したら、 AUTHZ_ROLE 列を含むテーブルにポリシーを追加します。

ポリシーを作成します。

CREATE OR REPLACE ROW ACCESS POLICY rap_authz_role_map AS (authz_role string)
RETURNS boolean ->
EXISTS (
  SELECT 1 FROM mapping_table m
  WHERE authz_role = m.key AND IS_DATABASE_ROLE_IN_SESSION(m.role_name)
);
Copy

ポリシーをテーブルに追加します。

ALTER TABLE allowed_roles
  ADD ROW ACCESS POLICY rap_authz_role_map ON (authz_role);
Copy

プロバイダーは、マスキングポリシーの例に示すように、オブジェクトを単一のデータベースで共有するか、複数のデータベースで共有するかを選択できます。コンシューマーは、プロバイダーが提供する各データベースについて、同じ手順に従って共有からデータベースを作成します。