Power BI Row Level Security Implementation
One report that shows each person only their own slice of the data is the most requested Power BI feature after the first dashboard ships. Getting it right is less about the DAX filter and more about who sits in which workspace role.
A Power BI row level security implementation puts a filter on the semantic model itself, so the same published report returns different rows depending on who is signed in. A recruiter sees their own placements, a branch manager sees the branch, the owner sees the firm. Microsoft defines the rules as roles in Power BI Desktop, each one a DAX filter on a table, and you assign people or security groups to those roles in the Power BI service after publishing. That much is well documented. What the documentation leaves to you is the design decision in front of it: whether row-level security is the right tool at all, whether the roles should be static or dynamic, and which sharing paths quietly step around it.
This is the general guide. Our industry pages each describe the access pattern that business usually needs — producers and managers in insurance agencies, recruiters and branches in staffing agencies, partners and teams in accounting firms, regions and owner books in property management, and subsidiaries in a NetSuite integration. Read this page for the mechanics and the traps, then the one that matches your business for the shape of the roles.
Row-level security, separate reports or separate workspaces?
Use row-level security when many people need the same report with the same measures, and the only difference between them is which rows they may see. Use separate workspaces when audiences need genuinely different content, or when a group must never sit near another group's model. Separate copies of one report per audience are almost never the right answer past a handful of people.
The copy-per-audience approach usually starts innocently: a filtered version for the West branch, another for the East. Each copy carries its own semantic model or its own filters, every change to a measure has to be made several times, and within a few months the copies disagree. Worse, a report-level filter is not security. Anyone who can edit the report, or who receives a copy of the file, can remove the filter and see everything underneath.
Separate workspaces do enforce separation, because access is granted per workspace. They suit genuinely separate audiences — an external client portal, a board pack, a department whose data should not share a model with anyone else. They are the wrong tool for slicing one business by region or by person, because you end up duplicating the model to do it. One more distinction worth knowing: audiences in a Power BI app control which reports someone sees in the app's navigation, not which data they can query. They are a convenience, not a security boundary.
- Same report, different rows — row-level security on one semantic model
- Different content for a separate audience — a separate workspace, or a separate app
- Hiding whole columns or tables, such as salary or loaded cost — object-level security, alongside row-level security
- A filter on a report page — a usability feature, never a security control
| Approach | Best for | Maintenance as headcount grows | Main risk |
|---|---|---|---|
| Static row-level security roles | A few stable slices — regions, subsidiaries, departments | A model change and republish for every new slice | Role sprawl once the slice is the individual person |
| Dynamic row-level security | Per-person or per-manager access across many users | Add a row to the security table; no model change | The security table becomes data someone must own and keep current |
| Separate report per audience | A one-off view for one or two people | Every measure change repeated in every copy | Copies drift apart, and report filters are not security |
| Separate workspaces | Genuinely separate audiences or content, such as an external client | A separate model and permissions per workspace | Duplicated models and definitions when used to slice one business |
Static roles or dynamic roles once headcount grows
A static role hard-codes its filter: a role called West with the rule Region = "West", and the West team assigned to it. Static roles are easy to read, easy to test, and perfectly sound when the number of slices is small and stable — a few regions, a few subsidiaries, a few departments.
They stop scaling when the slice is the person. Twenty producers who each see their own book would need twenty roles, and every hire, departure or territory change means editing the model and republishing it. Dynamic row-level security replaces that with one role and a security table that maps each user's sign-in name to the entities they may see. The role's filter compares that table to USERPRINCIPALNAME(), the DAX function that returns the signed-in user's identity, and relationships carry the filter on to the fact tables. Adding a person becomes a row in a table, not a change to the model.
Hierarchies are where dynamic security earns its keep. A manager who should see everyone who reports to them, at any depth, can be handled with a parent-child path built using the PATH and PATHCONTAINS functions, so promotions and reorganisations flow through from the HR or CRM source without touching the roles. The cost is that the security table becomes data that has to be maintained, owned and refreshed like any other — decide who updates it, and from which system, before you build on it.
- Assign Microsoft Entra security groups to roles rather than individuals, so access follows group membership
- Keep the security table in a governed source, not in a spreadsheet one person edits
- Watch relationship direction: a filter that must travel across a many-to-many or bidirectional relationship needs the security filter applied in both directions
- Test every role with View as in Power BI Desktop and Test as role in the service before anyone relies on it
Workspace roles that bypass row-level security
Row-level security only restricts people who hold the Viewer role in the workspace, or who reach the content through sharing or an app. Microsoft's documentation is explicit that it does not apply to workspace Admins, Members or Contributors, because those roles carry edit permission on the semantic model. This is the most common leak we see in small businesses.
It happens for understandable reasons. A workspace is created, the team is added as Members so everyone can get started, and row-level security is added later. Every one of those Members still sees every row, and the test that would catch it — opening the report as a restricted user — is usually run by the person who built it, who is an Admin and sees everything anyway. The fix is structural: keep report builders in one workspace, publish to the audience through an app or Viewer access, and give edit roles only to people who are entitled to see the whole dataset.
Three other paths deserve a check. Publish to web makes a report public with no sign-in and no security at all; it should be disabled at tenant level for any business with confidential data. Anyone with edit rights on the model can see and change the roles themselves. And a user given Build permission on a secured model can create new reports on it — row-level security still applies to them, but confirm that the roles are what you think they are before handing that permission out widely.
What sharing one secured report widely does to licensing
Row-level security makes it tempting to publish one report to the whole company, and that changes the licensing bill. On shared capacity, and on Fabric capacities from F2 through F32, everyone who views shared Power BI content needs a Pro or Premium Per User license of their own. Row-level security does not change that: a restricted viewer is still a viewer.
On an F64 or larger Fabric capacity, or a Power BI Premium P capacity, people with only a free license can view content shared with them, and row-level security filters what they see in the normal way. That is the threshold where one secured report for a large free-licensed audience starts to make financial sense. Below it, compare the cost of per-user licenses for everyone who will open the report against the capacity, and remember that people who build and publish content need Pro or Premium Per User on every option. Take current list prices from Microsoft's pricing page or your reseller on the day you buy; we cover the wider budget in Power BI implementation cost for small business.
How we implement it
We start with the access map, not the DAX: who should see what, which system is the source of truth for that, and how it changes when someone joins, moves or leaves. From that we choose static or dynamic roles, build the security table and roles in the semantic model, restructure workspace roles so nobody with edit rights is outside the intended audience, and test every role as a real restricted user before the report goes out.
The work is led by Edward Pinela, MBA, a principal consultant in business intelligence — the person who scopes it is the person who builds it. Securing an existing model is a bounded job, and Power BI Flex Support is usually the right vehicle: it starts at $2,500 for 20 hours at $100–$125 per hour, in prepaid blocks whose hours do not expire. If security is part of a new reporting build, it belongs in the scope of our Power BI consulting services engagement from day one.
Further reading: Microsoft Learn — row-level security (RLS) with Power BI.
Not sure if this is the right fit?
Book a free 30-minute call with Edward Pinela, MBA. If it is not the right fit, you will be told that on the call.
Frequently asked questions
Does row-level security apply to workspace Admins and Members?
No. Microsoft states that row-level security only restricts users with Viewer permissions; it does not apply to workspace Admins, Members or Contributors, because they can edit the semantic model. Anyone who must see a restricted slice should reach the report as a Viewer, through an app, or through sharing — never through an edit role.
When should we switch from static to dynamic roles?
When the slice is the individual person, or when roles change often enough that republishing the model is a chore. Dynamic security uses one role, a security table mapping each user to what they may see, and the USERPRINCIPALNAME() function, so adding a person becomes a data change rather than a model change.
Do free-license users see row-level security filtered reports?
Only where free users can view at all. On shared capacity and Fabric F2 to F32, every viewer needs a Pro or Premium Per User license. On F64 or larger, or a Premium P capacity, free-license users can view shared content, and row-level security filters it for them in the same way as for licensed users.
Are Power BI app audiences a security feature?
No. App audiences decide which reports and pages appear in the app for each group, which keeps navigation tidy. They do not restrict the data a person can query from the underlying semantic model. Use row-level security for rows and object-level security for columns or tables; use audiences only to organise what people see.
How do we test row-level security before go-live?
Use View as in Power BI Desktop and Test as role on the semantic model in the Power BI service, checking each role against a user you know. Then have a real restricted user open the published report, because the builder is usually an Admin and sees every row regardless of the roles.
Talk it through with a senior consultant
Book a free 30-minute call with Edward Pinela, MBA. No obligation and no sales pitch — just an honest read on whether this is the right fit.
Prefer to call? +1 (714) 872-9606