GOC644 — DAX základy (2 dny)
1. Úvod do Power BI 2. Datový model 3. Úvod do DAX 4. Oblasti použití DAX 5. Kontext výpočtu 6. Časová inteligence 7. Optimalizace DAX 8. Row Level Security 9. Nástroje
GOC6441 — Pokročilý DAX (2 dny)
1. Opakování & přehled 2. Dynamické reporty 3. DAX jako dotazovací jazyk 4. VertiPaq engine 5. Ladění výkonu 6. Composite Models 7. Workshop
Cvičení
1. Datový model 2. DAX základy 3. Kontext výpočtu 4. Časová inteligence
🏠 Rozcestník kurzů
GOC644 · Kapitola 8

Zabezpečení dat a Row Level Security

Ochrana citlivých dat — statické a dynamické RLS, delegované přístupy
⏱ 55 minut🗂 Kapitola 8

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
8.1

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(...)
⚠️
RLS je kritické bezpečnostní opatření. Špatná implementace může vést k úniku dat. Vždy testujte důkladně!
8.2

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í.

TMDL (definice role)
-- role Staticka — filtr na tabulku DimProduct
DimProduct[Category] IN {"Bikes", "Clothing"}
ℹ️
Proč filtr na DimProduct? Power BI propaguje filtr přes relace — filtr na DimProduct[Category] automaticky omezí i FactInternetSales, FactResellerSales atd. Nemusíte filtrovat každou tabulku zvlášť.

Přiřazení uživatelů k rolím v Service

  1. Otevřete dataset v Power BI Service
  2. Klikněte na "⋯" menu → Security
  3. Vyberte roli (např. Staticka)
  4. Klikněte "Add members" a zadejte e-mail uživatele
⚠️
Jeden uživatel může být přiřazen více rolím. V tom případě vidí sjednocení dat všech rolí (logický OR).
8.3

Dynamické RLS

Dynamické RLS se přizpůsobuje na základě uživatele, který report otevírá. Používá funkce USERNAME() a USERPRINCIPALNAME

📝
Na blogu Jiřího Neorala: Different approach to Dynamic Row Level Security — alternativní přístup k Dynamic RLS — real-world pattern (anglicky)
().

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:

DAX
-- 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()
💡
Tip: Přidejte tyto míry do reportu během vývoje. Umožní vám ověřit, jaký identifikátor Power BI Service vrací pro konkrétní uživatele — základ pro ladění RLS.

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:

TMDL (definice role)
-- 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ů.

8.4

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:

KategorieLogin
Bikesuser1@gopas.cz
Clothinguser2@gopas.cz
Bikesuser2@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]:

TMDL (definice role)
-- 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:

TMDL (definice role)
-- 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()
)
ℹ️
Přístup A vs B: LOOKUPVALUE v RLS (přístup B) je vhodný, pokud má každý uživatel přesně jednu povolenou hodnotu. Pokud má uživatel více povolených kategorií (jako v naší tabulce user2@gopas.cz), je nutný přístup A přes mapovací tabulku a oboustrannou relaci, která propaguje celý set hodnot.

Jak Dynamicka Mapping (Přístup A) funguje

  1. USERPRINCIPALNAME() vrátí UPN přihlášeného uživatele (preferujte před USERNAME())
  2. security_mapping se filtruje na řádky tohoto uživatele (může jich být víc)
  3. Přes oboustrannou relaci se filtrují kategorie v DimProduct
  4. FactInternetSales vidí pouze odpovídající produkty
⚠️
Oboustranná relace (Both Directions): Používejte opatrně — může způsobit neočekávané ambiguity ve filtru. Vhodná pro RLS, ale v obecném modelu ji raději nahraďte jednosměrnou relací + explicitním CROSSFILTER v mírách.
8.5

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

  1. Klikněte na "Create Role"
  2. Zadejte jméno role (např. "EMEA", "Sales Rep")
  3. 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:

DAX
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ží.

✓
RLS se definiuje v Power BI Desktop. Když publikujete report do Service, role se publikují spolu s ním.
8.6

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

  1. V Modeling > Manage roles, klikněte na "View As"
  2. Vyberte roli, kterou chcete testovat (EMEA, Americas, ...)
  3. Zobrazí se report přesně tak, jak jej vidí uživatel v dané roli
  4. 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:

  1. Jděte do Modeling > Manage roles > View as
  2. Zaškrtněte roli, kterou chcete testovat
  3. Zaškrtněte volbu "Other user" a zadejte testovací e-mail (UPN)
  4. Klikněte OK — report se zobrazí přesně tak, jak by jej viděl daný uživatel
⚠️
Nikdy neupravujte data kvůli testování! "Dočasná" změna e-mailů v tabulce je nebezpečný workaround — hrozí risk, že se změna dostane do produkce. Vždy použijte "Other user" v dialogu View As.

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?
⚠️
Chyba v RLS se může projevit až v produkci. Vždy testujte důkladně před nasazením!
8.7

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í

  1. V Power BI Desktop jděte na File > Publish
  2. Vyberte workspace a klikněte "Select"
  3. Report se publikuje s RLS definicemi

Přiřazení uživatelů v Service

  1. Otevřete report v Power BI Service
  2. Klikněte na tři tečky (...) v pravém rohu
  3. Vyberte "Security" (lock ikona)
  4. Klikněte na roli (EMEA, Americas, ...)
  5. Klikněte "Add members"
  6. Zadejte e-mail skupiny nebo uživatele
  7. 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:

  1. Otevřete report jako uživatel (pokud máte přístup)
  2. Ověřte, že vidíte pouze data ze své role
ℹ️
Pokud máte skupinu v Azure AD (Entra ID), je lepší přiřadit skupinu místo jednotlivého uživatele. Zjednodušuje to správu.
🔴
Kritické: Workspace role obcházejí RLS!
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.
8.8

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:

DAX
-- 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.

DAX (ŠPATNĚ)
-- 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.

⚠️
Bezpečnostní varování: RLS je pouze filtr na úrovni Power BI. Pokud je databáze přímě přístupná, data mohou uniknout. Kombinujte RLS s databázovým zabezpečením!

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