Home/Insights/Data Governance · Power BI
Data Governance · Power BI

Row-Level Security Looks Simple. That's How It Fails.

SD

Shauna Duffy

Data Engineering Lead

August 2026·8 min read
Row-Level Security Looks Simple. That's How It Fails.

Row-level security is easy to demo and easy to get quietly wrong in production. Here is how RLS actually behaves at scale, where teams get caught out, and how to test it properly before real users see the wrong rows.

Row-level security demos beautifully. Build two roles, log in as each one in Power BI Desktop’s “View as Roles” panel, watch the numbers change, ship it. Production is a different environment, and it exposes the gaps that a five-minute demo never will.

RLS in Power BI is enforced inside the semantic model, which means it is only as good as the DAX filter expressions and the table relationships behind it. Get either wrong and the failure mode is not an error message. It is a user quietly seeing rows they should never have seen, or seeing nothing at all and assuming the report is broken.

The demo lies. Production tells the truth.

View as Roles checks whether the DAX expression evaluates correctly for a role you built. It does not check what happens when a real user belongs to two roles at once, when a user matches zero rows and gets a blank report with no explanation, or when a manager’s role is supposed to see their team’s data but the org hierarchy table has a gap in it. Those are the failures that show up in week three, not in the demo.

Static versus dynamic RLS is a design decision, not a checkbox

Static RLS hardcodes each role’s filter in DAX, one role per team or region. It is simple to reason about and simple to test, but it does not scale past a few dozen roles without becoming its own maintenance project. Dynamic RLS filters based on the logged-in user’s identity against a permissions table, so one set of rules covers everyone. It scales, but the permissions table becomes as sensitive as the data it protects, and it needs the same change control as any other part of the model.

Test it like an attacker, not like the developer who built it

Before rollout, test with a real account for every role, not just View as Roles inside Desktop, because the service can behave differently once a report is published and shared. Deliberately create the edge cases: a user in two roles, a user in no role, a role whose filter returns zero rows. Check what each one actually sees, not what you expect them to see.

Workspace roles are not a substitute for RLS

Workspace roles decide who can view, edit or manage a workspace. They say nothing about which rows within a table a given person can see once they have access. We still see reports where a workspace has been locked down carefully at the folder level while the underlying semantic model has no RLS at all, meaning anyone with workspace access sees every row. The two controls solve different problems and you need both.

What this means for you

RLS is a good pattern, and it is not a substitute for thinking through who should see what before you build it. Test with real accounts, choose static or dynamic deliberately rather than by default, and keep workspace access and row-level security as two separate decisions rather than one. If you would like a second pair of eyes on your current RLS setup, get in touch.

SD

Shauna Duffy

Data Engineering Lead

Part of the Hopton Analytics team, delivering governed analytics programmes for UK mid-market organisations.

FAQs

Frequently asked questions

Get started

Ready to put this into practice?

Reading about better analytics is a start. Working with us is how it happens.

Book a free analytics audit