Administrer les accès aux objets dans Snowflake

Qui peut faire quoi ? Sur quels objets ?

Voici les questions auxquelles nous devons répondre en implémentant notre stratégie de gestion de droit. Comme vous l’aurez sans doute deviné, cet article va traiter du fonctionnement du mécanisme de gestion des accès de Snowflake. S’il est facile à prendre en main, il peut être ardu d’en saisir toutes les subtilités. Je vais essayer de regrouper tout ce qu’il y a à savoir dessus dans cet article.

Une approche discrétionnaire basée sur des rôles

Dans Snowflake, les différents objets sont organisés sous forme de hiérarchie dont la racine est le compte. On peut répartir les objets en deux catégories. Il y a ceux, comme les warehouses, les bases de données, les utilisateurs et les rôles, qui sont rangés à la racine. Les autres appartiennent à un schéma qui, lui-même, se situe dans une base de données. Parmi ces derniers, on trouve notamment les tables, les vues, les stages, etc. Puisqu’un dessin vaut mieux que mille mots, vous trouverez ci-dessous la hiérarchie des objets.

Hiérarchie des objets dans Snowflake
Hiérarchie des objets dans Snowflake

À chaque type d'objet correspond un ensemble de privilèges qui, une fois accordés, permettent au bénéficiaire d'opérer les actions correspondantes sur l'objet en question. Par exemple, la lecture d’une table n’est possible qu’à ceux qui se sont vu accorder le privilège SELECT dessus. En suivant ce lien vers la documentation de Snowflake, vous trouverez une liste exhaustive des objets et de leurs privilèges. Ne vous laissez pas impressionner par le nombre, tout est bien expliqué.

Mais attention, pour opérer sur un objet stocké dans un schéma, il ne suffit pas d’avoir des privilèges dessus, il faut aussi concéder les droits d’utilisation sur les conteneurs (base de données et schéma) dans lesquels il se trouve.

Les privilèges ne peuvent pas directement être donnés aux utilisateurs. Il faut les attribuer à des rôles qui seront eux-mêmes attribués à des utilisateurs. Ainsi, lors d'une session, un utilisateur pourra impersonnifier l'un des rôles qui lui a été accordé, jouissant ainsi des privilèges liés à ce celui-ci.

Pour résumer, il est possible d’effectuer un ensemble d’actions sur un objet. Ces actions correspondent à des privilèges. Ces privilèges peuvent être accordés à un rôle. Ce rôle peut être attribué à un utilisateur qui pourra effectuer sur cet objet les actions autorisées à ce rôle. Il ne nous reste plus qu’à voir qui peut accorder des privilèges sur des objets à des rôles. C’est ici qu’intervient la notion de propriété.

Dans Snowflake, tous les objets disposent d'un privilège OWNERSHIP qui est automatiquement accordé au rôle ayant été utilisé à sa création. En plus de lui donner tous les droits, le rôle propriétaire d’un objet peut octroyer des privilèges dessus à d’autres rôles. Si un objet ne peut avoir qu'un propriétaire, il est toutefois possible de transférer le privilège OWNERSHIP à un autre rôle.

Voilà pour les bases, voyons maintenant la première petite subtilité : les hiérarchies de rôles.

Inception : des rôles dans des rôles

De la même manière que l'on peut accorder un rôle à des utilisateurs, il est possible d'accorder un rôle à d'autres rôles, créant ainsi une hiérarchie de rôle.

Dans une hiérarchie, le rôle parent hérite de l'ensemble des privilèges de ses enfants. Cela permet notamment, en créant plusieurs niveaux de rôle, d’implémenter une stratégie de gestion d’accès reflétant l’organisation de l’entreprise. Au premier niveau, on aurait des rôles techniques accordant des accès à une sélection d’objets à différentes granularités (par exemple : rôle de lecture, rôle d’écriture). Ensuite, on pourrait définir des rôles fonctionnels, représentant des fonctions dans l’entreprise, en se basant sur les rôles techniques qui sont nécessaires à l'accomplissement de leurs tâches.

Fonctionnement du mécanisme de rôle
Exemple de hiérarchie de rôle avec les rôles techniques Lecture et Ecriture et les rôles fonctionnels Adhérent et Admin. Ces derniers se basent sur les rôles techniques héritant ainsi de leurs privilèges.

Maintenant que vous êtes familiarisé avec les hiérarchies de rôles, je vais pouvoir vous parler des rôles système.

Au commencement, il y avait 5 rôles…

Snowflake met à disposition 5 rôles systèmes : ACCOUNTADMIN, SYSADMIN, SECURITYADMIN, USERADMIN et PUBLIC. Ces rôles sont organisés dans la manière suivante :

Hiérarchie des rôles système
Hiérarchie des rôles système de Snowflake

Comme ils sont en hiérarchie, je vais vous les présenter en commençant par le bas :

  • Le rôle PUBLIC est accordé automatiquement à l’ensemble des utilisateurs. De plus, tout nouveau rôle sera automatiquement parent de PUBLIC. Cela fait donc de lui le rôle le plus bas de la hiérarchie. Il est donc pratique pour propager des privilèges à l’ensemble des rôles.
  • Le rôle USERADMIN permet de créer des rôles personnalisés et des utilisateurs. Et comme tout propriétaire d’objet, il va pouvoir les administrer.
  • Le rôle SECURITYADMIN, en plus d’hériter des privilèges de USERADMIN, a le privilège global MANAGE GRANTS. Celui-ci lui permet d’administrer les privilèges de tous les objets du compte comme s’il en était le propriétaire.
  • Le rôle SYSADMIN permet quant à lui de créer des bases de données et des warehouses. Même topo que pour USERADMIN, SYSADMIN va permettre d’administrer les objets dont il est propriétaire.
  • ACCOUNTADMIN est le rôle principal servant à la configuration du compte. Il cumule l’ensemble privilèges globaux et hérite des tous les privilèges des autres rôles système. De par la nature critique de ce rôle, il convient de mettre en place un certain nombre de bonnes pratiques :
    • mettre en place la MFA pour les utilisateurs ayant accès à ce rôle
    • accorder ce rôle à au moins 2 utilisateurs afin de parer l’éventualité d’une perte de mot de passe
    • ne pas définir ce rôle comme rôle par défaut d'un utilisateur afin de prévenir des actions involontaires avec le rôle.

Vous voilà presque paré pour vous lancer. Mais avant ça, j’aimerai voir avec vous quelques points auxquels il faut faire attention.

5 secrets sur les rôles (le 2ème va vous étonner)

O. Twist : l’objet orphelin

Nous avons vu ensemble que SYSADMIN pouvait créer des bases de données. Ce faisant, il est propriétaire légitime de ces bases et sera donc en mesure de créer des objets dedans.

Maintenant, imaginez qu’un rôle non rattaché à SYSADMIN crée un objet dans une de ces bases. N’étant ni propriétaire de l’objet, ni parent du propriétaire de l’objet, SYSADMIN ne sera pas en mesure de l’administrer. C’est ce qu’on appelle un rôle orphelin.

Afin d’éviter ce cas de figure, il est conseillé de rattacher les hiérarchies de rôles personnalisés à SYSADMIN.

De plus, il peut également être judicieux d’utiliser les schémas en mode accès managé. Cela permet de centraliser l’administration des droits sur les objets contenus. En effet, si un objet est créé dans un schéma managé, son propriétaire perdra, au profit du propriétaire du conteneur, le droit d’octroi de privilèges sur l’objet. Ainsi, même si le propriétaire n’est pas rattaché à SYSADMIN, ce dernier pourra toujours agir sur l’objet en s’accordant des privilèges dessus.

Travailler avec des données sensibles

Si vous travaillez avec des données sensibles, vous serez sûrement amené à mettre en place une sécurité à la ligne et/ou à la colonne (appelées respectivement dans Snowflake row access policy et masking policy).

Dans ce cas, il est conseillé de créer un rôle équivalent à la fonction de data protection officer introduite par la RGPD. Ce rôle devra avoir les privilèges globaux APPLY MASKING POLICY et APPLY ROW ACCESS POLICY. Ces privilèges n’étant pas attribués par défaut au SYSADMIN, il est préférable de ne pas respecter la règle énoncée ci-dessus. On préférera plutôt rattacher ce nouveau rôle à la hiérarchie de rôles système via le rôle ACCOUNTADMIN.

De manière générale, avant de raccrocher un rôle à une hiérarchie, il faut s’interroger sur la nécessité d’accorder les droits correspondants aux rôles parents.

Pour aller plus loin sur le sujet des données sensibles, je vous recommande l’article d’Antoine Chenon sur les maskings policies.

USERADMIN ou SECURITYADMIN ?

Lorsqu’un rôle est supprimé, le privilège d’OWNERSHIP des objets dont il est propriétaire est transféré au rôle utilisé pour la suppression. Ainsi, USERADMIN pourrait accéder à des objets auxquels il ne devrait pas en supprimant des rôles qu’il possède.

Dans certains cas, il pourrait donc être préférable de réaliser les créations de rôles avec le rôle SECURITYADMIN. En effet, avec le privilège MANAGE GRANTS, celui-ci est déjà en mesure de s’accorder les droits sur tous les objets.

De manière générale, il est préférable d’opérer le transfert d’OWNERSHIP avant la suppression de rôle.

Avec future grants, fini les oublis !

Pour simplifier l’octroi de droit, un rôle avec le privilège MANAGE GRANTS peut automatiquement accorder, pour certains types d'objets (schémas ou objets de schéma), un ensemble de privilèges sur toutes nouvelles instances d’objets.

Par exemple, il est possible d’accorder à un rôle le privilège de SELECT sur toutes les futures tables d’un schéma.

Si votre organisation d’objet est bien pensée, vous n’aurez plus jamais à faire de grant aux rôles technique de lecture/écriture !

Le cumul de rôles

On peut attribuer autant de rôles à un utilisateur qu’il en a besoin. De plus, quand un utilisateur se voit attribuer un rôle, il peut également endosser n’importe lequel des rôles fils de ce dernier. Un utilisateur peut donc vite se retrouver à la tête d’une multitude de rôles.

Dans une session, afin de déterminer l’ensemble de privilèges auquel l’utilisateur aura accès, un rôle principal devra être défini. S’il n’est pas choisi explicitement parmi les rôles disponibles à l’utilisateur, il prendra la valeur du rôle par défaut de l’utilisateur. Ce rôle sera celui retourné par la fonction de contexte current_role().

Ainsi, un utilisateur n’a accès aux privilèges que d’un seul de ses rôles à la fois. Néanmoins, il peut passer outre ce fonctionnement en utilisant la commande USE SECONDARY ROLES ALL qui lui donnera accès à l’union des privilèges de ses rôles, avec pour exception les privilèges de création d’objets qui ne proviennent que du rôle principal.

L’utilisation d’une telle commande peut révéler qu’il manque un rôle taillé pour la fonction de cet utilisateur.

Conclusion

J’espère que cet article vous aura aidé à comprendre le fonctionnement du mécanisme de contrôle d’accès de Snowflake.

Avant de commencer à implémenter votre stratégie de gestion d’accès, je vous invite à consulter le post d’Arnaud Col concernant la gouvernance dans Snowflake. Celui-ci propose une organisation des objets qui pourrait vous inspirer.