セキュアオブジェクトを使用したデータアクセスの制御

共有データベースの機密データがコンシューマーアカウントのユーザーに公開されないように、Snowflakeは、テーブルを直接共有するのではなく、 セキュアビュー および/または セキュア UDFs を共有することを 強く お勧めします。

さらに、特に非常に大きなテーブルでデータを共有する場合に最適なパフォーマンスを得るために、安全なオブジェクトのベーステーブルで clustering keys を定義することをお勧めします。

このトピックでは、共有セキュアオブジェクトのためのベーステーブルにおけるクラスタリングキーの使用について説明し、セキュアビューをコンシューマーアカウントと共有するための詳細な手順を提供します。データプロバイダーとコンシューマーの両方にサンプルスクリプトを提供します。

注釈

セキュアオブジェクトを共有するための手順は、テーブルを共有する場合と基本的に同じですが、次のオブジェクトが追加されています。

  • ベーステーブルを含む「プライベート」スキーマと、セキュアオブジェクトを含む「パブリック」スキーマ。パブリックスキーマとセキュアオブジェクトのみが共有されます。

  • 「マッピングテーブル」(「プライベート」スキーマにおいても)は、ベーステーブルのデータを複数のコンシューマアカウントと共有し、テーブル内の特定の行を特定のアカウントと共有する場合にのみ必要です。

このトピックの内容:

共有データでのクラスタリングキーの使用

非常に大きな(つまり、数テラバイト)テーブルでは、クラスタリングキーによりクエリのパフォーマンスが大幅に向上します。共有セキュアビューまたは UDFs で使用されるベーステーブルで1つ以上のクラスタリングキーを定義して、これらのオブジェクトを使用する際にコンシューマーカウントのユーザーが悪影響を受けないようにします。

テーブルのクラスタリングキーとして使用する列を選択するときは、 重要な考慮事項 に注意してください。

サンプルの設定とタスク

これらのサンプル手順では、 mydb という名前のデータベースがデータプロバイダーアカウントに存在し、 privatepublic の2つのスキーマを持っていることを前提としています。データベースとスキーマが存在しない場合は、先に進む前にそれらを作成する必要があります。

ステップ1: プライベートスキーマでデータとマッピングテーブルを作成する

mydb.private スキーマに次の2つのテーブルを作成し、それらにデータを入力します。

sensitive_data --- 共有するデータと、アカウントによるデータアクセスを制御するための access_id 列が含まれています。
sharing_access --- access_id 列を使用して、共有データとデータにアクセスできるアカウントをマップします。

ステップ2: パブリックスキーマにセキュアビューを作成する

mydb.public スキーマに次のセキュアビューを作成します。

paid_sensitive_data --- アカウントに基づいてデータを表示します。

ベーステーブル(sensitive_data)の access_id 列をビューに含める必要はありません。

ステップ3: テーブルとセキュアビューを検証する

テーブルとセキュアビューを検証して、アカウントによってデータが適切にフィルターされることを確認します。

他のアカウントと共有されるセキュアビューの検証を有効にするために、Snowflakeはセッションパラメーター SIMULATED_DATA_SHARING_CONSUMER を提供します。このセッションパラメーターを、アクセスをシミュレートするコンシューマアカウントの名前に設定します。その後、ビューをクエリして、コンシューマーアカウントのユーザーに表示される結果を確認できます。

ステップ4: 共有を作成する

  1. 共有 を作成します。

    共有を作成するには、 ACCOUNTADMIN ロールまたはグローバル CREATE SHARE 権限が付与されたロールを使用する必要があります。また、共有にオブジェクトを付与するには、ロールが次のいずれかを持っている必要があります。

  2. データベース(mydb)、スキーマ(public)、およびセキュアビュー(paid_sensitive_data)を共有に追加します。これらのオブジェクトに対する権限をデータベースロール経由で共有に追加するか、オブジェクトに対する権限を共有に直接付与するかの いずれか を選択できます。これらのオプションの詳細については、 データベースオブジェクトの共有方法の選択 をご参照ください。

  3. 共有の内容を確認します。最も基本的なレベルでは、 SHOW GRANTS コマンドを使用して、共有内のオブジェクトに必要な権限があることを確認する必要があります。

    セキュアビュー paid_sensitive_data は、コマンド出力にテーブルとして表示されます。

  4. 1つ以上のアカウントを共有に追加します。

サンプルスクリプト

次のスクリプトは、前のセクションで説明したすべてのタスクの実行を示しています。

  1. 「プライベート」スキーマに2つのテーブルを作成し、最初のテーブルに3つの異なる企業(Apple、Microsoft、および IBM)の株式データを入力します。そして、2番目のテーブルに株式データを個々のアカウントにマップするデータを入力します。

    use role sysadmin;
    
    create or replace table mydb.private.sensitive_data (
        name string,
        date date,
        time time(9),
        bid_price float,
        ask_price float,
        bid_size int,
        ask_size int,
        access_id string /* granularity for access */ )
        cluster by (date);
    
    insert into mydb.private.sensitive_data
        values('AAPL',dateadd(day,  -1,current_date()), '10:00:00', 116.5, 116.6, 10, 10, 'STOCK_GROUP_1'),
              ('AAPL',dateadd(month,-2,current_date()), '10:00:00', 116.5, 116.6, 10, 10, 'STOCK_GROUP_1'),
              ('MSFT',dateadd(day,  -1,current_date()), '10:00:00',  58.0,  58.9, 20, 25, 'STOCK_GROUP_1'),
              ('MSFT',dateadd(month,-2,current_date()), '10:00:00',  58.0,  58.9, 20, 25, 'STOCK_GROUP_1'),
              ('IBM', dateadd(day,  -1,current_date()), '11:00:00', 175.2, 175.4, 30, 15, 'STOCK_GROUP_2'),
              ('IBM', dateadd(month,-2,current_date()), '11:00:00', 175.2, 175.4, 30, 15, 'STOCK_GROUP_2');
    
    create or replace table mydb.private.sharing_access (
      access_id string,
      snowflake_account string
    );
    
    
    /* In the first insert, CURRENT_ACCOUNT() gives your account access to the AAPL and MSFT data.       */
    
    insert into mydb.private.sharing_access values('STOCK_GROUP_1', CURRENT_ACCOUNT());
    
    
    /* In the second insert, replace <consumer_account> with an account name; this account will have     */
    /* access to IBM data only. Note that account names are case-sensitive and must be in uppercase      */
    /* enclosed in single-quotes, e.g.                                                                   */
    /*                                                                                                   */
    /*      insert into mydb.private.sharing_access values('STOCK_GROUP_2', 'ACCT1')                */
    /*                                                                                                   */
    /* To share the IBM data with multiple accounts, repeat the second insert for each account.          */
    
    insert into mydb.private.sharing_access values('STOCK_GROUP_2', '<consumer_account>');
    
    Copy
  2. 「公開」スキーマにセキュアビューを作成します。このビューは、2番目のテーブルのマッピング情報を使用して、最初のテーブルの株式データをアカウント別にフィルター処理します。

    create or replace secure view mydb.public.paid_sensitive_data as
        select name, date, time, bid_price, ask_price, bid_size, ask_size
        from mydb.private.sensitive_data sd
        join mydb.private.sharing_access sa on sd.access_id = sa.access_id
        and sa.snowflake_account = current_account();
    
    grant select on mydb.public.paid_sensitive_data to public;
    
    
    /* Test the table and secure view by first querying the data as the provider account. */
    
    select count(*) from mydb.private.sensitive_data;
    
    select * from mydb.private.sensitive_data;
    
    select count(*) from mydb.public.paid_sensitive_data;
    
    select * from mydb.public.paid_sensitive_data;
    
    select * from mydb.public.paid_sensitive_data where name = 'AAPL';
    
    
    /* Next, test the secure view by querying the data as a simulated consumer account. You specify the  */
    /* account to simulate using the SIMULATED_DATA_SHARING_CONSUMER session parameter.                  */
    /*                                                                                                   */
    /* In the ALTER command, replace <consumer_account> with one of the accounts you specified in the    */
    /* mapping table. Note that the account name is not case-sensitive and does not need to be enclosed  */
    /* in single-quotes, e.g.                                                                            */
    /*                                                                                                   */
    /*      alter session set simulated_data_sharing_consumer=acct1;                                     */
    
    alter session set simulated_data_sharing_consumer=<account_name>;
    
    select * from mydb.public.paid_sensitive_data;
    
    Copy
  3. ACCOUNTADMIN ロールを使用して共有を作成します。

    use role accountadmin;
    
    create or replace share mydb_shared
      comment = 'Example of using Secure Data Sharing with secure views';
    
    show shares;
    
    Copy
  4. オブジェクトを共有に追加します。これらのオブジェクトに対する権限をデータベースロール経由で共有に追加する(オプション1)か、オブジェクトに対する権限を共有に直接付与する(オプション2)かの いずれか を選択できます。

    /* Option 1: Create a database role, grant privileges on the objects to the database role, and then grant the database role to the share */
    
    create database role mydb.dr1;
    
    grant usage on database mydb to database role mydb.dr1;
    
    grant usage on schema mydb.public to database role mydb.dr1;
    
    grant select on mydb.public.paid_sensitive_data to database role mydb.dr1;
    
    grant database role mydb.dr1 to share mydb_shared;
    
    
    /* Option 2: Grant privileges on the database objects to include in the share.  */
    
    grant usage on database mydb to share mydb_shared;
    
    grant usage on schema mydb.public to share mydb_shared;
    
    grant select on mydb.public.paid_sensitive_data to share mydb_shared;
    
    
    /*  Confirm the contents of the share. */
    
    show grants to share mydb_shared;
    
    Copy
  5. アカウントを共有に追加します。

    /* In the alter statement, replace <consumer_accounts> with the  */
    /* consumer account(s) you assigned to STOCK_GROUP2 earlier,     */
    /* with each account name separated by commas, e.g.              */
    /*                                                               */
    /*    alter share mydb_shared set accounts = acct1, acct2;       */
    
    alter share mydb_shared set accounts = <consumer_accounts>;
    
    Copy

サンプルスクリプト(コンシューマー用)

コンシューマーは次のスクリプトを使用してデータベースを作成し(上記のスクリプトで作成した共有から)、結果のデータベースのセキュアビューをクエリできます。

  1. 共有からデータベースを作成して、共有データベースをアカウントに取り込みます。

    /* In the following commands, the share name must be fully qualified by replacing     */
    /* <provider_account> with the name of the account that provided the share, e.g.      */
    /*                                                                                    */
    /*    desc prvdr1.mydb_shared;                                                        */
    
    use role accountadmin;
    
    show shares;
    
    desc share <provider_account>.mydb_shared;
    
    create database mydb_shared1 from share <provider_account>.mydb_shared;
    
    Copy
  2. データベースに対する権限をアカウント内の他のロールに付与します(例: CUSTOM_ROLE 1)。GRANT ステートメントは、データコンシューマーがデータベースロールを使用してオブジェクトを共有に追加した(オプション1)か、オブジェクトに対する権限を直接共有に付与した(オプション 2)かによって異なります。

    /* Option 1 */
    grant database role mydb_shared1.db1 to role custom_role1;
    
    /* Option 2 */
    grant imported privileges on database mydb_shared1 to custom_role1;
    
    Copy
  3. CUSTOM_ROLE 1ロールを使用して、作成したデータベースのビューをクエリします。クエリを実行するには、セッションで使用中のアクティブなウェアハウスが必要であることに注意してください。USE WAREHOUSE コマンドで、 <ウェアハウス名> をアカウント内のいずれかのウェアハウス名に置き換えます。CUSTOM_ROLE 1ロールには、ウェアハウスに対する USAGE 権限が必要です:

    use role custom_role1;
    
    show views;
    
    use warehouse <warehouse_name>;
    
    select * from paid_sensitive_data;
    
    Copy