Kernpunten
- RLS filtert rijen in het semantische model, en geldt dus voor elk rapport dat op dat model draait.
- Statische RLS gebruikt vaste waarden per rol; dynamische RLS filtert op de ingelogde gebruiker, meestal met USERPRINCIPALNAME().
- Bij Power BI Embedded geeft de applicatie de identiteit mee in het embedtoken, eventueel met een extra waarde die je uitleest met CUSTOMDATA().
- RLS geldt alleen voor kijkers; leden, inzenders en beheerders van een werkruimte zien alle data.
- Een veilige inrichting kent geen terugval: wie geen rol of tag heeft, ziet niets.
Hoe row-level security in Power BI werkt
Row-level security is een vorm van rolgebaseerde toegang tot data (role-based access): de rol van een gebruiker bepaalt welke rijen hij ziet. In Power BI Desktop maak je via Modellering en Rollen beheren een of meer rollen aan. Per rol schrijf je een DAX-filter op een tabel, bijvoorbeeld [Regio] = "Noord". Het filter wordt per rij geëvalueerd; alleen rijen waarvoor de uitkomst waar is, blijven zichtbaar.
Het filter loopt via de relaties in je model door naar gekoppelde tabellen. Filter je de dimensie Klant, dan worden ook de orders en facturen van andere klanten verborgen. Na publicatie wijs je in de Power BI-service gebruikers of beveiligingsgroepen toe aan de rollen, in de beveiligingsinstellingen van het semantische model.
Omdat RLS in het model zit, geldt het voor elk rapport en elke analyse op dat model, ook als iemand de data in Excel analyseert. RLS beperkt rijen, geen tabellen of kolommen. Wil je hele kolommen of tabellen verbergen, dan heb je object-level security nodig.
Statische en dynamische RLS
Bij statische RLS staat de filterwaarde vast in de rol. Je maakt dan bijvoorbeeld de rollen Noord, Oost, Zuid en West, elk met een eigen filter. Bij dynamische RLS is er vaak maar één rol, en hangt het filter af van wie er kijkt.
Een gangbare opzet voor dynamische RLS is een toegangstabel met per regel een e-mailadres en een regio of klant. Het rolfilter op die tabel luidt dan [E-mail] = USERPRINCIPALNAME(). Let op de richting van de relatie: het filter moet van de toegangstabel naar je dimensie kunnen lopen. Lukt dat niet, dan kun je in de relatie het beveiligingsfilter in beide richtingen laten toepassen, of het filter rechtstreeks op de dimensie schrijven.
| Statische RLS | Dynamische RLS | |
|---|---|---|
| Filter | Vaste waarde per rol, zoals [Regio] = "Noord" | Afhankelijk van de gebruiker, via USERPRINCIPALNAME() of CUSTOMDATA() |
| Aantal rollen | Eén rol per variant | Vaak één rol voor iedereen |
| Beheer | Nieuwe regio betekent een nieuwe rol | Nieuwe gebruiker betekent een nieuwe rij in de toegangstabel |
| Geschikt voor | Weinig, stabiele groepen | Veel gebruikers of klanten, wisselende toegang |
USERPRINCIPALNAME() en USERNAME()
USERPRINCIPALNAME() geeft de user principal name (UPN) van de ingelogde gebruiker terug, meestal in de vorm naam@bedrijf.nl. USERNAME() geeft in de Power BI-service hetzelfde terug, maar in Power BI Desktop de vorm DOMEIN\gebruiker. Gebruik daarom bij voorkeur USERPRINCIPALNAME(), zodat je filter in Desktop en in de service hetzelfde werkt.
Een UPN is niet altijd gelijk aan het e-mailadres in je toegangstabel, bijvoorbeeld bij aliassen of na een naamswijziging. Controleer dat voordat je live gaat. Bij Power BI Embedded in het scenario "app owns data" geven beide functies de gebruikersnaam terug die de applicatie in het embedtoken meegeeft.
RLS bij Power BI Embedded: effectieve identiteit en CUSTOMDATA
In een klantportaal logt de eindgebruiker niet in bij Microsoft. De applicatie meldt zich aan met een service principal, die zelf alle data mag zien. Daarom geeft de applicatie bij het aanvragen van het embedtoken een effectieve identiteit (effective identity) mee: een gebruikersnaam, een of meer rollen en het semantische model. Power BI past de RLS-regels toe voor die identiteit. Heeft een model RLS, dan geeft Power BI zonder identiteit geen embedtoken af.
Naast de gebruikersnaam kun je een vrije tekstwaarde meegeven: customData. In een rolfilter lees je die uit met de DAX-functie CUSTOMDATA(), bijvoorbeeld [Klantcode] = CUSTOMDATA(). Dat is handig als de gebruikers van je portaal niet in je Microsoft Entra ID staan en je wilt filteren op een kenmerk dat in het portaal wordt beheerd, zoals een klantnummer of vestiging. Het betekent ook dat de applicatie volledig verantwoordelijk is voor de juiste waarde: een fout in die koppeling is een datalek.
In ENABLE koppel je toegangsprofielen of een gebruikerstag aan Power BI-rollen, optioneel met CUSTOMDATA(). Heeft een gebruiker geen tag, dan krijgt hij geen toegang: ENABLE valt nooit terug op ongefilterde data. RLS staat standaard uit en zet je per klant aan.
RLS testen voordat je live gaat
Test row-level security altijd met echte gebruikersscenario's, niet alleen met de rol die je net hebt gemaakt. In ENABLE kan een beheerder bovendien met "bekijk als gebruiker" nagaan wat een specifieke gebruiker te zien krijgt. Een praktische volgorde:
- Gebruik in Power BI Desktop de optie Weergeven als: kies een rol en, bij dynamische RLS, een andere gebruiker met een UPN uit je toegangstabel.
- Test na publicatie in de Power BI-service via de beveiligingsinstellingen van het semantische model met Testen als rol, eventueel als specifieke gebruiker.
- Test de randgevallen: een gebruiker zonder rij in de toegangstabel, een gebruiker met meerdere regio's, een nieuwe klant en een vertrokken medewerker.
- Controleer totalen en kaarten. Een measure met ALL() komt niet buiten het RLS-filter, maar een tabel zonder relatie met de gefilterde tabel wordt helemaal niet gefilterd.
- Test in een portaal de hele keten, van login tot embedtoken, en niet alleen het model.
Veelgemaakte fouten met row-level security
De meeste problemen met RLS zitten niet in de DAX-formule, maar in de inrichting eromheen. Let op deze valkuilen:
- Lezers met de rol lid, inzender of beheerder in de werkruimte. Voor hen geldt RLS niet; geef lezers de rol kijker of deel via een app.
- Tabellen zonder relatie met de gefilterde tabel. Die worden niet gefilterd en tonen dus alle rijen.
- Geen bewuste keuze voor gebruikers zonder rol. Het veilige uitgangspunt is: geen rol of tag betekent geen data.
- Een verouderde toegangstabel. RLS is zo goed als de koppeling tussen gebruikers en data; vertrekkers en verschuivingen moeten worden bijgewerkt.
- Vertrouwen op verborgen filters of slicers in het rapport. Dat is vormgeving, geen beveiliging.
- Ingewikkelde DAX in rolfilters op grote feitentabellen. Filter bij voorkeur op kleine dimensietabellen; dat is sneller en beter te controleren.