Blog / Power BI

Row-level security that survives a reorg

Most RLS breaks the first time the org chart changes. Here is how to build it so a restructure is a data update, not a redesign.

Row-level security is easy to demo and hard to live with. The version most teams ship hard-codes who sees what, and the first reorg, a new region, a merged team, a transferred patch, quietly breaks it. The fix is to stop encoding the structure in roles and start driving it from data.

Static roles are a trap

Static RLS defines a role per group and a filter per role. It works on day one. The problem is that every change to the organisation means editing roles in the model and republishing. In housing, where patches, contractors and teams reshuffle constantly, that is a standing maintenance cost you signed up for without noticing.

Under the hood, RLS evaluates a DAX expression that returns true or false for each row, and only the rows that return true stay visible. Static roles bake the membership into that expression. Dynamic roles look it up instead.

Drive it from a mapping table

Dynamic RLS uses the signed-in user’s identity to find them in a security table, then filters the data by whatever that table says they can see. The role never changes. When someone moves team, you update one row in the mapping table, not the model.

DAX role filter
[Patch] IN
    SELECTCOLUMNS(
        FILTER(
            UserPatch,
            UserPatch[Email] = USERPRINCIPALNAME()
        ),
        "Patch", UserPatch[Patch]
    )

Now a reorg is a data task. The mapping table can be maintained outside the model, in the warehouse or a simple managed list, so the people who own access do not need to open Power BI Desktop at all.

Test it the way it will fail

Use View as role on the Modeling ribbon to check filters before publishing, and measure the cost with Performance Analyzer, because RLS filters add query work and a heavy mapping relationship can slow every visual. Map security groups to roles rather than individuals wherever you can, so membership is managed once, centrally.

The BaseData take
1 If your structure changes more than once a year, go dynamic from the start. Retrofitting it later is harder than building it in.
2 Keep the mapping table outside the model. Access changes should not need a republish.
3 Always test with View as, and watch the performance cost of the security relationship before it reaches production.

RLS should be invisible. Build it so the next reorg is a row in a table, and it will be.

Power BIRLSGovernanceSecurity
Get in touch

Let's make your housing data make sense.

Tell us where your reporting hurts. We'll tell you, plainly, whether we can help and how we'd approach it.