Dans les articles sur les accès et les rôles système, on a vu comment structurer les droits avec des rôles. Sauf qu'on n'a jamais posé en clair le modèle sur lequel tout ça repose.
Quand tu fais un GRANT SELECT ... TO ROLE ..., c'est du RBAC. Quand le rôle qui a créé une table décide qui peut y accéder, c'est du DAC. Et Snowflake utilise les deux en même temps.
DAC + RBAC : le modèle de contrôle d'accès de Snowflake
Snowflake combine deux modèles :
RBAC (Role-Based Access Control) : C'est tout ce qu'on a vu dans l'article sur les accès. Les privilèges sont donnés à des rôles, et les rôles sont donnés ensuite aux utilisateurs. Donc on ne donne jamais un droit explicitement à un user mais plutôt à un rôle, et ensuite on attribue le rôle au user.
DAC (Discretionary Access Control) : C'est un modèle où le propriétaire d'un objet décide qui peut y accéder. Dans Snowflake, chaque objet (table, vue, schéma, base...) a un rôle propriétaire, c'est le rôle qui a créé l'objet. Et c'est ce rôle (ou un rôle parent dans la hiérarchie) qui peut accorder ou révoquer les privilèges dessus.
Concrètement, ça donne quoi ?
Prenons un exemple. Le rôle DATA_ENGINEER crée une table :
USE ROLE DATA_ENGINEER;
CREATE TABLE ANALYTICS_DB.RAW.EVENTS (
EVENT_ID NUMBER,
EVENT_TYPE STRING,
CREATED_AT TIMESTAMP
);
À ce stade, DATA_ENGINEER est le propriétaire de la table EVENTS. Si un autre rôle comme FINANCE_ANALYST essaye de lire cette table, il n'y aura pas accès, même s'il a USAGE sur la base et le schéma.
Pour lui donner accès, il faut que le propriétaire (ou un rôle parent) accorde le droit explicitement :
-- Le propriétaire DATA_ENGINEER accorde le SELECT
GRANT SELECT ON TABLE ANALYTICS_DB.RAW.EVENTS TO ROLE FINANCE_ANALYST;
C'est ça le DAC car le propriétaire (ou un rôle parent) décide.
Vérifier le propriétaire d'un objet
-- Voir qui possède une table
SHOW GRANTS ON TABLE ANALYTICS_DB.RAW.EVENTS;
Dans la colonne privilege, tu verras une ligne avec OWNERSHIP et le rôle propriétaire.

Transférer la propriété
Parfois un objet est créé avec un rôle qui ne devrait pas être propriétaire. Par exemple, quelqu'un crée une table avec ACCOUNTADMIN par erreur. Tu peux transférer la propriété comme suit :
GRANT OWNERSHIP ON TABLE ANALYTICS_DB.RAW.EVENTS
TO ROLE DATA_ENGINEER
REVOKE CURRENT GRANTS;
REVOKE CURRENT GRANTS retire les grants existants au passage. Si tu veux les garder, utilise COPY CURRENT GRANTS.
GRANT OWNERSHIP ON TABLE ANALYTICS_DB.RAW.EVENTS
TO ROLE DATA_ENGINEER
COPY CURRENT GRANTS;
Le piège classique avec le DAC
C'est exactement pour cette raison qu'il est recommandé de toujours rattacher les nouveaux rôles à SYSADMIN et ne jamais laisser de rôle orphelin.
-- Rattacher le rôle pour éviter d'avoir un rôle orphelin
GRANT ROLE DATA_ENGINEER TO ROLE SYSADMIN;
Secondary Roles : utiliser plusieurs rôles en même temps
Par défaut dans Snowflake, un utilisateur a un seul rôle actif à la fois. Si tu es FINANCE_ANALYST et que tu veux accéder à une table qui nécessite le rôle MARKETING_READ, tu dois faire un USE ROLE. Mais tu perds alors tes droits FINANCE_ANALYST.
C'est un problème qu'on rencontre rapidement en pratique. Et les Secondary Roles le résolvent.
Exemple sans secondary roles
USE ROLE FINANCE_ANALYST;
-- OK : on a le droit
SELECT * FROM FINANCE_DB.MART_FINANCE.REVENUE;
-- ERREUR : on n'a pas le droit avec ce rôle
SELECT * FROM MARKETING_DB.MART_MARKETING.CAMPAIGNS;
-- Il faut switcher
USE ROLE MARKETING_READ;
-- OK maintenant
SELECT * FROM MARKETING_DB.MART_MARKETING.CAMPAIGNS;
-- Mais on a perdu l'accès finance
SELECT * FROM FINANCE_DB.MART_FINANCE.REVENUE; -- ERREUR
Exemple avec secondary roles : tout d'un coup
USE ROLE FINANCE_ANALYST;
USE SECONDARY ROLES ALL;
-- OK
SELECT * FROM FINANCE_DB.MART_FINANCE.REVENUE;
-- OK aussi, grâce aux secondary roles
SELECT * FROM MARKETING_DB.MART_MARKETING.CAMPAIGNS;
USE SECONDARY ROLES ALL, l'utilisateur hérite des privilèges de tous les rôles qui lui sont assignés, en plus de son rôle actif. Plus besoin de switcher.Désactiver les secondary roles
USE SECONDARY ROLES NONE;
Le comportement redevient celui par défaut avec un seul rôle actif.
Configurer les secondary roles par défaut pour un utilisateur
Pour éviter par exemple qu'un utilisateur fait la manip USE SECONDARY ROLES ALL à chaque connexion
USE ROLE SECURITYADMIN;
ALTER USER alice_toto SET DEFAULT_SECONDARY_ROLES = ('ALL');
À partir de là, les secondary roles sont activés automatiquement à chaque connexion pour cet utilisateur.
Le point subtil : OWNERSHIP et CURRENT_ROLE
Les secondary roles donnent accès aux privilèges de tous les rôles. Mais le rôle actif (CURRENT_ROLE) reste celui défini par USE ROLE. Et c'est ce CURRENT_ROLE qui détermine le propriétaire (OWNERSHIP) quand tu crées un objet.
USE ROLE FINANCE_ANALYST;
USE SECONDARY ROLES ALL;
-- Cette table sera créée avec FINANCE_ANALYST comme propriétaire
-- (pas MARKETING_READ, même si ses privilèges sont actifs)
CREATE TABLE FINANCE_DB.MART_FINANCE.TEST (ID NUMBER);
Vérifier les rôles actifs
-- Le rôle principal
SELECT CURRENT_ROLE();
-- Tous les rôles secondaires actifs
SELECT CURRENT_SECONDARY_ROLES();
Aller plus loin : Formation Snowflake
J'ai regroupé tous mes articles Snowflake dans un parcours complet.
👉 Formation Snowflake : tous les modules pas à pas
Vous voulez que je vous accompagne sur votre projet data (Snowflake, ingestion, modélisation, performance, coûts, gouvernance) ?

