skip to content

In Power BI Desktop, how do you check what an RLS role sees before publishing?

level: juniorimportance: should knowfreq 42%

answer

  1. you can render the report as somebody else
  2. the role alone is not enough when dynamic
  3. type the UPN the function will return
  4. check the user who is in no mapping row
  5. Desktop cannot test workspace permissions

basics

~20 s

Use Desktop's View as feature to render the report under a chosen role, and for dynamic RLS also as another user by typing their UPN. After publishing, the semantic model's security page in the Power BI Service can test the report as a role.

solid answer

~40 s

In Power BI Desktop, **View as** re-renders every visual as if a chosen role were applied, and a banner shows which role is active until you stop. For dynamic RLS you also tick **Other user** and type a UPN, which is what `USERPRINCIPALNAME()` will return during the test — that is how you verify the entitlement table without borrowing an account. After publishing, the semantic model's security settings in the Service let you test the report as a role. Test three cases at minimum: a user with several permitted keys, a user with exactly one, and someone missing from the mapping table, who should see nothing rather than everything. Remember Desktop tests the model's filters only; it cannot tell you that a consumer with workspace edit rights will bypass RLS entirely.

code

text · 9 lines
text
Test matrix for a dynamic RLS role

 user                 expected regions   expected total
 ------------------   ----------------   --------------
 [email protected]         1, 2               128,400
 [email protected]          3                   41,900
 [email protected]    (none)               0 / no rows

Repeat each row against EVERY fact table in the model.

go deeper

for a junior

Know that Power BI Desktop can render the report as a role, and that dynamic RLS also needs a user name typed in so the identity function has something to return.

for a middle

Explain why roles are additive, why the entitlement table must be exercised with a real UPN, and why the Service test after publishing catches things Desktop cannot.

for a senior

Bring a test matrix: several keys, one key, no keys, every fact table, exact expected totals, and post-refresh timing — plus awareness that workspace edit rights void the whole exercise.

for a principal

Push for RLS assertions in the release pipeline rather than manual clicking, so a model change that breaks propagation fails a deployment instead of quietly widening access.

## Why testing is a named step RLS is the one part of a Power BI model whose failure is silent and expensive: a mis-propagated filter shows *more* data, and nothing on the page says so. Nobody in the report sees an error; the number is simply too big. So verifying a role is not a nicety, it is the acceptance test for the feature. ## Testing in Power BI Desktop Desktop's **View as** renders the whole report as though the selected role's filters were applied. The report re-queries, the visuals shrink to the permitted rows, and a coloured banner tells you which role you are simulating so you cannot forget you are in it. You can select more than one role at once, which is important because **roles are additive**: a user in two roles sees the union of what each role permits, not the intersection. For dynamic RLS the role alone is not enough — the filter depends on the identity, so Desktop lets you supply **Other user** with a UPN. That string becomes what `USERPRINCIPALNAME()` returns while the simulation is active, so the entitlement table is exercised exactly as it will be in production. You must still tick the role as well; supplying a user without the role does nothing, because it is the role that carries the filter. ## Testing in the Power BI Service After publishing, the semantic model's security page lists each role and its members, and lets you view the report as that role. This is worth doing even after a clean Desktop test, because the Service is where the real identity, the real membership and the real refreshed entitlement data come together. Desktop tested the *logic*; the Service tests the *deployment*. ## What to actually test A useful minimum set: 1. **A user with several permitted keys** — confirms the union works and does not silently pick one row. 2. **A user with exactly one key** — confirms the numbers match a hand-calculated figure. Have the expected total ready from the source before you look. 3. **A user absent from the entitlement table** — should see no rows, not all rows. If they see everything, the filter is not propagating. 4. **Every fact table on its own visual** — this is where propagation gaps hide. A second fact table added last sprint, or a table with an inactive relationship, will still show unrestricted totals while the main page looks correct. 5. **A grand total, not just a detail table** — the total is computed from the permitted rows, so comparing it against a known per-user figure is the cheapest leak detector you have. ## What the simulation cannot tell you View as tests the **model's filters**. It knows nothing about the permissions layer above them, and two production failures live there. First, a user with edit rights on the workspace — Admin, Member or Contributor — is not subject to RLS at all, so a perfectly tested role protects nothing if consumers were given the wrong workspace role. Second, membership: Desktop holds no members, so a role that filters correctly may simply have nobody, or the wrong Entra group, assigned to it in the Service. It also cannot tell you that a permission change has been picked up: in an import model the entitlement rows are as of the last refresh, so test after refreshing rather than before. ## Automating the check Beyond manual clicking, the model can be queried under an identity through the XMLA endpoint, which makes it possible to run a small suite of expected-total assertions as part of a deployment pipeline. That is the mature version of the same idea: for a set of known users, the model must return exactly these totals. It is worth mentioning in an interview because it turns a manual, forgettable step into a regression test that survives the next model change.

  • Why must you supply a user name and not only a role when testing dynamic RLS?
    The role's filter is an equality against `USERPRINCIPALNAME()`. With no simulated identity there is nothing to compare against, so the test is meaningless. Supplying the UPN makes the function return that value during the simulation, exercising the entitlement table exactly as production will. The role must still be selected, because the role is what carries the filter expression.
  • What result should a user who appears in no entitlement row see, and why does it matter?
    No rows at all — an empty visual or zeroed totals. That is the safe failure direction: a missed onboarding looks like a broken report and gets reported, whereas the opposite failure, showing everything, is silent. If an unmapped user sees the full dataset, the filter is not reaching the fact table and the model is leaking.
  • You tested one page and it was correctly restricted. Why is that not enough?
    RLS is filter propagation, so it is per-relationship, not per-report. A second fact table with a missing or inactive relationship, or a disconnected helper table, stays unrestricted while the tested page looks perfect. Put every fact table on a scratch page and check its total under a test identity before you sign off.

saying these in an interview costs you the question

  • Testing only the role and never a specific user
  • Checking one page and declaring the model secure
  • Believing Desktop's simulation also validates workspace permissions
  • Verifying that data appears rather than comparing exact totals
  • Never testing a user who is in no mapping row

context