Utilisation d’objets sécurisés pour contrôler l’accès aux données

Pour s’assurer que les données sensibles dans une base de données partagée ne sont pas exposées dans les comptes de consommateur, Snowflake recommande fortement de partager des vues et/ou des UDFs sécurisés au lieu de partager directement des tables.

De plus, pour des performances optimales, en particulier lors du partage de données dans de très grandes tables, nous recommandons de définir des clés de clustering sur la (les) table(s) de base pour vos objets sécurisés.

Ce chapitre décrit l’utilisation des clés de clustering dans des tables de base pour les objets sécurisés partagés et fournit des instructions étape par étape pour partager une vue sécurisée avec un compte de consommateur. Il fournit des exemples de scripts pour les fournisseurs et les consommateurs de données.

Note

Les instructions pour partager un objet sécurisé sont essentiellement les mêmes que pour partager une table, avec l’ajout des objets suivants :

  • Un schéma « privé » contenant la table de base et un schéma « public » contenant l’objet sécurisé. Seuls le schéma public et l’objet sécurisé sont partagés.

  • Une « table de mappage » (également dans le schéma « privé »), qui n’est nécessaire que si vous souhaitez partager les données de la table de base avec plusieurs comptes de consommateur et partager des lignes spécifiques de la table avec des comptes spécifiques.

Dans ce chapitre :

Utilisation de clés de clustering pour les données partagées

Sur de très grandes tables (c’est-à-dire de plusieurs téraoctets), les clés de clustering offrent des avantages significatifs en termes de performances d’interrogation. En définissant une ou plusieurs clés de clustering sur les tables de base utilisées dans les vues sécurisées partagées ou UDFs, vous vous assurez que les utilisateurs de vos comptes de consommateur ne subissent pas d’impact négatif lorsqu’ils utilisent ces objets.

Lorsque vous choisissez les colonnes à utiliser comme clé de clustering pour une table, veuillez noter quelques considérations importantes.

Exemples de configuration et de tâches

Ces exemples d’instructions supposent qu’une base de données nommée mydb existe dans le compte du fournisseur de données et possède deux schémas : private et public. Si la base de données et les schémas n’existent pas, vous devez les créer avant de continuer.

Étape 1 : Création des données et des tables de mappage dans un schéma privé

Créez les deux tableaux suivants dans le schéma mydb.private et remplissez-les de données :

sensitive_data — contient les données à partager, et une colonne access_id pour contrôler l’accès aux données par compte.
sharing_access — utilise la colonne access_id pour mapper les données partagées et les comptes qui peuvent accéder aux données.

Étape 2 : Création d’une vue sécurisée dans un schéma public

Créez la vue sécurisée suivante dans le schéma mydb.public :

paid_sensitive_data — affiche les données en fonction du compte.

Notez que la colonne access_id de la table de base (sensitive_data) n’a pas besoin d’être incluse dans la vue.

Étape 3 : Validation des tables et vues sécurisées

Validez les tableaux et les vues sécurisées pour vous assurer que les données sont filtrées correctement par compte.

Pour activer la validation des vues sécurisées qui seront partagées avec d’autres comptes, Snowflake fournit un paramètre de session, SIMULATED_DATA_SHARING_CONSUMER. Définissez ce paramètre de session sur le nom du compte de consommateur pour lequel vous souhaitez simuler l’accès. Vous pouvez alors interroger la vue et voir les résultats qu’un utilisateur du compte de consommateur verra.

Note

Pour le moment, le paramètre de session SIMULATED_DATA_SHARING_CONSUMER ne prend en charge que les vues sécurisées et les vues matérialisées sécurisées, mais ne prend pas en charge les UDFs sécurisés.

Étape 4 : Création d’un partage

  1. Créez un partage en utilisant le rôle ACCOUNTADMIN.

  2. Ajoutez des privilèges pour la base de données (mydb), le schéma (public) et la vue sécurisée (paid_sensitive_data) au partage. Notez que ce sont les uniques objets ajoutés au partage, ce qui assure qu’aucun utilisateur des comptes de consommateur ne peut accéder au schéma private ou à l’une des tables du schéma.

  3. Confirmez les contenus du partage. Au niveau le plus basique, nous recommandons d’utiliser la commande SHOW GRANTS pour confirmer que les objets du partage ont les privilèges nécessaires.

    Notez que la vue sécurisée paid_sensitive_data est affichée dans la sortie de commande sous forme de table.

  4. Ajoutez un ou plusieurs comptes au partage.

Exemple de script

Le script suivant illustre l’exécution de toutes les tâches décrites dans la section précédente :

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

Exemple de scénario (pour les consommateurs)

Le script suivant peut être utilisé par les consommateurs pour créer une base de données (à partir du partage créé dans le script ci-dessus) et interroger la vue sécurisée dans la base de données obtenue :

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