ポリシーで保護されたデータを共有する¶
データ共有コンシューマーは共有データベースロールを使用して、マスキングポリシーまたは行アクセスポリシーで保護された共有データにアクセスできます。
概要¶
データ共有プロバイダーは、データ共有コンシューマーがポリシーで保護されたデータにアクセスできるように、データベースロールを共有できます。プロバイダーは、 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は 保護されたオブジェクト を含むデータベースを検索します。これらのオブジェクトが共有されておらず、定義されているデータベースロールが別のデータベースで定義されている場合、この関数は - Falseと評価されます。
 
- IS_DATABASE_ROLE_IN_SESSION 関数の 引数に列名 を指定した場合: - テーブルクエリがこの関数を呼び出す場合、列はその列を含むテーブルのテーブル識別子にマップされます。次にSnowflakeは、テーブルを含むデータベースのデータベースロールを調べます。たとえば、 AUTHZ_ROLE 列(つまり認可されたロール)を引数として指定します。 - SELECT * FROM mydb.myschema.t WHERE IS_DATABASE_ROLE_IN_SESSION(AUTHZ_ROLE); Copy
- マスキングポリシー、行アクセスポリシー、または UDF が関数を呼び出すと、保護されたテーブルを含むデータベースで検索が行われます。 
 
一般的なワークフロー¶
ポリシーで保護されたデータをポリシー内の IS_DATABASE_ROLE_IN_SESSION 関数と共有するには、関数を呼び出してデータを共有するポリシーを作成するのと同じ手順が必要です。まとめ:
- プロバイダーはアカウントロールを作成します。 
- プロバイダーはポリシーを作成し、テーブルまたは列にポリシーを設定します。 
- プロバイダーは、アカウントロールでポリシーをテストします。 
- プロバイダーはデータベースロールを作成し、そのデータベースロールを使用してポリシーをテストします。 
- プロバイダーは共有を作成し、共有にデータベースロールの付与を含む権限を付与します。 
- コンシューマーは共有からデータベースを作成します(マウントされたデータベース)。 
- コンシューマーは、ポリシーによって保護されている共有オブジェクトをクエリします。 
例: 同じデータベース内にあるすべてのオブジェクト¶
この例では、データベースロール、マスキングポリシー、保護されたテーブルはすべて、 mydb という同じデータベース内にあります。
参照情報:
- データベースロールは - analyst_dbroleと- support_dbroleです。
- マスキングポリシーは次のように定義されています。 - CREATE OR REPLACE MASKING POLICY mydb.policies.email_mask AS (val string) RETURNS string -> CASE WHEN IS_DATABASE_ROLE_IN_SESSION('ANALYST_DBROLE') THEN val WHEN IS_DATABASE_ROLE_IN_SESSION('SUPPORT_DBROLE') THEN REGEXP_REPLACE(val,'.+\@','*****@') ELSE '********' END COMMENT = 'use database role for shared data' ; Copy
- EMAIL 列は、 - mydb.tables.empl_infoという名前のテーブルにあり、マスキングポリシーはこの列に設定されています。
次の手順を実行して、データベース mydb を共有し、コンシューマーが共有データベースロールを使用して、共有マスキングポリシーによって保護された共有データをクエリできるようにします。これらの手順は、プロバイダーがアカウントロールとデータベースロールを使用して、 EMAIL 列のマスキングポリシーをテスト済みであることを前提としています。
- プロバイダーアカウントで、 CREATE SHARE コマンドを実行し、アナリストデータベースロールの共有を作成します。 - USE ROLE r1; CREATE SHARE analyst_share; Copy
- 共有に権限を付与します。各共有には同じ権限が必要です。 - USE ROLE r1; GRANT USAGE ON DATABASE mydb 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 analyst_dbrole TO SHARE analyst_share; Copy
- コンシューマーアカウントを共有に追加します。 - ALTER SHARE analyst_share ADD ACCOUNTS = consumer_account; Copy
- コンシューマーアカウントでアカウントロール - 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
- 共有をインポートします。 - USE ROLE r1; CREATE DATABASE mounted_db FROM SHARE provider_account.analyst_share; Copy
- データベースロールがセッションにあることを確認します。 - USE DATABASE mounted_db; USE SCHEMA mounted_db.tables; SELECT IS_DATABASE_ROLE_IN_SESSION('ANALYST_DBROLE'); Copy- SELECT ステートメントは - Trueを返す必要があります。
- 保護されたテーブルをクエリします。 - SELECT * FROM empl_info; Copy- SELECT ステートメントは、マスクされていないメールアドレスを返すはずです。 
- データベースロールをアカウントロールに付与して、これらのロールを持つユーザーがマスキングポリシー定義に基づいて保護されたテーブルにクエリを実行し、データを表示できるようにします。 - 前の2つのステップを繰り返した後、 - support_dbroleデータベースロールが付与されたユーザーには、部分的にマスクされたメールアドレスが表示されるはずです。
例: 異なるデータベースにおけるマスキングポリシーと保護されたデータ¶
ポリシーと保護テーブルが異なるデータベースにある場合、保護テーブルを含むデータベースをコンシューマーと共有します。
例:
- mydb1にはマスキングポリシーが含まれています。
- mydb2には- mydb2.tables.empl_infoというテーブルがあり、 EMAIL 列が含まれます。マスキングポリシーはこの列に設定されます。- テーブルとデータベースロール( - analyst_dbrole)は同じデータベースでグループ化する必要があります。
プロバイダーが、共有の作成、共有への権限の付与、共有へのデータベースロールの付与を行う場合は、前の例と同じ手順に従います。
コンシューマーが、共有からデータベースを作成する場合は、前の例と同じ手順に従います。ただし、コンシューマーは、データベースロールをアクティブ化するために、保護されたテーブルを含むデータベースを使用する必要があります。その後、コンシューマーはテーブルの完全修飾名を指定することで、保護されたテーブルをクエリできます。
- プロバイダーアカウントで CREATE SHARE コマンドを実行し、各データベースの共有を作成します。 - USE ROLE r1; CREATE SHARE analyst_policy_share; CREATE SHARE analyst_table_share; Copy
- 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; GRANT DATABASE ROLE mydb2.analyst_dbrole TO SHARE analyst_table_share; Copy
- コンシューマーアカウントを共有に追加します。 - ALTER SHARE analyst_table_share ADD ACCOUNTS = consumer_account; Copy
- コンシューマーアカウントでアカウントロール - 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
- 保護されたテーブルとデータベースロールを含む共有をインポートします: - USE ROLE r1; CREATE DATABASE mounted_db2 FROM SHARE provider_account.analyst_table_share; Copy
- データベースロールがセッションにあることを確認します。 - USE DATABASE mounted_db2; USE SCHEMA mounted_db2.tables; SELECT IS_DATABASE_ROLE_IN_SESSION('ANALYST_DBROLE'); Copy- SELECT ステートメントは - Trueを返す必要があります。
- 保護されたテーブルをクエリします。 - 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
プロバイダーは、マスキングポリシーの例に示すように、オブジェクトを単一のデータベースで共有するか、複数のデータベースで共有するかを選択できます。コンシューマーは、プロバイダーが提供する各データベースについて、同じ手順に従って共有からデータベースを作成します。