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

共有データベースの機密データがコンシューマーアカウントのユーザーに公開されないように、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 を提供します。このセッションパラメーターを、アクセスをシミュレートするコンシューマアカウントの名前に設定します。その後、ビューにクエリを実行して、コンシューマアカウントのユーザーに表示される結果を確認できます。

注釈

現時点では、 SIMULATED_DATA_SHARING_CONSUMER セッションパラメーターは、セキュアビューとセキュアマテリアライズドビューのみをサポートしており、セキュア UDFsはサポートしていません。

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

  1. ACCOUNTADMIN ロールを使用して share を作成します。

  2. データベース(mydb)、スキーマ(public)、およびセキュアビュー(paid_sensitive_data)の権限を共有に追加します。これらは共有に追加される 唯一 のオブジェクトであり、コンシューマアカウントのユーザーが private スキーマまたはスキーマ内のテーブルにアクセスできないようにします。

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

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

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

サンプルスクリプト

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

/* Create two tables in the 'private' schema and populate the first one with stock data from three   */
/* different companies (Apple, Microsoft, and IBM). You will then populate the second one with       */
/* data that maps the stock data to individual accounts.                                             */

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 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>');


/* Create a secure view in the 'public' schema. This view filters the stock data from the first      */
/* table by account, using the mapping information in the second table.                              */

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;


/* Create a share using the ACCOUNTADMIN role. */

use role accountadmin;

create or replace share mydb_shared
  comment = 'Example of using Secure Data Sharing with secure views';

show shares;


/*  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;


/* Add accounts to the share.                                    */
/*                                                               */
/* 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>;

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

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

/* Bring the shared database into your account by creating a database from the share. */
/*                                                                                    */
/* 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;


/* Grant privileges on the database to other roles (e.g. SYSADMIN) in your account. */

grant imported privileges on database mydb_shared1 to sysadmin;


/* Now you can use the SYSADMIN role to query the view in the database you created.       */
/*                                                                                        */
/* Note that there must be a warehouse in use in the session to perform queries. In the   */
/* USE WAREHOUSE command, replace <warehouse_name> with the name of one of the warehouses */
/* in your account.                                                                       */

use role sysadmin;

show views;

use warehouse <warehouse_name>;

select * from paid_sensitive_data;