4.2 · Sécurité au niveau des lignes (RLS)

Niveau 4 · Design, sécurité & performance

4.2Sécurité au niveau des lignes (RLS)

Objectif : Créer des rôles statiques, les tester, et monter la RLS dynamique avec sa table de correspondance utilisateur → périmètre.
Temps estimé : 20 min · lecture autonome · Si vous n'avez que 5 min : lisez « L'essentiel en 30s » + le schéma.

L'essentiel en 30 secondes

  • La RLS filtre les lignes selon l'utilisateur : un rôle dans Desktop porte un filtre DAX (ex. [Région] = "Alger"), testé par « Afficher comme », puis assigné dans le Service.
  • On filtre les dimensions (le filtre se propage aux faits par la relation) plutôt que les faits directement — et on teste toujours avant de publier.
  • La RLS dynamique : un seul rôle qui filtre via USERPRINCIPALNAME() et une table de sécurité (e-mail → périmètre) — le standard pro, plus un rôle par personne.

Mini-cas filé — Zineb ouvre le rapport aux directeurs régionaux

Zineb, contrôleuse de gestion dans une PME agroalimentaire à Alger, publie un rapport de ventes unique pour trois directeurs régionaux — mais chacun ne doit voir que sa région, car les chiffres par secteur sont confidentiels. Elle applique la méthode : dans Modélisation → Gérer les rôles, elle crée « Région Alger » avec le filtre DAX [Région] = "Alger" posé sur la dimension Région. Elle teste avec « Afficher comme » : tout le rapport se restreint à Alger. Puis elle prépare l'industrialisation : une table Securite (Email, Région) reliée à la dimension, et un rôle « Dynamique » dont le filtre est Securite[Email] = USERPRINCIPALNAME(). Elle note le jalon : l'assignation réelle des utilisateurs se fera dans le Service (niveau 5).

Cas autonome de cette section : il revient dans le cours, le schéma, le script et le défi 48h de la section 4.2.

1. Un rapport, des lectures

Un même rapport, des lectures différentes : le directeur d'Alger ne voit qu'Alger, la directrice générale voit tout. C'est la sécurité au niveau des lignes (RLS) : des rôles définis dans Desktop (Modélisation → Gérer les rôles) portent des filtres DAX comme [Région] = "Alger". La RLS filtre les lignes visibles selon l'utilisateur connecté : un rapport, des périmètres différents. Zineb définit donc un rôle par périmètre.

2. Filtrer les dimensions, tester toujours

On pose le filtre sur les dimensions (Région, Ville) : par la relation, il se propage aux tables de faits — plus fiable que de filtrer les faits directement. Et on teste toujours avec « Afficher comme » (Modélisation) : on voit le rapport avec les yeux d'un rôle avant de publier. Zineb simule « Région Alger » et vérifie que rien ne déborde.

3. La RLS dynamique

Créer un rôle par personne ne tient pas à l'échelle. La version dynamique industrialise : une table de sécurité (Email → Région) reliée à la dimension, et un unique rôle dont le filtre est Securite[Email] = USERPRINCIPALNAME(). Chaque utilisateur ne voit alors que son périmètre, sans rôle dédié. Zineb pose ce standard — c'est aussi le réflexe attendu à la PL-300.

Erreur d'interprétation fréquente : « La RLS, je la teste avec mon propre compte, je pose le filtre sur les faits au hasard, et je crée un rôle par personne ». Non, triple erreur. Je teste avec « Afficher comme » : un auteur voit toujours tout, donc tester avec son compte ne prouve rien. Je filtre les dimensions (le filtre se propage aux faits), pas les faits directement. Et je passe à la RLS dynamique (USERPRINCIPALNAME + table de sécurité) plutôt que d'empiler un rôle par personne, ingérable.
De statique à dynamique La brique sécurité : un rôle à filtre DAX, testé, puis industrialisé en dynamique. Rôle Filtre DAX[Région] = "Alger"Tester Afficher commeTable sécurité Email→ Région
La brique sécurité : un rôle à filtre DAX, testé, puis industrialisé en dynamique.
Version texte du schéma (SEO / lecteurs d'écran / traduction) : 1) Zineb, contrôleuse de gestion à Alger, veut un rapport unique lu différemment selon les directeurs régionaux : elle crée des rôles (Modélisation → Gérer les rôles) portant un filtre DAX comme [Région] = "Alger", posé sur la dimension Région. 2) Elle teste chaque rôle avec « Afficher comme » — jamais avec son propre compte d'auteur, qui voit toujours tout — et vérifie que le filtre des dimensions se propage bien aux faits. 3) Elle industrialise : une table de sécurité (Email → Région) reliée à la dimension, et un unique rôle dynamique filtré par Securite[Email] = USERPRINCIPALNAME(). Leçon : filtrer les dimensions, tester toujours, et préférer la RLS dynamique à un rôle par personne.

🔎 Exemple concret — 🔎 Exemple concret — Le rôle dynamique

Zineb fait tenir tous les périmètres dans un seul rôle :

Table Securite (Email, Région) reliée à la dimension Région.
Rôle « Dynamique », filtre sur Securite :
  Securite[Email] = USERPRINCIPALNAME()
→ chaque utilisateur ne voit que son périmètre, sans rôle dédié.

Lecture : un seul rôle suffit pour tous — la table de sécurité porte la correspondance e-mail → région.

Leçon : tester avec « Afficher comme » en spécifiant un e-mail de la table : le périmètre suit l'identité.

Vocabulaire de la section

RLS (Row-Level Security)
Filtrer les LIGNES visibles selon l'utilisateur connecté : un rapport, des périmètres de données différents.

Exemple simple : Zineb restreint le rapport à la région de chaque directeur.

Ce que ce n'est pas : partager un rapport où tout le monde voit tout.

Réflexe : données confidentielles → RLS.

Rôle
Un jeu de filtres DAX nommé (Modélisation → Gérer les rôles) : « Région Alger » = [Région]="Alger".

Exemple simple : Zineb crée un rôle par périmètre, puis un rôle dynamique.

Ce que ce n'est pas : un filtre posé à la main sur un seul visuel.

Réflexe : rôle = filtre DAX nommé et réutilisable.

Afficher comme
Le test dans Desktop (Modélisation → Afficher comme) : voir le rapport avec les yeux d'un rôle avant publication.

Exemple simple : Zineb simule « Région Alger » et ne voit qu'Alger.

Ce que ce n'est pas : tester avec son propre compte d'auteur.

Réflexe : la RLS se teste, toujours, avant publication.

USERPRINCIPALNAME()
La fonction qui renvoie l'e-mail de l'utilisateur connecté : la clé de la RLS dynamique.

Exemple simple : Zineb l'utilise pour filtrer les lignes selon l'identité.

Ce que ce n'est pas : un filtre figé sur une seule valeur.

Réflexe : RLS dynamique → USERPRINCIPALNAME().

Table de sécurité
La table de correspondance e-mail → périmètre (région, ville…) qu'un unique rôle dynamique traverse pour filtrer.

Exemple simple : Zineb y liste Email et Région pour ses directeurs régionaux.

Ce que ce n'est pas : un rôle dédié par personne.

Réflexe : un rôle dynamique + une table de sécurité.

En pratique — En pratique — Du rôle statique à la RLS dynamique

  1. Modélisation → Gérer les rôles → Nouveau : « Région Alger » avec le filtre DAX [Région] = "Alger" (sur la dimension Région — le meilleur choix).
  2. Testez : Modélisation → Afficher comme → cochez le rôle : tout le rapport se restreint à Alger. Quittez le mode test.
  3. Version dynamique : créez une table Securite (Email, Région) avec 2-3 lignes, reliez-la à la dimension Région, puis un rôle « Dynamique » filtré par Securite[Email] = USERPRINCIPALNAME().
  4. Testez encore avec « Afficher comme » en spécifiant un e-mail de la table : le périmètre suit l'identité. (L'assignation réelle des utilisateurs se fait dans le Service — niveau 5.)
La RLS maîtrisée dans ses deux formes — la brique sécurité exigée de tout déploiement d'entreprise (et de la PL-300).

Script pas-à-pas — sécuriser le rapport comme Zineb (8 min)

1) Modélisation → Gérer les rôles → Nouveau, nommez « Région Alger », sélectionnez la dimension Région et écrivez le filtre DAX [Région] = "Alger". 2) Modélisation → Afficher comme → cochez le rôle : tout le rapport se limite à Alger ; décochez pour revenir. 3) Créez une table Securite (Email, Région) de 2-3 lignes et reliez Région à la dimension Région. 4) Rôle « Dynamique » : filtre Securite[Email] = USERPRINCIPALNAME(). 5) Testez avec « Afficher comme » en saisissant un e-mail de la table : le périmètre suit l'identité. L'assignation des utilisateurs se fera dans le Service.

Si le test ne change rien, vérifiez le sens de la relation et que le filtre porte bien sur la DIMENSION (le filtre se propage aux faits).

Modèle copier-coller — ma check-list RLS

Rôles : Modélisation → Gérer les rôles → Nouveau
Filtre statique : [Région] = "Alger" (sur la DIMENSION, pas les faits)
Tester : Modélisation → Afficher comme (jamais avec son propre compte)
Dynamique : table Securite (Email, Région) + rôle filtré par
  Securite[Email] = USERPRINCIPALNAME()
Assignation des utilisateurs : dans le Service (niveau 5).

Par région

Zineb crée un rôle « Région Alger » : le directeur d'Alger ne voit que sa région.

Test « Afficher comme »

Zineb simule chaque rôle avant de publier : aucun périmètre ne déborde.

Un rôle pour tous

Zineb remplace les rôles par personne par un rôle dynamique USERPRINCIPALNAME().

Dimensions d'abord

Zineb filtre la dimension Région : le filtre se propage aux ventes par la relation.

Prudence : La RLS touche à la confidentialité des données : définissez qui a le droit de voir quoi, testez chaque rôle avant de publier et documentez les périmètres. Ces règles relèvent de la gouvernance de votre organisation — la RLS filtre les lignes, mais ne remplace pas les permissions d'accès au rapport. En cas de doute sur un périmètre sensible, faites valider la règle en interne.

✓ Bonnes pratiques

  • Filtrer les dimensions (le filtre se propage aux faits par la relation).
  • Tester avec « Afficher comme » avant toute publication.
  • Préférer la RLS dynamique (USERPRINCIPALNAME + table de sécurité).

✗ Pièges fréquents

  • Filtrer directement les faits au lieu des dimensions.
  • Publier une RLS sans l'avoir testée.
  • Créer un rôle par personne (ingérable ; préférer le dynamique).

Points clés à retenir

  • La RLS filtre les données par utilisateur : un rapport unique, des visions multiples.
  • Filtrez les DIMENSIONS plutôt que les faits directement.
  • « Afficher comme » avant toute publication : la RLS se teste, toujours.
  • La RLS dynamique (USERPRINCIPALNAME + table de sécurité) évite un rôle par personne.

Défi 48h — appliquez demain

Comme Zineb, créez un rôle RLS sur un rapport (ex. [Région] = "Alger"), testez-le avec « Afficher comme », puis montez la table de sécurité + le rôle dynamique (USERPRINCIPALNAME). Écrivez en une phrase qui doit voir quoi dans votre organisation.

Checklist sortie de section
  • Je peux créer un rôle RLS avec un filtre DAX et le tester (« Afficher comme »).
  • Je filtre les dimensions et je sais pourquoi.
  • Je sais monter une RLS dynamique avec USERPRINCIPALNAME et une table de sécurité.
Auto-évaluation 1-5 : est-ce que je pose toujours le filtre sur la dimension ?Auto-évaluation 1-5 : ai-je testé chaque rôle avant de le considérer prêt ?

Questions fréquentes

La RLS s'applique-t-elle aussi à moi, l'auteur ?

Dans Desktop, non (sauf en mode test) : vous voyez tout. Dans le Service, les administrateurs et membres de l'espace de travail ne sont pas soumis à la RLS — elle joue pour les lecteurs. N'en concluez donc pas qu'elle « ne marche pas » en la testant avec votre propre compte.

La RLS protège-t-elle contre l'export des données ?

Oui pour le périmètre : un lecteur limité à Alger n'exporte que les lignes d'Alger. Mais elle ne remplace pas les permissions d'accès au rapport (qui peut l'ouvrir) : les deux couches se complètent.

Vérifiez votre compréhension

Quelle fonction est la clé de la RLS dynamique ?

Ressources supplémentaires (optionnel, pour aller plus loin)

Examen du niveau 4Questions inédites et durcies pour valider vos acquis