Utilisez les politiques d’accès aux lignes¶
Cette rubrique présente une introduction à l’implémentation de politiques d’accès aux lignes.
Dans ce chapitre :
Mettez en œuvre des politiques d’accès aux lignes¶
Les sous-sections suivantes fournissent des exemples sur la façon de mettre en œuvre des politiques d’accès aux lignes :
Utiliser une politique d’accès aux lignes typique avec une recherche dans la table de mappage.
Remplacer les sous-requêtes existantes de la politique d’accès aux lignes par des fonctions mémoïsables pour augmenter les performances des requêtes.
Référencer une table de mappage protégée par une politique d’accès aux lignes dans une autre politique d’accès aux lignes.
Exemple : recherche dans la table de mappage¶
Les étapes suivantes constituent un guide représentatif pour configurer les privilèges de politiques d’accès aux lignes et ajouter des politiques d’accès aux lignes aux tables et aux vues.
Ces étapes reposent sur les hypothèses suivantes :
L’approche de gestion est centralisée.
Si le cas d’utilisation de la politique d’accès aux lignes comprend une approche de gestion hybride ou décentralisée, voir Gérez les politiques d’accès aux lignes pour une distribution représentative des rôles et des privilèges.
Une table de mappage est nécessaire, similaire à la table Cas d’utilisation représentatif : utiliser une table de mappage pour filtrer le résultat de la requête.
Les étapes suivantes utilisent la fonction de contexte CURRENT_ROLE pour déterminer si les utilisateurs voient des lignes dans le résultat d’une requête, tandis que le cas d’utilisation représentatif se concentre sur le prénom de l’utilisateur (c’est-à-dire CURRENT_USER).
Si l’activation et la hiérarchie des rôles sont importantes, Snowflake recommande que les conditions de la politique utilisent la fonction IS_ROLE_IN_SESSION pour les rôles de compte et la fonction IS_DATABASE_ROLE_IN_SESSION pour les rôles de base de données. Pour plus de détails, voir Hiérarchie des rôles actifs et tables de mappage.
Le processus global de mise en œuvre d’une politique d’accès aux lignes avec des tables de mappage reste le même, même si les fonctions contextuelles sont différentes.
Le rôle système SECURITYADMIN accorde des privilèges aux rôles personnalisés pour gérer et mettre en œuvre les politiques d’accès aux lignes.
Si vous ne souhaitez pas utiliser des rôles à privilèges plus élevés (c’est-à-dire SECURITYADMIN ou ACCOUNTADMIN) dans un environnement de production en faveur de rôles personnalisés moins privilégiés (par exemple
database_admin
,finance_admin
), vérifiez que les rôles moins privilégiés disposent des privilèges nécessaires pour gérer et mettre en œuvre les politiques d’accès aux lignes.Pour plus d’informations, voir Privilèges de la politique d’accès aux lignes et Résumé des commandes, des opérations et des privilèges DDL.
Il existe des étapes distinctes pour créer une table à protéger par une politique d’accès aux lignes (étape 1) et pour ajouter la politique d’accès aux lignes à la table (étape 5). Il est possible d’ajouter une politique d’accès aux lignes à la table lors de sa création, en supposant qu’une politique d’accès aux lignes existe déjà. Pour plus d’informations sur la syntaxe, voir CREATE TABLE.
Par exemple :
Créez une table pour les données de ventes :
CREATE TABLE sales ( customer varchar, product varchar, spend decimal(20, 2), sale_date date, region varchar );
Dans le schéma
security
, créez une table de mappage comme indiqué dans l’exemple représentatif. Cette table définit les lignes de la tablesales
que les responsables des ventes peuvent voir :CREATE TABLE security.salesmanagerregions ( sales_manager varchar, region varchar );
Ensuite, un administrateur de sécurité crée le rôle personnalisé
mapping_role
et accorde le privilège SELECT au rôle personnalisé. Cette autorisation permet aux utilisateurs ayant le rôle personnalisé d’interroger la table de mappage :USE ROLE SECURITYADMIN; CREATE ROLE mapping_role; GRANT SELECT ON TABLE security.salesmanagerregions TO ROLE mapping_role;
En utilisant le rôle de propriétaire de schéma, créez une politique d’accès aux lignes avec les deux conditions suivantes :
Les utilisateurs ayant le rôle personnalisé
sales_executive_role
peuvent voir toutes les lignes.Les utilisateurs ayant le rôle personnalisé
sales_manager
peuvent visualiser les lignes basées sur la table de mappagesalesmanagerregions
.
Notez que le rôle de propriétaire de schéma se voit automatiquement accorder le privilège CREATE ROW ACCESS POLICY. Si d’autres rôles doivent pouvoir créer des politiques d’accès aux lignes, le rôle de propriétaire du schéma peut accorder le privilège de politique CREATE ROW ACCESS à d’autres rôles.
USE ROLE schema_owner_role; CREATE OR REPLACE ROW ACCESS POLICY security.sales_policy AS (sales_region varchar) RETURNS BOOLEAN -> 'sales_executive_role' = CURRENT_ROLE() OR EXISTS ( SELECT 1 FROM salesmanagerregions WHERE sales_manager = CURRENT_ROLE() AND region = sales_region ) ;
Où :
security.sales_policy
Le nom de la politique d’accès aux lignes dans le schéma
security
.AS (sales_region varchar)
La signature de la politique d’accès aux lignes.
Une signature spécifie l’attribut de la table de mappage et le type de données. La valeur renvoyée détermine si l’utilisateur a accès à une ligne donnée de la table ou de la vue à laquelle la politique d’accès aux lignes est ajoutée.
'sales_executive_role' = CURRENT_ROLE()
Le début du
body
dans la politique d’accès aux lignes.La première condition de l’expression de la politique d’accès aux lignes qui permet aux utilisateurs ayant le rôle personnalisé
sales_executive_role
de visualiser les données.OR EXISTS (select 1 from salesmanagerregions WHERE sales_manager = CURRENT_ROLE() AND region = sales_region)
La deuxième condition de l’expression de la politique d’accès aux lignes qui utilise une sous-requête.
La sous-requête exige que CURRENT_ROLE soit le rôle personnalisé
sales_manager
et que la requête exécutée sur les données spécifie une région répertoriée dans la table de mappage{salesmanagerregions}
.Astuce
Pour améliorer les performances des requêtes sur la table protégée par des règles, remplacez la sous-requête de recherche dans la table de mappage dans la clause
EXISTS
par une fonction mémoïsable.Pour plus de détails, voir l’exemple de fonction mémoïsable (dans cette rubrique).
En utilisant le rôle système SECURITYADMIN, exécutez les deux instructions suivantes :
GRANT OWNERSHIP ON ROW ACCESS POLICY security.sales_policy TO mapping_role; GRANT APPLY ON ROW ACCESS POLICY security.sales_policy TO ROLE sales_analyst_role;
Ces deux instructions GRANT <privilèges> ont les effets suivants :
La propriété de la politique n’appartient pas au rôle système SECURITYADMIN . Au moment de l’exécution de la requête, Snowflake utilise les privilèges accordés au rôle personnalisé, car les politiques sont exécutées avec les droits du propriétaire, et non avec le rôle système SECURITYADMIN, plus privilégié. Cette approche soutient le principe du moindre privilège.
Le rôle personnalisé
sales_analyst_role
peut ajouter ou détruire la politique d’accès aux lignes d’une table selon les besoins.
Ajoutez (c’est-à-dire liez) la politique d’accès aux lignes à la colonne région dans la table de données
sales
:USE ROLE SECURITYADMIN; ALTER TABLE sales ADD ROW ACCESS POLICY security.sales_policy ON (region);
Accordez le privilège SELECT sur les données
sales
protégées au rôle personnalisésales_manager_role
:GRANT SELECT ON TABLE sales TO ROLE sales_manager_role;
Une fois que les données de vente ont rempli les données
sales
, testez la politique d’accès aux lignes :USE ROLE sales_manager_role; SELECT product, SUM(spend) FROM sales WHERE YEAR(sale_date) = 2020 GROUP BY product;
Exemple : remplacer des sous-requêtes de politique par une fonction mémoïsable¶
Les étapes de cet exemple créent une fonction mémoïsable pour chaque recherche dans table de mappage dans les conditions de la politique d’accès aux lignes. La sous-requête dans chaque clause EXISTS
spécifie la recherche dans la table de mappage, où les tables sont nommées regions
, customers
et products
, respectivement :
CREATE OR REPLACE ROW ACCESS POLICY rap_NO_memoizable_function AS (region_id number, customer_id number, product_id number) RETURNS BOOLEAN -> EXISTS(SELECT 1 FROM regions WHERE id = region_id) OR EXISTS(SELECT 1 FROM customers WHERE id = customer_id) OR EXISTS(SELECT 1 FROM products WHERE id = product_id) ;
Pour les étapes suivantes, supposez que le rôle personnalisé rap_admin
peut créer des politiques d’accès aux lignes (c’est-à-dire qu’il dispose du privilège CREATE ROW ACCESS POLICY sur SCHEMA).
Effectuez les étapes suivantes pour remplacer chacune des recherches de la table de mappage des politiques d’accès aux lignes par une fonction mémoïsable :
Créer un rôle personnalisé nommé
functions_admin
pour gérer la fonction mémoïsable :USE ROLE USERADMIN; CREATE ROLE functions_admin;
Accorder les privilèges suivants au rôle
functions_admin
pour permettre la création de la fonction mémoïsable dans un schéma existant nommégovernance.functions
:USE ROLE SECURITYADMIN; GRANT USAGE ON DATABASE governance TO ROLE functions_admin; GRANT USAGE ON SCHEMA governance.functions TO ROLE functions_admin; GRANT CREATE FUNCTION ON SCHEMA governance.functions TO ROLE functions_admin;
Créez une fonction mémoïsable pour chacune des clauses de sous-requête
EXISTS
dans la politique d’accès aux lignes. Chaque définition de fonction mémoïsable prend la même forme. Par souci de concision, un seul exemple de fonction est présenté :USE ROLE functions_admin; USE SCHEMA governance.functions; CREATE OR REPLACE function allowed_regions() RETURNS array memoizable AS 'SELECT ARRAY_AGG(id) FROM regions';
Utilisez une instruction CREATE ROW ACCESS POLICY pour définir une nouvelle politique d’accès aux lignes qui remplace les sous-requêtes par des fonctions mémoïsables :
La nouvelle politique d’accès aux lignes permet de tester les requêtes sur une table protégée, lorsque la politique utilise ou non les fonctions mémoïsables, afin de quantifier l’impact sur les performances de l’utilisation des fonctions mémoïsables dans les conditions de la politique :
USE ROLE rap_admin; CREATE OR REPLACE ROW ACCESS POLICY rap_with_memoizable_function AS (region_id number, customer_id number, product_id number) RETURNS BOOLEAN -> ARRAY_CONTAINS(region_id, allowed_regions()) OR ARRAY_CONTAINS(customer_id, allowed_customers()) OR ARRAY_CONTAINS(product_id, allowed_products()) ;
Exemple : protéger la table de mappage avec une politique d’accès aux lignes¶
Cet exemple montre comment référencer une table de mappage protégée par une politique d’accès aux lignes dans une autre politique d’accès aux lignes. La politique d’accès aux lignes qui protège la table de mappage fait appel à la fonction contextuelle IS_ROLE_IN_SESSION pour tenir compte de la hiérarchie des rôles. Une autre politique d’accès aux lignes protège la table que l’utilisateur interroge. Cette politique d’accès aux lignes utilise une sous-requête pour effectuer une recherche dans la table de mappage. Par exemple :
Créez une table de mappage pour définir les rôles autorisés en fonction des régions géographiques de vente et insérez des données dans la table :
CREATE OR REPLACE TABLE sales.tables.regional_managers ( allowed_regions varchar allowed_roles varchar );
INSERT INTO sales.tables.regional_managers (allowed_regions, allowed_roles) VALUES ('na', 'NA_MANAGER'), ('eu', 'EU_MANAGER'), ('apac', 'APAC_MANAGER');
Créez une politique d’accès aux lignes pour spécifier la colonne ALLOWED_ROLES dans la table de mappage :
CREATE OR REPLACE ROW ACCESS POLICY governance.policies.rap_map_exempt AS (allowed_roles varchar) RETURNS BOOLEAN -> IS_ROLE_IN_SESSION(allowed_roles);
Ajoutez la politique d’accès aux lignes sur la table de mappage à l’aide d’une instruction ALTER TABLE :
ALTER TABLE sales.tables.regional_managers ADD ROW ACCESS POLICY governance.policies.rap_map_exempt ON (allowed_roles);
Créez une nouvelle politique d’accès aux lignes qui spécifie la consultation de la table de mappage sur la table de mappage protégée :
CREATE OR REPLACE ROW ACCESS POLICY governance.policies.rap_map_lookup AS (allowed_regions varchar) RETURNS BOOLEAN -> EXISTS ( SELECT * FROM sales.tables.regional_managers WHERE REGION = allowed_regions );
Ajoutez la politique d’accès aux lignes nommée
governance.policies.rap_map_lookup
sur la table nomméesales.tables.data
à l’aide d’une instruction ALTER TABLE :ALTER TABLE sales.tables.data ADD ROW ACCESS POLICY governance.policies.rap_map_lookup ON (allowed_regions);
Accordez des privilèges aux rôles dans la table de mappage pour permettre aux utilisateurs ayant ces rôles d’interroger les données protégées. Par exemple, ces accords concernent le rôle personnalisé
na_manager
:USE ROLE SECURITYADMIN; GRANT USAGE ON DATABASE sales TO ROLE na_manager; GRANT USAGE ON SCHEMA sales.tables TO ROLE na_manager; GRANT SELECT ON TABLE sales.tables.regional_managers TO ROLE na_manager; GRANT SELECT ON TABLE sales.tables.data TO ROLE na_manager;
Si nécessaire, répétez les commandes de cette étape pour chaque rôle de la table de mappage.