Study Guide
Row-Level Security in Power BI: Static vs Dynamic, With a Walkthrough
By Dr. Rosario Feghali · August 21, 2026 · 8 min read
Row-Level Security is one of those PL-300 topics that quietly appears in two different exam domains — modeling and deployment — which means candidates who treat it as a footnote usually lose more points than they expect. I have watched otherwise well-prepared students get tripped up by a scenario question that asks them to choose between static and dynamic RLS, simply because they never built one themselves. This post walks through both, with a model you can reproduce in Power BI Desktop in about fifteen minutes.
What RLS actually restricts
Row-Level Security controls which rows of data a user can see when they open a report — not which pages, not which visuals, rows. It is enforced inside the semantic model itself, so it applies no matter how the user gets to the data: a report page, Q&A, Analyze in Excel, a live connection from another workbook. That's the detail the exam likes to test — RLS is a modeling-layer control, not a report-layer one.
There are two ways to build it, and the difference comes down to one question: does the filter value live in a role definition, or does it come from the identity of whoever is logged in?
Static RLS: filters baked into the role
Static RLS means you write the filter condition directly into a security role, using a fixed value.
In Power BI Desktop: Modeling → Manage Roles → Create. Say you have a Sales table with a Region column. You'd create a role called East Region and give it this table filter (a DAX expression that must evaluate to TRUE/FALSE per row):
[Region] = "East"
Any user assigned to the East Region role, once published to the Power BI Service and mapped to that role under workspace security, only ever sees rows where Region equals "East". If you have five regions, you create five roles — one per region, each with its own hardcoded filter.
Static RLS is simple to build and easy to reason about, which is exactly why it doesn't scale. Fifty regions means fifty roles, and every new region means a model change and a redeploy. It's the right choice for a small, stable number of groups — a handful of departments or business units — not for anything with per-user or frequently-changing membership.
Dynamic RLS: the filter comes from the logged-in user
Dynamic RLS replaces the hardcoded value with a function that resolves to whoever is currently viewing the report: USERPRINCIPALNAME(). This returns the email address (or UPN) of the signed-in user in the Power BI Service.
The standard pattern uses a mapping table — a table that says which user is allowed to see which value — related to your fact table:
UserRegionMapping
| Email | Region |
|-------------------------|--------|
| priya@contoso.com | East |
| daniel@contoso.com | West |
| priya@contoso.com | Central|
Note Priya appears twice — dynamic RLS handles many-to-many membership without extra roles. Relate UserRegionMapping[Region] to Sales[Region], then define one role (not one per region) with a filter on the mapping table:
[Email] = USERPRINCIPALNAME()
Power BI evaluates this per user at query time: it filters UserRegionMapping down to the signed-in user's row(s), and the relationship propagates that filter through to Sales[Region]. Add a new employee, and you add a row to the mapping table — no new role, no republish of the model's logic.
This is why dynamic RLS is the default recommendation for anything beyond a handful of fixed groups: the security logic lives in data, not in redeployed roles.
A five-minute walkthrough
- Build a simple star schema:
Sales(fact) with aRegioncolumn, related toUserRegionMapping(a small table you type in manually with Enter Data) onRegion. - Go to Modeling → Manage Roles → Create Role, name it
Regional Access. - Select the
UserRegionMappingtable and set its filter to[Email] = USERPRINCIPALNAME(). - Use Modeling → View As and check "Other user," typing in one of the emails from your mapping table. Confirm the report now only shows that user's region.
- Publish to the Service. Under the workspace's dataset settings, go to Security, select the
Regional Accessrole, and add the actual Microsoft Entra ID accounts or security groups that should be enforced under it.
Step 4 is the one candidates skip in practice and then get wrong on the exam — "View As" is how you validate RLS before publishing, and it's a named feature the exam expects you to recognize.
Common exam traps
- RLS does not apply to the report author or workspace Admins/Members/Contributors by default when they view the report inside the workspace — only Viewers, or anyone accessing through an app, get the role enforced normally. This surprises people testing their own RLS setup.
- RLS filters propagate one-directional relationships correctly, but if you have a bidirectional relationship in the wrong place, the filter can leak further than intended, or fail to reach a table it should. Know your relationship directions before you add security on top.
USERPRINCIPALNAME()vsUSERNAME()— the exam sometimes offers both as distractors. UseUSERPRINCIPALNAME()for the Power BI Service (it returns the UPN/email used for sign-in);USERNAME()behaves differently depending on context and is not the standard choice for Service-based RLS.- Object-Level Security (OLS) is a related but separate concept — it hides entire tables or columns, not rows, and is configured with external tools (like Tabular Editor), not the built-in Manage Roles dialog. If a question asks about hiding a whole column from a group, that's OLS, not RLS.
Static or dynamic — how to decide
Ask how many distinct groups you're securing, and how often membership changes. A handful of stable groups (three regional managers who never change) is a legitimate case for static roles — it's less setup than building a mapping table for something that will never need one. Anything with per-user permissions, frequent membership changes, or more than a small fixed number of groups should be dynamic. On the exam, watch for the word "hundreds" or "individual users" in a scenario — that's Microsoft signaling dynamic RLS is the expected answer.
Want to build RLS models like this with feedback from an MCT?
Gyromitra's PL-300 membership pairs the full self-paced course with a live weekly Q&A with a Microsoft Certified Trainer — bring your own RLS model and we'll work through it together. Join anytime, no cohort to wait for.