Power BI Row-Level Security: How to Design, Implement and Govern RLS in 2026
- 30 min read
- on November 15, 2026
- by Gaurav Verma
TL;DR
Power BI row level security filters semantic-model rows per signed-in user, and dynamic RLS on a governed mapping table suits most enterprises. Choose static roles only when a handful of fixed groups rarely change. Roles hold DAX filters, members come from Microsoft Entra ID security groups, and every query a report sends is filtered. The catch is scope: RLS binds only workspace Viewers, so Admins, Members and Contributors see every row. It also filters rows, not columns, which is the job of object-level security. Then give the mapping table an owner, test with real identities and recertify access every quarter.
Key Takeaways
- RLS applies DAX filters to a semantic model, so each user sees only the rows their role allows.
- It binds workspace Viewers only, while Admins, Members and Contributors bypass it, even inside the same report.
- Dynamic RLS with USERPRINCIPALNAME and a mapping table scales to thousands of users, because one role serves everyone.
- Roles are additive, so a user in two roles sees the union of both filters.
- RLS secures rows; pair it with object-level security when whole columns or tables are sensitive.
- Govern the mapping table like financial data: a named owner, change control and quarterly recertification.
Watch on YouTube
Boosting Financial Efficiency with Power BI | Advanced Data Analytics
See how finance teams use Power BI dashboards to analyze cost and performance, the kind of shared report where row-level security decides which entity each viewer can see.
When a Regional Report Shows Another Region’s Revenue
Picture the Monday sales review. When the East regional manager opens the quarterly revenue report, she sees East numbers only, exactly as designed. Down the hall, though, a new analyst opens the same report and sees every region, including the West pipeline that leadership had not yet shared.
Nothing in the DAX was wrong. The analyst had been added to the workspace as a Member to fix a broken visual, but Members are not filtered by row-level security. The report looked secure because it worked for the people it was tested with.
That gap between “RLS is on” and “the right people see the right rows” is what this guide closes. It covers what RLS does, how to choose a design, and how to build, test and govern roles across an enterprise.
Updated November 2026 to reflect current Microsoft Learn guidance on Direct Lake, B2B guest users and Microsoft Entra ID naming.
What Is Power BI Row Level Security?
Power BI row level security is a filter that decides which rows of a semantic model each user can read. You define it once in the model, and it applies to every report, dashboard and app built on that model. The user never sees a filter pane for it, so they cannot switch it off.
The design has three parts. A role is a named container, such as a Regional Sales role. A rule is a DAX expression on a table that returns true or false for each row, so only rows that return true stay visible. Members are the users or groups assigned to the role in the Power BI service, which in practice means Microsoft Entra ID security groups.
For example, a role called “East Sales” carries the rule [Region] = "East" on the Region table. When an East sales rep opens the revenue report, every visual, total and drill-through is calculated over East rows only. The fact table is filtered too, because the Region filter flows through the model’s relationships.
According to Microsoft’s row-level security documentation, RLS works on Import and DirectQuery models. Live connections to Analysis Services work differently, since security is defined in the source model, not in Power BI.
What RLS Protects and What It Leaves Open
RLS is precise about rows but silent about almost everything else. Knowing its limits up front saves a painful audit finding later.
- It protects: rows in the semantic model, for users in the Viewer workspace role or users who receive the content through an app or a share.
- Columns and tables stay visible. Hiding them is the job of object-level security (OLS).
- Opening a workspace or report is a separate check. Workspace roles and item permissions decide that.
- Admins, Members and Contributors are never filtered. They see all rows by design, because they can edit the model.
- Service principals fall outside it. A service principal cannot be an RLS member, so RLS is not applied when it is the final effective identity.
In other words, RLS is one layer in a stack. The next section shows where it sits in that stack and which layer answers which question.
Where RLS Sits in the Power BI and Fabric Security Model
Think of Power BI security as a set of doors, each answering a different question. Workspace roles decide who gets into the building. Item permissions then decide which rooms they can enter, while RLS decides which papers on the desk they can read.
The confusion starts when teams expect one layer to do another layer’s job. A team might lock rows with RLS, then give a contractor the Contributor role so they can publish fixes. That contractor now sees everything, because the workspace role sits above the row filter.
| Layer | What it controls | Who it binds |
|---|---|---|
| Workspace roles (Admin, Member, Contributor, Viewer) | Access to every item in the workspace and the right to edit or publish | Everyone given a role in the workspace |
| Item and Build permission | Opening a specific report or app, and building new content on a semantic model | Users who receive an item, an app or a share |
| Row-level security (RLS) | Which rows of the semantic model a user can query | Viewers and app or share recipients; not Admin, Member or Contributor |
| Object-level security (OLS) | Whether a table or column exists at all for the user | Same audience as RLS |
| SQL analytics endpoint RLS | Rows returned by T-SQL queries against a lakehouse or warehouse | Users querying through the endpoint |
| OneLake security | Access to lakehouse data in OneLake | Users and engines reading OneLake data |
| Sensitivity labels | Classification and protection that travels with content and exports | Anyone handling labeled content |
Reading the Layers in Order
When you read the table from top to bottom, the order of checks becomes clear. A user who fails the workspace check never reaches the row filter, while a user who holds an editing role skips it entirely. Microsoft’s Fabric permission model describes the same layering for every Fabric item.

Column protection, however, works differently. Object-level security secures specific tables or columns from report viewers, so a salary column can disappear for most users while rows stay filtered by region. Many enterprise models need both. Both live in model roles, but keep each user’s RLS and OLS in the same role, because combining them across different roles raises an error at query time.
The Viewer-Only Rule: Why Admins, Members and Contributors See Everything
This single rule causes more data exposure than any DAX mistake. Microsoft states it plainly: RLS roles apply to members assigned the Viewer role in the workspace. Admins, Members and Contributors are not filtered, because they can edit the model and could remove the rule anyway.
The rule also cuts the other way. A Viewer who holds Build permission on the semantic model is still filtered, and that includes queries from Analyze in Excel. So you can let business analysts build their own reports on a secured model without handing them every row.
The practical fix is structural. Keep report consumers in the Viewer role or give them access through an app. Then keep editing roles for the small team that maintains the model. When someone needs to “just fix one visual,” give them a development workspace instead of a Member seat in production.
Static, Dynamic and Source-Level RLS: The Options Compared
There are four ways to filter rows for Power BI users, and the real difference is who maintains the access list. Static RLS keeps it inside role definitions, so every change touches the model. Dynamic RLS moves it into a table, CUSTOMDATA hands it to the embedding application, and source-level RLS leaves it in the database.
A short example shows the difference. Say a company has five regions. Static RLS then needs five roles, one per region, each with a fixed value. Dynamic RLS instead needs one role and a mapping table that pairs each user’s email with a region. When the company opens a sixth region, static RLS needs a model change, while dynamic RLS needs one new row.
| Option | How it filters | Best for | Upkeep | Watch-outs |
|---|---|---|---|---|
| Static RLS | One role per value, with a fixed DAX filter such as [Region] = “East” | A few stable groups | A model change for every new group | Role sprawl; users in two roles see both sets of rows |
| Dynamic RLS (USERPRINCIPALNAME) | One role; the rule matches the signed-in user’s UPN against a mapping table | Per-user territories, hierarchies, large user bases | Data updates to the mapping table | UPN format must match exactly; the mapping table needs an owner |
| CUSTOMDATA (embedded) | The app passes a value in the embed token, and the rule reads it with CUSTOMDATA() | Apps that embed reports for their own customers | Application code | The app can pass any value, so test unexpected ones |
| Source-level RLS | The database filters rows, for example an Azure SQL security policy read through DirectQuery with single sign-on | Sources that already enforce row security | Database administration | Performance and connectivity depend on the source |
When the Database Should Hold the Rules
SQL Server and Azure SQL have supported row-level security since SQL Server 2016, using CREATE SECURITY POLICY with inline table-valued predicate functions. When those policies already exist, a DirectQuery model with single sign-on can pass the user’s identity through and let the database filter. For the Fabric side of that pattern, see our guide to warehouse-level security with T-SQL.
For a semantic model that serves many reports, though, dynamic RLS is usually the cleaner home. It keeps access logic next to the business model, so it travels with the model through deployment. It also works the same way in Import, DirectQuery and Direct Lake.
Kanerika Service
Power BI Consulting and Implementation
Kanerika designs secured Power BI semantic models, from dynamic RLS and object-level security to deployment pipelines and governed access, as a Microsoft Solutions Partner for Data and AI.
Explore Power BI ServicesDecision Framework: Choosing a Power BI Row Level Security Design
The shape of your access rules decides the right RLS design, while company size matters far less. For example, a firm with 10,000 users and five fixed regions can live happily with static roles. A 300-person distributor with territories that change monthly needs dynamic RLS from day one.
Start by writing down who should see what in plain English, then match each sentence to a row below. Most enterprises then settle on dynamic RLS as the base, plus one or two special cases layered on top.
| Scenario | Pick | Why |
|---|---|---|
| Under five fixed groups that rarely change (for example, two business units) | Static RLS | Simple to read and test, since the role list stays short |
| Per-user sales territories that change often | Dynamic RLS with a user-to-territory mapping table | Territory changes become data updates rather than model releases |
| Managers see their own team and everyone below them | Dynamic RLS with PATH functions | The hierarchy lives in data, so it follows reorganizations |
| Franchise or branch finance, where each branch sees only its own ledger | Dynamic RLS on the branch dimension | One role covers every branch, while head office gets an “all branches” row |
| Healthcare provider panels with sensitive columns | Dynamic RLS plus OLS | Rows filter by provider panel, while OLS hides identifying columns |
| Software vendor embedding reports for many customer tenants | Workspace isolation with service principal profiles, then RLS inside each tenant | Microsoft’s recommended pattern for large multi-tenant apps |
| DirectQuery source that already enforces row security | Source-level RLS with single sign-on | One set of rules instead of two that can drift apart |
Breaking a Tie Between Two Designs
When two rows seem to apply, choose the one with the simpler upkeep. A rule that the business can maintain through data changes will stay correct longer than one that needs a developer for every update. The decision tree below also shows the same logic as a set of yes-or-no questions.

Worked Example: Regional Sales Access for 400 Users
Consider a sales organization with 400 report users across four regions: East, West, Central and South. Most reps cover one region, while a few cover two, and regional directors see their own region plus a national summary built elsewhere. Even so, the team wants one semantic model and one role.
The design is a mapping table called UserRegion, with one row per user per region. A user who covers two regions simply gets two rows. A user with no row, on the other hand, sees nothing, which is the safe default.
| UserEmail | Region |
|---|---|
| [email protected] | East |
| [email protected] | West |
| [email protected] | Central |
| [email protected] | South |
The Regional Sales role carries two rules. First, it filters the Region dimension to the regions listed for the signed-in user. Then a second rule hides other people’s rows in the mapping table itself, so nobody can browse who has access to what.
-- Role: Regional Sales
-- Rule 1, on the Region dimension table
Region[Region]
IN CALCULATETABLE (
VALUES ( UserRegion[Region] ),
UserRegion[UserEmail] = USERPRINCIPALNAME ()
)
-- Rule 2, on the UserRegion mapping table
UserRegion[UserEmail] = USERPRINCIPALNAME ()Here is what each user sees once the role is assigned to the sales security group:
| Signed-in user | Mapping rows | Rows visible in reports |
|---|---|---|
| [email protected] | East | East only |
| [email protected] | West, Central | West and Central combined |
| [email protected] | None | No rows (fails closed) |
| Workspace Member | Not evaluated | All regions (RLS does not apply) |
Two rows in that table matter most, because they mark the edges of the design. Mia, who has no mapping row, sees an empty report instead of everything, so a missing entry fails safe. The workspace Member, by contrast, sees all regions, so editing roles must stay with the model team.
Licensing and Effort Drivers
Licensing follows who views the content rather than how RLS is designed. As of November 2026, Microsoft lists Power BI Pro at $14.00 and Premium Per User at $24.00 per user per month, paid yearly. Under the Fabric licensing rules, free-license users can view content when the workspace sits on F64 or larger capacity, or a P capacity. In app-owns-data embedding, end users need no Power BI license at all.
For a deeper look at those trade-offs, our comparison of Power BI Premium vs Pro walks through the numbers. Capacity planning also has its own guide on Microsoft Fabric capacity.
Effort is harder to predict than licensing, so we avoid quoting hours without seeing the model. Instead, these five drivers decide whether an RLS project is a week of work or a quarter:
| Driver | Low effort | Medium effort | High effort |
|---|---|---|---|
| Entitlement sources | One clean list | Two systems to reconcile | Several systems with conflicting records |
| Hierarchy depth | Flat regions | Two or three levels | Matrix or deep manager chains |
| Storage mode | Import | Direct Lake | DirectQuery with source security |
| Embedding | None | Internal app | Multi-tenant customer embedding |
| Test coverage | A few personas | A persona per role | Regulated evidence for every release |
How to Set Up Static RLS in Power BI Desktop
Static RLS is the right place to learn the mechanics, even if you end up with a dynamic design. The steps below build one role per region and then publish it to the service.
- Open Manage roles. In Power BI Desktop, go to the Modeling tab and select Manage roles.
- Create a role. Name it after the audience, such as “East Sales,” so the role list reads like an access policy.
- Add a filter. Select the Region table and enter a DAX rule such as
[Region] = "East". Then switch to the DAX editor when a rule goes beyond simple equality. - Validate in Desktop. Use View as on the Modeling tab, pick the role, and confirm every page shows East data only.
- Publish. Publish the report to a workspace, and the role definitions travel with the semantic model since they are part of it.
- Add members. In the service, open the semantic model’s Security page and add Microsoft Entra ID security groups to each role. Microsoft recommends security groups over individual users, since membership is then managed in Entra ID.
- Test as role. On the same Security page, use Test as role to check the published result before you share the report.
A note on naming: Azure Active Directory is now Microsoft Entra ID, and older guides use the old name for the same groups. Role members can be security groups, distribution groups or mail-enabled groups, but you cannot add groups created inside Power BI.
Object-Level Security Setup
Object-level security is configured in the same model roles, so it fits naturally after your first static role. Microsoft documents two routes, TMDL view inside the authoring tool or the external Tabular Editor, and the TMDL route needs no extra software.
- Open TMDL view. Start a new script tab in your authoring environment.
- Write a createOrReplace script. Define the role and set
metadataPermission: noneon the table or column to hide. Usereadto keep an object visible. - Preview, then apply. Preview shows the model changes before Apply writes the role definition.
- Publish and assign members. Publish the model, open its Security page in the service and add groups to the role.
createOrReplace
role CategoriesOLS
modelPermission: read
tablePermission Customers
columnPermission Address
metadataPermission: noneFor a Viewer in that role, the Address column simply does not exist, as if it had never been modeled. Two caveats from Microsoft apply here as well. OLS binds Viewers only, like RLS, and models with OLS do not support Quick insights, smart narrative visuals or the Excel Data Types gallery.
Static roles become hard to maintain once the list of regions or users starts to move. That is the point where most teams switch to the dynamic pattern in the next section.
Checklist
Power BI Checklist
A step-by-step checklist for planning, building and rolling out Power BI, including the modeling and security checks to run before reports reach business users.
Get the Checklist →How to Implement Dynamic RLS with USERPRINCIPALNAME
Dynamic RLS replaces many roles with one rule that asks a simple question: who is signed in, and what are they allowed to see? The USERPRINCIPALNAME function returns the signed-in user’s UPN, usually their work email, and a mapping table turns that identity into a set of rows.
The steps below follow the worked example above, so they assume an Import or Direct Lake model with a star schema.
- Build the mapping table. Create a UserRegion table with UserEmail and Region columns, one row per user per region. Source it from a governed system rather than a spreadsheet on someone’s desktop.
- Load it into the model. Keep it as a separate table, then hide it from report view.
- Filter the dimension table. Add the rule on the Region dimension using USERPRINCIPALNAME, as shown in the code above. The filter then flows to sales facts through the active relationship.
- Protect the mapping table. Add a second rule on UserRegion so each user sees only their own rows.
- Keep relationships single-direction. RLS uses single-direction filtering by default, even if a relationship is set to both directions. Turn on “Apply security filter in both directions” only when a design truly needs it.
- Publish and assign a group. Add one Entra security group, such as “Sales Report Users,” as the role’s member.
Why the Rule Fails Closed
The rule is also written to fail closed. If a user’s email is missing from UserRegion, the inner table is empty, so no region passes and the report shows nothing. Microsoft’s RLS guidance makes the same point about static values. Each rule should test for every expected value, so a typo returns no rows instead of all rows.
A fail-open rule, though, is easy to write by accident. A condition such as “everyone except Worker sees all rows” means a misspelled value like “Wrker” exposes the whole table. Write the positive case, never the exception.

Manager Hierarchies with PATH Functions
Managers often need to see their own team and every level below it, so the rule must follow the reporting chain. Building a role for each manager does not scale, but DAX parent-child functions handle the chain neatly. Store each employee’s ID and manager ID in an Employee table, then build the path as a calculated column.
-- Calculated column on Employee
Path = PATH ( Employee[EmployeeID], Employee[ManagerID] )
-- RLS rule on Employee
VAR CurrentUserID =
MAXX (
FILTER ( ALL ( Employee ), Employee[Email] = USERPRINCIPALNAME () ),
Employee[EmployeeID]
)
RETURN
NOT ISBLANK ( CurrentUserID )
&& PATHCONTAINS ( Employee[Path], CurrentUserID )The rule keeps every employee whose path contains the signed-in manager’s ID, which means the manager and everyone beneath them. The ISBLANK check keeps the rule fail-closed for anyone missing from the Employee table. When the company reorganizes, the HR feed updates the ManagerID column and access follows on the next refresh.
Users With More Than One Entitlement
Roles in Power BI are additive, so combining roles only ever widens access. A user who belongs to two roles sees the union of both filters, never the intersection. So a rep in “East Sales” and “Partner Channel” sees East rows plus every partner row, which is rarely what the business intended.
Microsoft’s guidance is to design one role that grants everything a user needs. Model a multi-region user as several rows in the mapping table, as Raj has in the worked example, rather than as membership in several roles. The access list then lives in one place, and an auditor can read it as data.
For a tool-level view of the same ideas, Tabular Editor also publishes a guide to row-level security in Power BI semantic models.
RLS in Fabric, Direct Lake and Embedded Scenarios
RLS behaves the same on paper across Power BI and Microsoft Fabric, but each platform pattern adds one twist worth knowing before go-live. Direct Lake can change where queries run, embedding changes who the user is, and guest accounts change what the user’s name looks like. Each one can quietly break a rule that passed every test in Desktop.
Direct Lake and DirectQuery Fallback
Direct Lake semantic models read Delta tables in OneLake directly, and they also support RLS with the same roles and DAX as any other model. The twist, however, is fallback. When a DAX query uses a feature Direct Lake cannot serve, the query falls back to DirectQuery (Direct Lake on SQL only; Direct Lake on OneLake does not fall back). RLS filters still apply, but performance characteristics may change.
Where the row security lives matters. If you define RLS on the SQL analytics endpoint, a Direct Lake on SQL model falls back to DirectQuery to honor it. A Direct Lake on OneLake model does not apply that SQL-based RLS at all, according to the Direct Lake overview. So pick one home for row security per model, and prefer semantic-model RLS, which both Direct Lake modes enforce.
Fallback shows up in the Fabric capacity metrics app, so watch for it there after release. Teams that already track platform health with Azure monitoring tools can add capacity alerts to the same routine. Our guide to Direct Lake semantic models in Power BI covers fallback triggers in more depth.
Power BI Embedded and Service Principals
Embedded analytics changes who the “user” is. In app-owns-data embedding, your application signs in to Power BI with a service principal and generates an embed token for each end user. That token carries an effective identity: a user name, the roles to apply, and optionally a CUSTOMDATA value.
Service principals cannot be RLS members, and RLS is not applied when a service principal is the final effective identity. So the app must always pass an effective identity for a model with RLS. Microsoft’s embedded RLS documentation describes three patterns for software vendors:
- Small to mid-sized vendors: one semantic model and report for all customers, with dynamic RLS filtering each customer’s rows.
- Vendors with a few large customers: a mix of static and dynamic RLS, possibly with OLS for sensitive columns.
- Large vendors with thousands of customers: workspace isolation with service principal profiles, giving each customer its own model, then RLS inside each tenant.
Because the application can pass any value as the effective identity, test unexpected values as carefully as expected ones. Our overview of Power BI Embedded explains the embedding models themselves.
External B2B Guest Users
Sharing a secured report with a partner adds an identity wrinkle. Guests can be RLS members, but Microsoft warns that security groups containing B2B guests may not resolve correctly for RLS. So the recommended workaround is to add guest users directly to the role by email address.
Dynamic rules also need care. For a guest, USERPRINCIPALNAME may return an email-style value or a UPN in the #EXT# format, depending on tenant settings. When the mapping table stores a different format, the guest sees no data. Test with a real guest account, because Test as role uses your own identity and will not reveal the mismatch.
Testing RLS Before and After Release
Testing RLS means proving two things: each person sees their rows, and nobody sees anyone else’s. Teams often test the first but forget the second, which is how leaks reach production.
Power BI gives you two built-in tools. View as in Desktop checks roles during development, and Test as role in the service checks the published model. Both have limits: Test as role does not work for DirectQuery models with single sign-on, and it cannot validate Q&A visuals, Quick insights or Copilot. So the final check always uses real identities.

| Persona | Expected rows | Test method | Pass rule |
|---|---|---|---|
| Single-region rep | Own region only | View as, then a real Viewer account | Totals match the source for that region |
| Multi-region rep | Union of assigned regions | Real Viewer account | Both regions present, no others |
| User with no mapping row | None | Real Viewer account | Report is empty rather than complete |
| Viewer with Build permission | Own rows only | Analyze in Excel with that account | Pivot totals match the role |
| B2B guest | Partner rows only | Real guest account | UPN matches the mapping table |
| Embedded customer | Own tenant only | Embed token with a test identity | Unexpected identity values return no rows |
Run the matrix twice: once before the first release, and again whenever the model, the mapping logic or the workspace roles change. Store the results with the release record so an auditor can see what was tested and when.
Negative tests carry the most weight. A report that shows the right East numbers proves very little if a user with no mapping row also sees East. The no-row persona is the cheapest test you can run and the one that catches the worst failure.
Performance: Why RLS Slows Reports and How to Fix It
RLS adds work to every query, because the engine applies the role’s filters before it computes any visual. On a well-shaped model that cost is small, but on a model with heavy rules on large fact tables, users will notice.
The fixes are mostly about where the filter lands. A rule on a small dimension table filters a few hundred rows and then lets relationships do the rest. A rule on a fact table, or one that walks lookups row by row, repeats that work across millions of rows. Good dimensional design helps here, because a clean star schema gives RLS small tables to filter.
- Put RLS rules on dimension tables rather than fact tables.
- Rely on active relationships, because RLS filters only propagate through them.
- Avoid LOOKUPVALUE in rules when a model relationship can do the job.
- Turn on the bi-directional security filter only when the design needs it.
- Make sure aggregation tables are filtered consistently with the detail tables they summarize.
- Avoid USERELATIONSHIP in measures on RLS models, since Microsoft notes it may cause errors.
- Measure query times with RLS on before release, not after users complain.
If a report is fast for an admin and slow for a Viewer, RLS is the likely cause, because the admin’s queries skip the filter. Compare the two with Performance Analyzer in Desktop, using View as for the Viewer’s role.
Talk to Kanerika
Is Row-Level Security Slowing Your Reports?
Bring one secured semantic model. Kanerika will review where your RLS rules land, how filters propagate and which personas need testing, then map the fixes.
Book an RLS Review →Common RLS Mistakes That Leak or Block Data
RLS failures come in two kinds: leaks, where someone sees too much, and blocks, where someone sees nothing. Leaks are worse, but blocks erode trust in the report just as fast. The table below lists the mistakes we see most often and how to fix each one.
| Mistake | Symptom | Fix |
|---|---|---|
| Report consumers in the Member or Contributor role | Users see all rows despite RLS | Move consumers to Viewer or an app audience instead |
| Rule written as an exception (“all except X”) | A typo or new value exposes every row | Test for each expected value so unknowns return nothing |
| Mapping table visible to viewers | Anyone can see who has access to what | Hide the table and add a self-only rule on it |
| USERELATIONSHIP in measures | Unexpected errors for filtered users | Use model relationships or other DAX patterns |
| B2B guests added through security groups | Guests see no data or the wrong data | Add guests to the role by email and test as the guest |
| Stale mapping rows | Leavers keep access; movers see their old territory | Feed the table from HR or Entra ID and recertify quarterly |
| Users placed in several roles | Users see the union of roles | One role, with multiple rows in the mapping table |
Nearly every row in that table is a process failure rather than a DAX failure. That is why the last step of an RLS design is governance, which the next section covers.
Governing RLS Across an Enterprise
An RLS model is only as accurate as its access list, but access lists decay. People join, move and leave every week, so the mapping table needs the same care as any other business-critical data set.

Start with ownership. Every mapping table needs a business owner who decides whether each person should see the data. Usually that is one of the data stewards who own the mapping table for that domain. The BI team owns the rules and the model, while the steward owns the entries as part of wider data governance.
Next, automate the feed. A mapping table that someone edits by hand drifts quickly, because manual edits lag behind joiners, movers and leavers. Load it from Microsoft Entra ID groups or the HR system through a scheduled pipeline. Then apply the same data engineering best practices you use for any governed table: validation, history and alerts on failed loads.
Release Control, Recertification and Audit Evidence
Third, put changes under control. Promote model changes through Power BI deployment pipelines so rules are tested in development before they reach production. Also run the persona test matrix as part of each promotion, and keep editing roles in production to a short, named list.
Fourth, recertify on a schedule. Once a quarter, send each owner the list of who can see their data and ask them to confirm or remove entries. That review catches the leavers and movers that automated feeds miss, and it also gives auditors a signed record.
Finally, keep evidence. Fabric and Power BI activity can be searched in the Microsoft Purview portal audit log, which requires the Audit Logs role. Combined with the release record and recertification sign-offs, that log answers the auditor’s real question: who could see this data, and who approved it? Our Microsoft Purview guide covers the wider governance platform behind that audit log.
Governance also extends to AI features. Copilot in Power BI works over the same semantic models, so the access rules you govern here also shape what its answers can reveal. Our guide to Power BI Copilot covers how to prepare models for that use.
On-Demand Webinar
Transform Your Data Strategy with Microsoft Purview: Governance, Security & Growth
An on-demand session on using Microsoft Purview to classify, protect and audit data, the governance layer that sits around Power BI access controls.
Watch the Webinar →How Kanerika Delivers RLS at Enterprise Scale
Kanerika treats RLS as an access program with a technical core rather than a modeling task. We are a Microsoft Solutions Partner for Data and AI and a Microsoft Fabric Featured Partner. We build RLS in five stages, and each stage hands over a named artifact. That way security, performance and audit needs are settled before the first report ships.
- Access contract. The business owner signs a plain-English statement of who sees which rows and columns. It becomes the reference every later test is checked against.
- Entitlement model. We design the mapping table, name its owner (usually the domain’s data steward) and feed it from Microsoft Entra ID groups or the HR system on a schedule.
- Fail-closed build. Dynamic roles return nothing for unknown users, and OLS hides sensitive columns. The output is a role catalog that maps each role back to a line of the contract.
- Persona test matrix. One row per persona (Viewer, guest, embedded identity, leaver), each with the rows it must see and the rows it must not. Negative tests count as much as positive ones.
- Release and recertification pack. Changes move through deployment pipelines, owners recertify the mapping table every quarter, and audit-log exports sit with the sign-offs.
Our Power BI practice is led by Amit Chandak, Kanerika’s Chief Analytics Officer and a Microsoft MVP for Power BI. Teams that want help with the build can explore our Power BI consulting and implementation services. Our data governance services also cover the ownership and recertification side. We also work across Microsoft Fabric and Microsoft Purview when RLS spans the wider platform.
Case in Point: Allen Distribution
Allen Distribution shows the pattern in practice. The US logistics and supply chain company, headquartered in Pennsylvania, had warehouse management (WMS) and HR data spread across on-premises SQL servers. Kanerika centralized that data on Microsoft Fabric with Power BI reporting, and implemented row-level security so data access is role-based.
That mix is what made the access contract matter. Warehouse figures and HR records now sat in one platform, yet the teams reading them had very different needs. Scoping access by role, as the case study records, let operations, inventory and HR plan from shared data while keeping privacy and compliance intact. In our method, a contract like that becomes the persona test matrix: each team’s role is checked against the rows it should see and the HR rows it should not.
The project as a whole improved operational efficiency by 60% and data accuracy by 54%. It also lifted decision-making precision by 42% and grew data-driven decisions by 61%. Those are outcomes of the full platform work rather than of RLS alone. Role-based RLS is what let one shared platform serve operations, inventory and HR, with access scoped by role for privacy and compliance.
Case Study
60% Efficiency Gain with Microsoft Fabric & Power BI
Allen Distribution moved fragmented WMS and HR data from on-premises SQL servers to Microsoft Fabric, with Power BI reporting and role-based row-level security, and improved operational efficiency by 60%.
Read the Case Study →If you are weighing outside help, our guide to choosing a Power BI consulting company is a useful checklist. For broader context, see our Power BI overview, our comparison of Microsoft Fabric vs Power BI, and the wider data security practices that RLS supports.
So how should you design, implement and govern Power BI row level security? Design it around a governed mapping table, and implement it with fail-closed dynamic rules tested on real identities. Then govern it with named owners, controlled releases and quarterly recertification.
Frequently Asked Questions
What is Power BI row-level security?
Power BI row-level security (RLS) is a filter on a semantic model that limits which rows each user can read. You create roles in Power BI Desktop, add DAX rules that return true or false for each row, and assign Microsoft Entra ID security groups in the service. Every report and app built on that model then respects the filter.
What is the difference between static and dynamic row-level security?
Static RLS hard-codes a value in each role, such as one role per region, so every new group needs a model change. Dynamic RLS uses one role whose rule compares USERPRINCIPALNAME() with a mapping table of users and their entitlements. Access changes become data updates, which is why dynamic RLS suits most enterprise models with changing users.
What happens when a user belongs to multiple RLS roles?
Power BI roles are additive, so the user sees the union of every role’s filters, not the overlap. A rep in both an East Sales role and a Partner Channel role sees all East rows plus all partner rows. Microsoft recommends one role per user’s full needs, with multiple entitlements stored as extra rows in the mapping table.
Why is my Power BI row-level security not working?
Check the workspace role first, because Admins, Members and Contributors bypass RLS. Then confirm the user’s UPN exactly matches the mapping table, that filters flow through active relationships, and that aggregation tables are filtered consistently. USERELATIONSHIP in measures can also cause errors. Users not assigned to any role typically see no data at all.
How does row-level security work in Power BI Embedded?
In app-owns-data embedding, the app requests an embed token that carries an effective identity: a user name, the roles to apply and an optional CUSTOMDATA value. Service principals cannot be RLS members, so RLS is not applied when one is the final identity. Large software vendors combine service principal profiles for tenant isolation with RLS inside each tenant.
What Power BI license do I need for row-level security?
Licensing follows who views content. As of November 2026, Power BI Pro costs $14.00 and Premium Per User $24.00 per user per month, paid yearly. Free-license users can view content in workspaces on F64 or larger Fabric capacity, or a P capacity. In app-owns-data embedding, end users need no Power BI license at all.
How does RLS work for external B2B guest users?
Guests can be RLS members, but Entra security groups that contain B2B guests may not resolve correctly, so add guests to the role by email address. For dynamic rules, USERPRINCIPALNAME may return an email or an #EXT# style UPN, depending on tenant settings. Store the matching format in the mapping table and test with the real guest account.
Should I use row-level security or workspace permissions?
Use both, because they answer different questions. Workspace roles and item permissions decide who can open a workspace, report or app. RLS decides which rows a user sees once inside. Keep report consumers in the Viewer role or an app audience, since workspace Admins, Members and Contributors bypass RLS and see every row of the model.
How do I test row-level security in Power BI?
Use View as in Power BI Desktop while you build, then Test as role on the semantic model’s Security page after publishing. Finish with real Viewer accounts for each persona, including a user with no mapping row, who should see nothing. Test as role cannot validate Q&A, Quick insights or Copilot, and fails for DirectQuery with SSO.
Does row-level security work with Direct Lake semantic models?
Yes. Direct Lake models support RLS with the same roles and DAX rules as Import models. If a query falls back to DirectQuery, the RLS filters still apply, but performance can change. Defining RLS on the SQL analytics endpoint forces that fallback, so keep row security in the semantic model and watch fallback in the capacity metrics app.
Can a workspace admin bypass row-level security?
Yes. RLS applies only to users in the workspace Viewer role and to people who receive content through an app or share. Workspace Admins, Members and Contributors see every row, because they can edit the model anyway. Keep editing roles for a small model team, and always test RLS with a Viewer-only account, never an admin account.
How does Power BI row-level security affect report performance?
RLS adds the role’s filters to every query, so heavy rules slow reports. Put rules on small dimension tables, not large fact tables, and let active relationships carry the filter. Avoid LOOKUPVALUE where a relationship works, enable the bi-directional security filter only when needed, and compare query times with Performance Analyzer using View as.
Is row-level security the same as column-level security in Power BI?
No. Row-level security filters which rows a user sees, while object-level security (OLS) hides whole tables or columns, such as a salary or patient identifier column. Both are defined in the same semantic model roles and often run together. A typical design filters rows by region with RLS and hides sensitive columns with OLS for most users.
How do I use USERPRINCIPALNAME for dynamic row-level security?
Create a mapping table with one row per user and entitlement, for example UserEmail and Region. Add a rule on the Region dimension that keeps regions listed for USERPRINCIPALNAME(), and a second rule so users see only their own mapping rows. Assign one Entra security group to the role. Users without a mapping row then see nothing.
Does Build permission or Analyze in Excel bypass row-level security?
No. A user in the Viewer role who also holds Build permission on the semantic model is still filtered by RLS. That includes queries from Analyze in Excel and new reports they build on the model. The bypass comes from workspace roles, not Build, so Admins, Members and Contributors are the accounts that see unfiltered data.
