Zabezpečení dat a Row Level Security
Cíle kapitoly
- Pochopit koncept Row Level Security a kdy jej používat
- Implementovat statické RLS s fixními rolemi
- Vytvořit dynamické RLS na bázi USERNAME()
- Ovládat LOOKUPVALUE() pattern pro mapování uživatelů
- Správně nastavit a testovat RLS role v Power BI
- Nasadit RLS do Power BI Service
- Vyhnout se bezpečnostním chybám
Co je Row Level Security (RLS)?
Row Level Security (RLS) je mechanismus v Power BI, který omezuje viditelnost dat pro jednotlivé uživatele nebo skupiny. Stejný report vidí různé uživatelé různá data na základě svého přístupu.
Typické případy použití
- Prodejci: Vidí pouze svůj prodej a svou geografickou oblast
- Manažeři: Vidí tým a jejich tým
- Vedení: Má přístup k celkovým datům
- Finanční oddělení: Vidí pouze svůj departement
- Klienti: Vidí pouze svá data v samoobslužném portálu
Statické vs Dynamické RLS
| Aspekt | Statické RLS | Dynamické RLS |
|---|---|---|
| Definice | Role s pevně zadanými hodnotami | Role na bázi funkce (USERNAME) |
| Údržba | Ruční změna role a přesign | Automatické dle uživatele |
| Škálovatelnost | Malá (desítky uživatelů) | Velká (tisíce uživatelů) |
| Komplexnost | Jednoduchá na kód | Vyžaduje LOOKUPVALUE a tabulky |
| Příklad | Region = "EMEA" | Region = LOOKUPVALUE(...) |
Statické RLS
Statické RLS je založeno na pevně definovaných rolích s konkrétními hodnotami. Je vhodné pro menší týmy nebo fixní struktury.
Příklad z kurzu: Role Staticka — filtr na kategorii produktu
Role Staticka v modelu kurzu omezí DimProduct na dvě kategorie — Bikes a Clothing. Uživatel přiřazený k této roli neuvidí komponenty ani příslušenství.
-- role Staticka — filtr na tabulku DimProduct DimProduct[Category] IN {"Bikes", "Clothing"}
Přiřazení uživatelů k rolím v Service
- Otevřete dataset v Power BI Service
- Klikněte na "⋯" menu → Security
- Vyberte roli (např. Staticka)
- Klikněte "Add members" a zadejte e-mail uživatele
Dynamické RLS
Dynamické RLS se přizpůsobuje na základě uživatele, který report otevírá. Používá funkce USERNAME() a USERPRINCIPALNAME
USERNAME() vs USERPRINCIPALNAME() — diagnostické míry
V modelu kurzu jsou dvě diagnostické míry, které vám ukáží, co RLS "vidí" za přihlášeného uživatele:
-- Vrací Windows login (DOMAIN\username nebo jen username) @ whoami = USERNAME() -- Vrací UPN / email (user@domain.com) -- Toto je preferovaný identifikátor pro RLS @ whoamiUPN = USERPRINCIPALNAME()
Dynamické RLS přes DimEmployee — role Dynamicka
Role Dynamicka v modelu kurzu filtruje DimEmployee tak, aby uživatel viděl pouze svůj řádek. Reseller sales jsou pak automaticky omezené přes relaci:
-- role Dynamicka — filtr na tabulku DimEmployee -- [LOGIN] = Windows login sloupec v DimEmployee DimEmployee[LOGIN] == username()
Protože FactResellerSales → DimEmployee existuje relace, filtr se automaticky propaguje do prodejů.
LOOKUPVALUE Pattern
LOOKUPVALUE umožňuje namapovat přihlášeného uživatele na hodnotu z tabulky. V kurzu máme reálnou tabulku security_mapping s columns Kategorie a Login.
Tabulka security_mapping
Tabulka obsahuje mapování: přihlašovací jméno uživatele → kategorie produktů, které smí vidět:
| Kategorie | Login |
|---|---|
| Bikes | user1@gopas.cz |
| Clothing | user2@gopas.cz |
| Bikes | user2@gopas.cz |
Přístup A: Filtr přes oboustrannou relaci
Role filtruje tabulku security_mapping na řádky s přihlášeným uživatelem. Přes oboustrannou relaci (both directions) se filtr propaguje na DimProduct[Category]:
-- role Dynamicka Mapping — Přístup A -- Filtr na tabulku security_mapping: security_mapping[Login] == USERPRINCIPALNAME() -- Relace mezi security_mapping a DimProduct: -- crossFilteringBehavior: bothDirections (M:N) -- DimProduct[Category] ← → security_mapping[Kategorie] -- Filtr se automaticky propaguje na DimProduct a dále na FactInternetSales
Přístup B: LOOKUPVALUE() přímo v RLS filtru
Alternativní přístup bez oboustranné relace — LOOKUPVALUE() vyhledá kategorii přímo z mapovací tabulky a vrátí ji jako filtr na DimProduct:
-- role Dynamicka LookupValue — Přístup B -- Filtr přímo na tabulku DimProduct (jednoduchý případ: 1 kategorie/uživatel): DimProduct[Category] == LOOKUPVALUE( security_mapping[Kategorie], security_mapping[Login], USERPRINCIPALNAME() )
Jak Dynamicka Mapping (Přístup A) funguje
USERPRINCIPALNAME()vrátí UPN přihlášeného uživatele (preferujte před USERNAME())- security_mapping se filtruje na řádky tohoto uživatele (může jich být víc)
- Přes oboustrannou relaci se filtrují kategorie v DimProduct
- FactInternetSales vidí pouze odpovídající produkty
Nastavení RLS v Power BI Desktop
Krok za krokem nastavení RLS v Power BI Desktop (před nasazením do Service).
Krok 1: Otevřete Modeling tab
V Power BI Desktop jdete do Modeling > Manage roles.
Krok 2: Vytvořte novou roli
- Klikněte na "Create Role"
- Zadejte jméno role (např. "EMEA", "Sales Rep")
- Klikněte OK
Krok 3: Přidejte filtry DAX
V levém panelu se zobrazí tabulky. Klikněte na tabulku, kterou chcete filtrovat (např. DimGeography).
Do pole "Table filter DAX expression" zadejte filtr:
DimGeography[Region] = "EMEA"
Krok 4: Přidejte více rolí (pokud třeba)
Opakujte postup pro dalších regiony nebo týmy.
Krok 5: Uložte soubor
Uložte soubor .pbix. RLS definice se v něm uloží.
Testování RLS
Testování je kritické. Power BI Desktop má vestavěný nástroj "View As" pro testování.
Testování v Desktop — View As
- V Modeling > Manage roles, klikněte na "View As"
- Vyberte roli, kterou chcete testovat (EMEA, Americas, ...)
- Zobrazí se report přesně tak, jak jej vidí uživatel v dané roli
- Ověřte, že se data správně filtrují
Testování dynamické RLS
Power BI Desktop umožňuje simulovat konkrétního uživatele přímo v dialogu View As — bez jakékoli úpravy dat:
- Jděte do Modeling > Manage roles > View as
- Zaškrtněte roli, kterou chcete testovat
- Zaškrtněte volbu "Other user" a zadejte testovací e-mail (UPN)
- Klikněte OK — report se zobrazí přesně tak, jak by jej viděl daný uživatel
Kontrolní seznam před nasazením
- Všechny role mají správné filtry?
- Testovali jste všechny role v "View As"?
- Ověřili jste, že vidíte správná data v každé roli?
- Zkontrolovali jste, že role "Admin" vidí veškerá data?
- Pokud máte dynamické RLS, existuje tabulka DimUserMapping?
Nasazení RLS do Power BI Service
Jakmile je RLS testováno v Desktop, publikujete report do Power BI Service a tam se přiřadí uživatelé k rolím.
Publikování
- V Power BI Desktop jděte na File > Publish
- Vyberte workspace a klikněte "Select"
- Report se publikuje s RLS definicemi
Přiřazení uživatelů v Service
- Otevřete report v Power BI Service
- Klikněte na tři tečky (...) v pravém rohu
- Vyberte "Security" (lock ikona)
- Klikněte na roli (EMEA, Americas, ...)
- Klikněte "Add members"
- Zadejte e-mail skupiny nebo uživatele
- Klikněte "Add"
Ověření přiřazení
Po přiřazení by měl uživatel vidět report s filtrovanými daty. Můžete si to ověřit:
- Otevřete report jako uživatel (pokud máte přístup)
- Ověřte, že vidíte pouze data ze své role
Uživatelé s rolí Admin, Member nebo Contributor v Power BI workspacu vidí veškerá data v sémantickém modelu bez ohledu na RLS. RLS je omezuje pouze uživatele s rolí Viewer.
Důsledek: Správce reportu, který má roli Member, uvidí automaticky všechna data — i ta, která by jinak byla skrytá. Pokud potřebujete, aby správce editoval report ale viděl jen svá data, musíte mu přidat přístup přes sdílený odkaz nebo aplikaci s rolí Viewer, ne přes workspace s rolí Member/Contributor.
Best Practices a Bezpečnostní chyby
Best Practice 1: Role "Admin"
Vždy vytvořte roli "Admin" bez filtrů, která vidí všechna data. Přiřaďte ji vedení nebo správcům:
-- Role: Admin (bez filtru - vidí všechny řádky) -- Žádný filtr v tabulkách
Best Practice 2: Testování s omezenými daty
Při vývoji testuji s menší datovou sadou, abych rychle ověřit RLS.
Best Practice 3: Dokumentace
Dokumentujte, která role co vidí. Příklad:
- EMEA: Vidí všechny regiony EMEA (ČR, SR, Německo...)
- Americas: Vidí Severní a Jižní Ameriku
- Admin: Vidí všechna data
Chyba 1: Zapomenutá role
Chyba: Vytvoříte role, ale některý uživatel není přiřazen k žádné roli.
Následek: Uživatel nevidí žádná data, i když by měl vidět.
Řešení: Vždy ověřte, že všichni uživatelé jsou přiřazeni k roli.
Chyba 2: Chybný filtr DAX
Chyba: Filtr je syntakticky chybný nebo odkazuje na neexistující sloupec.
-- Chybné - sloupec neexistuje DimGeography[NonExistentColumn] = "EMEA"
Řešení: Vždy zkontrolujte syntaxi a existence sloupců.
Chyba 3: Viditelná citlivá data bez RLS
Chyba: Zapomenete RLS aplikovat na důležitou tabulku.
Následek: Citlivá data jsou viditelná všem uživatelům.
Řešení: Mějte kontrolní seznam všech tabulek, které vyžadují RLS.
Chyba 4: Performance problém s LOOKUPVALUE
Chyba: LOOKUPVALUE je pomalý ve velkých mapovacích tabulkách.
Řešení: VertiPaq nepracuje s tradičními relačními indexy — nelze "přidat index" na sloupec. Výkon závisí na kardinalitě vyhledávacího sloupce a kvalitě komprese (Dictionary + RLE encoding). Udržujte mapovací tabulku malou (stovky řádků, ne miliony) a sloupec Login s nízkou kardinalitou (unikátní e-maily). Samotný LOOKUPVALUE v RLS filtru se vyhodnocuje jednou za dotaz — při rozumné velikosti tabulky je výkonnostní dopad zanedbatelný.
Chyba 5: Údaje unikají přes export nebo XMLA
Chyba: RLS je aplikován na tabulky, ale uživatel si může zobrazit podkladová data přes Export dat z vizuálu (funkce "Zobrazit jako tabulka" / export do CSV) nebo přes XMLA endpoint (přímé připojení k sémantickému modelu v Excelu, DAX Studio atd.), kde RLS stále platí, ale citlivé sloupce jsou viditelné.
Řešení: Pro ochranu na úrovni sloupců použijte Object-level Security (OLS) — omezí, které sloupce jsou vůbec přístupné. OLS je dostupné přes Tabular Editor a nevyžaduje Premium licenci.
Doporučené postupy
- Minimální přístup: Dávejte uživatelům pouze přístup k datům, která potřebují
- Pravidelný audit: Kontrolujte přiřazení rolí alespoň kvartálně
- Testování: Nové RLS vždy testujte v neproduktivním prostředí
- Soupisy: Vedete seznam, kdo má jakou roli a proč
- Kombinovaná bezpečnost: RLS v Power BI + zabezpečení na úrovni databáze
- Skupiny Azure AD: Používejte skupiny místo jednotlivých uživatelů, zjednodušuje správu