SELECTSELECT

SELECT

Nos 7 meilleures pratiques RBAC pour Snowflake

By Miguel DuarteAug 3, 202415 min read

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

Dans notre précédent article sur Snowflake, nous proposions un guide complet sur le fonctionnement des rôles et privilèges Snowflake, et sur la façon dont le contrôle d'accès basé sur les rôles permet de bâtir une hiérarchie simple et évolutive.

Dans cet article, nous poursuivons notre exploration du contrôle d'accès en partageant quelques conseils et bonnes pratiques pour mettre en place et gérer vos accès, le tout illustré par un exemple concret.

Les enseignements présentés ici reposent sur notre expérience de terrain chez Tasman Analytics, où nous avons conçu et déployé des hiérarchies RBAC dans Snowflake pour plus de 20 clients.

Conseil 1. Commencez par le principe du moindre privilège

Lors de la conception de votre modèle d'accès et de l'attribution des permissions aux différents utilisateurs de votre entreprise, visez une structure dans laquelle chaque utilisateur dispose exactement des permissions dont il a besoin (ni plus, ni moins) pour faire son travail. Pourquoi le nouveau Junior Finance Analyst aurait-il la permission de supprimer des tables alors qu'il a uniquement besoin d'interroger un bilan comptable ?

C'est ce que l'on appelle le principe du moindre privilège. Appliqué à votre modèle d'accès Snowflake, il présente de nombreux avantages :

  • Il réduit le risque et l'impact des menaces externes : limiter l'accès des utilisateurs au strict nécessaire diminue le risque de fuites de données, qu'elles soient accidentelles ou malveillantes. Et si une violation survient, les dégâts se limitent aux zones de la base accessibles par le ou les comptes compromis.
  • Il minimise le risque de corruption du système et renforce sa stabilité : restreindre les accès aide à prévenir les modifications susceptibles d'affecter l'intégrité ou la stabilité des données ; les membres d'équipe à exposition limitée ne devraient pas pouvoir supprimer de bases de données ! :)
  • Il facilite l'audit et la supervision : moins de privilèges en place, c'est aussi moins de privilèges à surveiller et à maintenir.
  • Il simplifie la conformité : ce principe facilite le respect des exigences réglementaires en matière de protection des données — lorsqu'elles s'appliquent —, comme le RGPD ou HIPAA, en limitant l'accès aux données sensibles au strict nécessaire.

Le principe du moindre privilège est un excellent point de départ : il offre un bon compromis entre sécurité et facilité de maintenance. Certaines entreprises préféreront un modèle de sécurité plus souple, au prix de risques accrus, tandis que d'autres opteront pour des pratiques plus strictes. Renseignez-vous également sur le modèle de sécurité Zero-Trust et sur la manière dont le principe du moindre privilège s'y articule.

Conseil 2. Rôles d'accès, fonctionnels et de service

Dans notre dernier article, nous avons évoqué différents types de rôles : rôles de compte, rôles de base de données et même rôles d'instance. Ils présentent des différences fondamentales et techniques. Pour rester simple, nous nous concentrerons ici sur les rôles de compte.

Explorons maintenant une autre approche pour définir les rôles : en fonction de leur intention. Voici les 3 types de rôles que nous souhaitons présenter :

  • Les rôles d'accès servent à contrôler l'accès à vos bases de données ;
  • Les rôles fonctionnels sont attribués aux utilisateurs Snowflake de votre entreprise, et les niveaux d'accès sont contrôlés en leur octroyant les rôles d'accès requis (selon le principe du moindre privilège) ;
  • Les rôles de service fonctionnent exactement comme les rôles fonctionnels, à ceci près qu'ils sont destinés à des services et non à des utilisateurs finaux (humains).

Notez qu'il n'existe aucune différence technique entre rôles d'accès, fonctionnels et de service. Tous sont créés comme des rôles de compte.

Rôles d'accès

Les rôles d'accès sont créés pour garantir différents niveaux d'accès aux bases de données et à leurs objets. Voyez-les comme les briques de base de votre hiérarchie.

Une façon simple de créer des rôles d'accès consiste à utiliser des rôles READ et READWRITE pour chaque base de données existante :

  • READ : accorde les privilèges SELECT sur toutes les tables et vues de la base.
  • READWRITE : accorde les opérations SELECT, INSERT, UPDATE et DELETE.

C'est un bon point de départ, mais selon les besoins de votre entreprise, vous pouvez créer des rôles d'accès plus fins (par exemple pour accéder à des schémas spécifiques d'une base).

Rôles fonctionnels

Les rôles fonctionnels sont conçus pour s'aligner sur les fonctions métier et combinent plusieurs rôles d'accès. Par exemple, un rôle DATA_ANALYST pourrait hériter des privilèges des rôles d'accès READ* *créés pour certaines bases. À l'inverse, un rôle DATA_ENGINEER pourrait hériter des rôles READWRITE pour ces mêmes bases.

Ce sont ces rôles qui seront attribués aux utilisateurs finaux. Vous pouvez les construire selon les besoins réels, en utilisant les rôles d'accès comme briques de base (et en gardant toujours à l'esprit le principe du moindre privilège).

Rôles de service

Ce type de rôle est essentiellement identique à un rôle fonctionnel, à la différence qu'il est attribué à des comptes de service et non aux utilisateurs de votre entreprise. Ils peuvent être utilisés par des outils tiers, comme des plateformes BI et de dashboard, ou tout autre SaaS nécessitant un accès READ ou READWRITE aux objets d'une base Snowflake (Airbyte, Rudderstack, Mode, etc.).

À l'instar des rôles fonctionnels, vous pouvez construire les rôles de service selon les besoins réels, en utilisant les rôles d'accès comme briques de base et en respectant toujours le principe du moindre privilège.

Avec ces 3 types de rôles, vous disposez de toutes les briques nécessaires pour bâtir une hiérarchie d'accès simple et efficace.

Conseil 3. Créez une hiérarchie de rôles DRY

L'un des principes clés du développement logiciel consiste à éviter la répétition de code, résumé par l'acronyme D.R.Y. (Don't Repeat Yourself). Avec les rôles d'accès, fonctionnels et de service, vous pouvez commencer à esquisser votre hiérarchie. Voici 4 étapes pour itérer.

1. Définissez les rôles fonctionnels et de service nécessaires dans votre entreprise

Recueillez les besoins des différents utilisateurs Snowflake de votre entreprise et dressez la liste des rôles fonctionnels à mettre en place, avec les niveaux d'accès requis. Cette liste vous permettra ensuite d'esquisser les rôles d'accès nécessaires.

2. Créez les rôles d'accès

Une fois votre liste de besoins finalisée, vous pourrez visualiser les rôles d'accès nécessaires. Créez ensuite ces rôles et accordez les privilèges appropriés sur les objets de base de données correspondants (par exemple FINANCE_DB_READ_ROLE).

3. Créez les rôles fonctionnels et de service (et attribuez-leur les rôles d'accès)

Avec les rôles d'accès en place, vous disposez de tout ce qu'il faut pour bâtir les rôles fonctionnels destinés à vos collaborateurs, ainsi que les rôles de service destinés aux services. Pour répondre aux besoins initialement définis, attribuez les rôles d'accès aux rôles fonctionnels ou de service que vous venez de créer (par exemple DATA_ANALYST).

4. Attribuez les rôles fonctionnels aux utilisateurs et les rôles de service aux comptes de service

Votre hiérarchie de rôles est désormais complète ! La dernière étape consiste à attribuer les rôles fonctionnels aux utilisateurs Snowflake et les rôles de service aux comptes de service. En cas d'ajustement, il suffit de reprendre les étapes 1 à 4.

À éviter…

N'attribuez pas de rôles d'accès directement aux utilisateurs finaux ni aux comptes de service

Si vous sautez la couche des rôles fonctionnels et attribuez directement un ensemble de rôles d'accès à un utilisateur, vous devrez recommencer chaque fois qu'un nouvel utilisateur aux responsabilités similaires rejoindra l'équipe. De plus, à chaque ajustement nécessaire, il vous faudra le faire manuellement pour plusieurs utilisateurs.

Un rôle fonctionnel, c'est au contraire un unique point d'ajustement. Les modifications s'appliqueront alors à tous les utilisateurs auxquels ce rôle fonctionnel a été attribué. La couche des rôles d'accès existe pour standardiser l'accès aux objets de base de données dans tout votre compte ; elle n'est pas faite pour être utilisée directement !

N'attribuez pas de rôles fonctionnels à d'autres rôles fonctionnels

Restez simple ! Chaque rôle fonctionnel doit être une composition de rôles d'accès. Introduire des dépendances peut compliquer les choses, surtout à mesure que votre entreprise grandit et que les postes évoluent.

Conseil 4. Tirez parti des Future Grants lors de la création de vos rôles d'accès

Vous avez créé des rôles d'accès pour une base de données, mais de nouveaux schémas et tables sont régulièrement ajoutés, vous obligeant à mettre constamment à jour les privilèges ? Ce conseil est fait pour vous ! Vous pouvez accorder des privilèges sur les futurs schémas d'une base, ainsi que sur les futures tables, vues ou autres objets. Ainsi, dès qu'un nouvel objet est créé, le grant est automatiquement appliqué.

Utiliser les future grants lors de la création des rôles d'accès permet de réduire les tâches de maintenance et de garantir que vos rôles disposent des bons privilèges à mesure que de nouveaux objets apparaissent. Plus besoin d'exécuter de nouvelles instructions grant à chaque ajout d'objet !

Conseil 5. Accordez les rôles fonctionnels à SYSADMIN

Lorsqu'un rôle personnalisé est créé pour la première fois, il existe de manière isolée, et il en va de même pour tous les objets créés par ce rôle. Par défaut, même le rôle ACCOUNTADMIN ne peut ni modifier ni supprimer les objets créés par un rôle personnalisé. Ainsi, quand un rôle n'a pas de parent, vous risquez de créer dans votre compte des objets qui ne seront accessibles que par lui.

En accordant un rôle personnalisé à SYSADMIN, vous garantissez qu'au minimum les rôles SYSADMIN (et ACCOUNTADMIN) pourront gérer les objets créés par ce rôle.

En conclusion, prenez l'habitude d'accorder vos rôles fonctionnels à SYSADMIN par défaut.

Conseil 6. Appuyez-vous sur l'interface Snowflake

Snowsight propose une excellente fonctionnalité permettant d'afficher la hiérarchie des rôles existants dans le compte Snowflake. Utilisez-la pour visualiser les rôles que vous créez et la façon dont ils s'articulent.

Cherchez l'option Graph dans Users & Roles. Vous pouvez ensuite utiliser l'option Focus pour observer un rôle précis ainsi que ses rôles parents et enfants.

Exemple d'interface Snowsight affichant le graphe des rôles pour ENGINEER_ROLE

Conseil 7. Vous n'avez probablement pas besoin d'ACCOUNTADMIN pour ça…

Autrement dit, utilisez les rôles adaptés à chaque opération administrative que vous effectuez. N'oubliez pas le principe du moindre privilège !

Le rôle ACCOUNTADMIN dispose par défaut de bien plus de privilèges qu'il n'en faut pour vos opérations quotidiennes : évitez de l'utiliser sans raison valable. Voici les rôles à privilégier pour les opérations courantes :

  • Pour créer des utilisateurs ou des rôles, utilisez USERADMIN !
  • Pour gérer les grants (par exemple attribuer un rôle à un utilisateur), utilisez SECURITYADMIN !
  • Pour créer des objets tels que des bases de données, des schémas ou des virtual warehouses, utilisez SYSADMIN !
  • Pour créer des bases de données ou des objets de base comme des tables, des vues ou tout autre objet, vous pouvez utiliser SYSADMIN !
  • Pour effectuer des opérations ad hoc sur les données d'une table (comme un SELECT ou un INSERT), utilisez un rôle fonctionnel approprié !
  • Enfin, si vous souhaitez connecter un service tiers à Snowflake, n'utilisez surtout pas ACCOUNTADMIN ! Créez et utilisez plutôt un rôle de service dédié :)

Par exemple, le package SELECT dbt-snowflake-monitoring requiert un privilège spécial IMPORTED PRIVILEGES sur la base SNOWFLAKE, qui ne peut être accordé que par le rôle ACCOUNTADMIN. Dans ce cas, utilisez USERADMIN pour créer un rôle d'accès dédié à ce seul privilège, accordez le privilège via ACCOUNTADMIN, puis utilisez SECURITYADMIN pour attribuer ce rôle d'accès à un rôle de service destiné à dbt.

Mettre en pratique ce que nous venons de voir

Contexte

Vous êtes Data Engineer au sein d'une équipe Data et vous commencez à travailler sur la mise en place de Snowflake dans votre organisation. On vous demande de gérer 3 bases de données :

Voici une brève description de ces 3 bases :

  • HR_DB contient des données sur les employés et les effectifs ;
  • FINANCE_DB contient des données financières comme des bilans et des états financiers ;
  • REPORTING_DB contient des données destinées à l'analytique et au reporting.

Votre mission : garantir que chaque personne de l'entreprise dispose des bons accès à ces bases.

Besoins

Vous avez interrogé différents utilisateurs Snowflake de votre entreprise et recueilli les besoins suivants :

  1. Richard, Data Analyst travaillant avec les équipes Finance et HR, demande à pouvoir lire toutes les données Finance et HR pour ses analyses. Il souhaite également pouvoir créer des tables de reporting dans la base Reporting.
  2. Lily, Data Engineer dans votre entreprise, doit charger des données historiques dans les bases Finance et HR.
  3. L'équipe Finance utilise un nouvel outil SaaS qui doit lire des données dans les bases Finance et HR et, en bonus, réécrire certaines données traitées dans la base Finance.
  4. On vous demande de mettre en place un nouvel outil de BI et de dashboard qui consommera les données de la base Reporting.

Utilisez le code suivant pour créer les bases dans Snowflake :

use role SYSADMIN ;

create database FINANCE_DB ;
create database HR_DB ;
create database REPORTING_DB ;

-- Create tables, views, ...
-- ...

Étapes

Définir les rôles fonctionnels et de service

Avec les besoins en main, commencez par dresser une liste pour identifier précisément ce qu'il vous faut.

Pour les rôles fonctionnels :

Pour les rôles de service :

⚠️ Accorder des permissions READWRITE complètes sur tous les schémas d'une base à un outil tiers, comme nous le faisons ici (Finance SaaS), n'est sans doute pas la meilleure idée en conditions réelles. Dans un scénario plus réaliste, l'outil n'aurait accès qu'à l'ensemble de schémas spécifiques dont il a besoin pour lire et écrire. N'oubliez pas qu'il s'agit d'un modèle simplifié.

Créer les rôles d'accès

D'après les tableaux ci-dessus, voici les rôles d'accès dont vous avez besoin :

  • HR_READ_ROLE
  • HR_READWRITE_ROLE
  • FINANCE_READ_ROLE
  • FINANCE_READWRITE_ROLE
  • REPORTING_READ_ROLE
  • REPORTING_READWRITE_ROLE

Comme indiqué plus haut, les rôles READ et READWRITE permettront d'exécuter respectivement des instructions SELECT, ou SELECT, INSERT, UPDATE et DELETE. Voici ce que cela donne :

Et voici les instructions à exécuter dans Snowflake :

-- Create Access Roles for HR_DB
use role USERADMIN ;

create role HR_READ_ROLE
        comment = 'Access Role READ for HR_DB' ;
create role HR_READWRITE_ROLE
        comment = 'Access Role READWRITE for HR_DB' ;

-- Grant Privileges to Access Roles for HR_DB
use role SECURITYADMIN ;

-- Granting Privileges to HR_READ_ROLE
-- Database
grant usage on database HR_DB to role HR_READ_ROLE ;

Voir le code complet

Notez que vous pouvez tirer parti de conventions de nommage fixes pour les bases de données et les rôles d'accès. Vous pouvez créer un script unique et utiliser des templates pour réutiliser et déployer facilement plusieurs bases avec leurs rôles d'accès respectifs. Voici un exemple :

-- Assign values to the following variables accordingly
set database_name = 'HR_DB';
set role_read_name = 'HR_READ_ROLE';
set role_readwrite_name = 'HR_READWRITE_ROLE';

-- Create database
use role SYSADMIN ;
create database identifier($database_name) ;

-- Create Access Roles for the database
use role USERADMIN ;
create role identifier($role_read_name) ;
create role identifier($role_readwrite_name) ;

-- Grant Privileges to READ role

Voir le code complet

Créer les rôles fonctionnels

Avec les rôles d'accès en place, vous pouvez facilement créer des rôles fonctionnels représentant les besoins des utilisateurs. C'est le moment de revenir aux besoins exprimés.

Reprenons la demande de Richard :

🎯 Richard, Data Analyst travaillant avec les équipes Finance et HR, demande à pouvoir lire toutes les données Finance et HR pour ses analyses. Il souhaite également pouvoir écrire des tables dans la base Reporting.

Voici ce que cela donne :

Il s'agit d'une implémentation simple de rôles d'accès et fonctionnels pour répondre aux besoins de Richard. Le rôle ANALYST_ROLE est le rôle fonctionnel et constitue le parent de HR_READ_ROLE, FINANCE_READ_ROLE et REPORTING_READWRITE_ROLE (tous des rôles d'accès).

Richard reçoit alors ANALYST_ROLE. Il peut désormais interroger les tables de HR_DB et FINANCE_DB, et modifier les données de REPORTING_DB. Et ce rôle pourra également être attribué à toute autre personne de l'équipe de Richard ayant des responsabilités similaires. 🎉

Dans Snowflake, cela donne :

-- Create Functional Role ANALYST_ROLE
use role USERADMIN ;

create role ANALYST_ROLE
        comment = 'Functional Role for Data Analysts' ;

-- Grants to role ANALYST_ROLE
use role SECURITYADMIN ;

grant role HR_READ_ROLE to role ANALYST_ROLE ;
grant role FINANCE_READ_ROLE to role ANALYST_ROLE ;
grant role REPORTING_READWRITE_ROLE to role ANALYST_ROLE ;

-- Grant Functional Role to SYSADMIN (good practice mentioned before)
grant role ANALYST_ROLE to role SYSADMIN ;

Voir le code complet

Appliquons à présent les mêmes principes pour Lily :

🎯 Lily, Data Engineer dans votre entreprise, doit charger des données historiques dans les bases Finance et HR.

Un exemple similaire pour un rôle fonctionnel Data Engineering :

La configuration est similaire mais, dans ce cas, le rôle ENGINEER_ROLE devient le parent de HR_READWRITE_ROLE et FINANCE_READWRITE_ROLE, puis est attribué à Lily.

Le SQL correspondant :

-- Create Functional Role ENGINEER_ROLE
use role USERADMIN ;

create role ENGINEER_ROLE
        comment = 'Functional Role for Data Engineers' ;

-- Grants to role ANALYST_ROLE
use role SECURITYADMIN ;

grant role HR_READWRITE_ROLE to role ENGINEER_ROLE ;
grant role FINANCE_READWRITE_ROLE to role ENGINEER_ROLE ;

-- Grant Functional Role to SYSADMIN (good practice mentioned before)
grant role ENGINEER_ROLE to role SYSADMIN ;

Voir le code complet

Passons maintenant aux besoins du nouveau SaaS Finance :

🎯 L'équipe Finance utilise un nouvel outil SaaS, qui doit lire des données dans les bases Finance et HR et, en bonus, réécrira certaines données traitées dans la base Finance.

Facile, non ? Voici le diagramme :

Dans ce cas, un nouveau rôle de service est créé, baptisé FINANCE_SAAS_ROLE. Il fonctionne essentiellement comme un rôle fonctionnel, à ceci près qu'il sera utilisé de manière programmatique et non par un humain. Le rôle hérite des privilèges de FINANCE_READWRITE_ROLE et HR_READ_ROLE, et est attribué à un compte de service Snowflake utilisé par le service.

En code :

-- Create Service Role FINANCE_SAAS_ROLE
use role USERADMIN ;

create role FINANCE_SAAS_ROLE
        comment = 'Service Role for Finance SaaS' ;

-- Grants to role FINANCE_SAAS_ROLE
use role SECURITYADMIN ;

grant role FINANCE_READWRITE_ROLE to role FINANCE_SAAS_ROLE ;
grant role HR_READ_ROLE to role FINANCE_SAAS_ROLE ;

-- Grant Service Role to SYSADMIN (good practice mentioned before)
grant role FINANCE_SAAS_ROLE to role SYSADMIN ;

Voir le code complet

Passons au cas de l'outil BI :

🎯 On vous demande de mettre en place un nouvel outil de BI et de dashboards qui consommera les données de la base Reporting.

Du grand classique ?

Dans ce cas, le seul rôle d'accès dont BI_ROLE a besoin est REPORTING_READ_ROLE. L'outil BI pourra désormais exécuter des requêtes SELECT pour alimenter ses dashboards ! 🎉

En code :

-- Create Service Role BI_ROLE
use role USERADMIN ;

create role BI_ROLE
        comment = 'Service Role for BI and Insights Tool' ;

-- Grants to role BI_ROLE
use role SECURITYADMIN ;

grant role REPORTING_READ_ROLE to role BI_ROLE ;

-- Grant Service Role to SYSADMIN (good practice mentioned before)
grant role BI_ROLE to role SYSADMIN ;

-- Grant role to service account

Voir le code complet

Pour conclure

Tous les cas d'usage étant couverts, notre hiérarchie de rôles initiale est complète ! Voici à quoi elle ressemble dans son ensemble :

Bonus — Gérer les changements et les ajustements

L'un des avantages d'une hiérarchie DRY, c'est qu'elle s'ajuste facilement quand de nouveaux besoins apparaissent. Imaginez par exemple que la Data Engineer Lily ait oublié de demander un accès READWRITE à REPORTING_DB. La demande se règle très simplement :

-- Adjust DATA_ENGINEER functional role
use role SECURITYADMIN ;
grant role REPORTING_READWRITE_ROLE to role DATA_ENGINEER ;

Vous gérez désormais une hiérarchie capable de s'adapter facilement à de nouveaux besoins métier ! 🎉

Dans cet article, nous avons partagé quelques conseils et astuces pour bâtir une hiérarchie RBAC Snowflake, illustrés par un exemple concret destiné à simplifier le quotidien des Snowflake Admins. Vous connaissez un bon conseil qui manque ici ? Faites-le nous savoir, nous l'ajouterons à l'article !

Miguel Duarte·Data Engineer chez Tasman Analytics

Miguel est Data Engineer chez Tasman Analytics, où il accompagne des entreprises en forte croissance dans le développement de leurs capacités data. Fort d'un parcours en BI et en analyse de données, il a acquis une solide expérience au sein de cabinets de conseil et d'entreprises produit. Plus récemment, animé par la curiosité et l'envie d'explorer davantage les aspects techniques du cycle de vie de la donnée, il s'est orienté vers le Data Engineering. Au quotidien, Miguel s'appuie sur des outils comme Snowflake pour aider les organisations à construire et optimiser leur infrastructure data.