EPC Group - Enterprise Microsoft AI, SharePoint, Power BI, and Azure Consulting
G2 High Performer Summer 2025, Momentum Leader Spring 2025, Leader Winter 2025, Leader Spring 2026
BlogContact
Ready to transform your Microsoft environment?Get started today
(888) 381-9725Get Free Consultation
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌
‌

EPC Group

Enterprise Microsoft consulting with 28+ years serving Fortune 500 companies.

(888) 381-9725
contact@epcgroup.net
4900 Woodway Drive - Suite 830
Houston, TX 77056

Follow Us

Solutions

  • All Services
  • Microsoft 365 Consulting
  • AI Governance
  • Azure AI Consulting
  • Cloud Migration
  • Microsoft Copilot
  • Data Governance
  • Microsoft Fabric
  • vCIO / vCAIO Services
  • Large-Scale Migrations
  • SharePoint Development

Industries

  • All Industries
  • Healthcare IT
  • Financial Services
  • Government
  • Education
  • Teams vs Slack

Power BI

  • Case Studies
  • 24/7 Emergency Support
  • Dashboard Guide
  • Gateway Setup
  • Premium Features
  • Lookup Functions
  • Power Pivot vs BI
  • Treemaps Guide
  • Dataverse
  • Power BI Consulting

Company

  • About Us
  • Our History
  • Microsoft Gold Partner
  • Case Studies
  • Testimonials
  • Blog
  • Resources
  • Contact

Microsoft Teams

  • Teams Questions
  • Teams Healthcare
  • Task Management
  • PSTN Calling
  • Enable Dial Pad

Azure & SharePoint

  • Azure Databricks
  • Azure DevOps
  • Azure Synapse
  • SharePoint MySites
  • SharePoint ECM
  • SharePoint vs M-Files

Comparisons

  • M365 vs Google
  • Databricks vs Dataproc
  • Dynamics vs SAP
  • Intune vs SCCM
  • Power BI vs MicroStrategy

Legal

  • Sitemap
  • Privacy Policy
  • Terms
  • Cookies

Our Specialized Practices

PowerBIConsulting.com|CopilotConsulting.com|SharePointSupport.com

© 2026 EPC Group. All rights reserved.

Power BI Row-Level Security: Enterprise Guide 2026 - EPC Group enterprise consulting

Power BI Row-Level Security: Enterprise Guide 2026

Implement static, dynamic, and hierarchical RLS to secure enterprise data at the row level across Power BI Service, Embedded, and DirectQuery.

What is Row-Level Security (RLS) in Power BI?

Row-Level Security (RLS) in Power BI restricts data access at the row level based on user identity. Instead of creating separate reports for each department, region, or role, RLS dynamically filters a single dataset so users see only the data they are authorized to access. For enterprise organizations in regulated industries, RLS is not optional — it is a compliance requirement for protecting sensitive data including PHI, PII, and financial records.

Quick Answer: To implement RLS in Power BI, create a role in Power BI Desktop (Modeling > Manage Roles), define a DAX filter expression, and assign Azure AD users or groups to the role in Power BI Service. For enterprise, use dynamic RLS with USERPRINCIPALNAME() and a security mapping table to automatically filter data based on the logged-in user — scaling to thousands of users without individual role management.

This guide covers every enterprise RLS pattern — from basic static roles to complex manager-hierarchy security — based on EPC Group's experience implementing RLS across Fortune 500 Power BI deployments in healthcare, finance, and government.

Static RLS

Hardcoded role-based filtering

Dynamic RLS

User identity-based filtering

Object-Level (OLS)

Column and table visibility

DAX Patterns

Enterprise filter expressions

Static RLS vs Dynamic RLS

Static RLS

Static RLS uses hardcoded values in DAX filter expressions. Each role is defined with a specific data filter that applies to all users assigned to that role.

DAX — Static RLS Example (West Region Role)

[Region] = "West"
  • Simple to implement and understand
  • One role per data partition
  • Works for small organizations (under 10 roles)
  • Does not scale — role count grows linearly with permissions

Dynamic RLSRecommended

Dynamic RLS uses DAX functions to resolve the current user identity and filter data based on a security mapping table — a single role scales to thousands of users.

DAX — Dynamic RLS Example

[UserEmail] = USERPRINCIPALNAME()
  • Single role handles all user permissions
  • Security table maps users to data partitions
  • Scales to 10,000+ users without new roles
  • Maintenance is data-driven, not role-driven

DAX Functions for Row-Level Security

Two key DAX functions power dynamic RLS. Understanding when to use each is critical for correct implementation.

USERPRINCIPALNAME()

Returns the Azure AD User Principal Name (UPN) of the current user — typically their email address (e.g., john.doe@contoso.com). This is the recommended function for enterprise RLS because UPN is a globally unique, Azure AD-governed identifier.

DAX — Security Table Filter with USERPRINCIPALNAME

// Filter the SecurityMapping table // Users see only rows where their UPN matches [UserEmail] = USERPRINCIPALNAME()

USERNAME()

Returns the user identity in DOMAIN\username format for on-premises environments or UPN format in Power BI Service. Use USERNAME() only when you need backward compatibility with Analysis Services or on-premises gateway scenarios.

DAX — USERNAME for On-Premises Scenarios

// USERNAME() returns DOMAIN\user on-prem // Returns UPN in Power BI Service [DomainUser] = USERNAME()

Manager Hierarchy Pattern

The most complex enterprise RLS pattern — managers see data for their direct and indirect reports using parent-child DAX functions.

DAX — Manager Hierarchy RLS

// Step 1: Build hierarchy path (calculated column) HierarchyPath = PATH(Employee[EmployeeID], Employee[ManagerID]) // Step 2: RLS filter expression VAR currentUser = USERPRINCIPALNAME() VAR userID = LOOKUPVALUE( Employee[EmployeeID], Employee[Email], currentUser ) RETURN PATHCONTAINS(Employee[HierarchyPath], userID)

Multi-Role RLS Pattern

When users need access across multiple dimensions (region + department + product line), use a security mapping table with multiple columns.

DAX — Multi-Dimension Security Filter

// SecurityMapping table has columns: // UserEmail, Region, Department, ProductLine // Create relationship from SecurityMapping // to each dimension table // RLS filter on SecurityMapping table: [UserEmail] = USERPRINCIPALNAME() // Relationships propagate filters to // fact table through dimension tables

RLS with DirectQuery

When using DirectQuery, RLS DAX expressions are translated to SQL WHERE clauses and pushed to the source database. This provides security at the database level — data never leaves the source unless the user is authorized to see it — which is a significant security advantage for sensitive environments.

DirectQuery RLS Benefits

  • SQL-level filtering — data never leaves source without authorization
  • Leverages database indexing for RLS filter performance
  • Real-time security enforcement (no stale cache)
  • Works with Azure SQL, SQL Server, Synapse, Databricks
  • Complementary to database-native security (SQL Server RLS)

DirectQuery RLS Considerations

  • Complex DAX may not push down — verify with SQL Profiler
  • USERPRINCIPALNAME() works, but calculated columns do not push down
  • Performance depends on source database optimization
  • SSO configuration required for per-user identity passthrough
  • Composite models add complexity (Import + DirectQuery RLS)

Testing and Deploying RLS

RLS Deployment Checklist

1

Define Roles in Desktop

Open Modeling > Manage Roles. Create roles with DAX filter expressions. Use dynamic RLS with USERPRINCIPALNAME() for enterprise scale.

2

Test in Desktop

Use Modeling > View as Roles. Select the role and optionally specify "Other user" to simulate specific identities. Validate that restricted data is not visible.

3

Publish to Service

Publish the report and dataset to Power BI Service. Navigate to the dataset > Security tab.

4

Assign Users/Groups

Add Azure AD users or security groups to each role. Use security groups (not individual users) for maintainability. Assign at the Azure AD group level.

5

Test in Service

Click the ellipsis next to a role > "Test as role." Verify with multiple user identities, including edge cases (new users, multi-role users, admins).

6

Validate with Stakeholders

Have data owners from each business unit validate they see exactly the correct data — no more, no less. Document sign-off.

RLS with Power BI Embedded Analytics

Power BI Embedded enables ISVs and enterprise applications to embed analytics in custom applications. RLS in embedded scenarios requires passing an effective identity in the embed token — the embedded user does not need a Power BI license, but security is enforced server-side.

App Owns Data (Service Principal)

Your application authenticates with a service principal and generates embed tokens with customer identity claims. The application controls who sees what by including RLS roles and usernames in the GenerateToken API call.

// Embed token with RLS EffectiveIdentity: { username: "customer@contoso.com", roles: ["DynamicRLS"], datasets: ["dataset-guid"] }

User Owns Data (Azure AD)

The user authenticates directly with Azure AD. Their identity passes through to Power BI Service, and RLS is enforced based on their Azure AD group membership — identical to standard Power BI Service behavior.

// User token - RLS automatic // Azure AD token passed to PBI // RLS resolved from dataset // security role assignments

Learn more about embedded analytics patterns in our Power BI Embedded Analytics Guide.

Object-Level Security (OLS)

Object-Level Security (OLS) complements RLS by hiding entire tables or columns from specific roles. While RLS filters rows, OLS prevents users from even knowing certain data exists in the model. OLS is configured using Tabular Editor — it is not available in the standard Power BI Desktop interface.

Common OLS Use Cases

Healthcare (HIPAA)

Hide PHI columns (SSN, DOB, diagnosis codes) from non-clinical roles

Financial Services

Hide compensation and bonus data from non-HR roles

Government

Hide classified data columns from uncleared personnel

Multi-Tenant SaaS

Hide internal metrics tables from external customer-facing reports

Important: OLS requires Tabular Editor (external tool) to configure. It cannot be set up in Power BI Desktop directly. When OLS hides a column used by a visual, the visual shows an error — design reports with OLS restrictions in mind from the start, not as an afterthought.

Common Enterprise RLS Patterns

Territory / Region

Sales reps see only their assigned territories. Managers see their team territories. VPs see all regions. Implemented with a SecurityMapping table joining users to territory dimension.

Department

Finance sees financial data, HR sees HR data, Operations sees operational metrics. Each department mapped in a security table with USERPRINCIPALNAME() lookup.

Manager Hierarchy

Managers see data for their direct and indirect reports using PATH/PATHCONTAINS DAX functions. Automatically cascades through the organizational hierarchy.

Cost Center

Budget owners see only their assigned cost centers. Cross-functional managers see multiple cost centers. CFO sees all. Security table maps users to cost center arrays.

Patient / Client (HIPAA)

Clinical staff see only their assigned patients. Care team leads see department patients. Audit logging on all RLS-filtered data access for HIPAA compliance.

External / Customer

Customer-facing embedded reports show only data belonging to the authenticated customer tenant. Internal users see cross-customer analytics for benchmarking.

RLS Performance Impact and Optimization

RLS adds query overhead because every DAX query must be wrapped in security filter context. The performance impact varies by implementation complexity.

RLS PatternTypical OverheadOptimization Strategy
Simple Static RLS1-3%No optimization needed — negligible impact
Dynamic RLS (USERPRINCIPALNAME)5-10%Keep security table in Import mode; index join columns
Multi-Dimension Dynamic RLS8-15%Pre-compute user-to-data mappings in ETL; minimize relationships
Hierarchical RLS (PATH)15-30%Flatten hierarchy in ETL; use materialized security columns
RLS + OLS Combined10-20%Test with DAX Studio; profile query plans for bottlenecks

Troubleshooting RLS Issues

Users See All Data (RLS Not Applied)

Most common cause: dataset owners and workspace admins bypass RLS by default. In Power BI Service, only users assigned to a role via the Security tab are filtered. Admins see all data for management purposes — use "Test as role" to validate the user experience.

Users See No Data (Blank Report)

Check that the user email in the security table exactly matches their Azure AD UPN (case-sensitive in some configurations). Verify the relationship between the security table and fact tables is active and filtering in the correct direction (single or both).

RLS Works in Desktop But Not in Service

Desktop uses simulated identities while Service uses real Azure AD tokens. Common issues: UPN format differences (Desktop may show DOMAIN\user while Service uses email), B2B guest user identity format (guest#EXT#@tenant), and SSO configuration for DirectQuery.

Performance Degradation After Enabling RLS

Use DAX Studio to profile queries with and without RLS. Check if RLS filter expressions cause storage engine scans instead of seeks. Optimize by pre-computing security lookups, keeping security tables small, and ensuring join columns are indexed.

RLS Not Working with Composite Models

In composite models (Import + DirectQuery), RLS must be defined on both storage modes. DirectQuery tables apply RLS at the source, while Import tables apply RLS in the Vertipaq engine. Ensure consistent role definitions across both modes.

Enterprise RLS Implementation by EPC Group

500+

Power BI deployments with RLS

28+

Years of Microsoft expertise

HIPAA

Compliant RLS for healthcare

10K+

Max users per RLS deployment

RLS misconfigurations are the number one cause of data breaches in Power BI environments. EPC Group implements enterprise-grade RLS with automated testing, compliance documentation, and ongoing security monitoring.

Get Free Security Assessment (888) 381-9725

Related Resources

Power BI Consulting Services

Enterprise dashboard development, data modeling, RLS implementation, and governance from EPC Group.

Read more

Power BI Data Modeling Best Practices

Star schema design, relationship optimization, and DAX patterns for enterprise Power BI models.

Read more

Embedded Analytics Guide

Integrate Power BI analytics into custom applications with RLS enforcement via embed tokens.

Read more

Frequently Asked Questions

How do you implement Row-Level Security in Power BI?

To implement Row-Level Security (RLS) in Power BI: 1) Open Power BI Desktop and go to Modeling > Manage Roles, 2) Create a new role and define a DAX filter expression on the table you want to restrict (e.g., [Region] = "West"), 3) For dynamic RLS, use USERPRINCIPALNAME() in your DAX expression to filter based on the logged-in user (e.g., [UserEmail] = USERPRINCIPALNAME()), 4) Test the role using "View as Role" in Desktop, 5) Publish to Power BI Service and assign users or Azure AD groups to the role under dataset Security settings. Dynamic RLS is preferred for enterprise because it scales without creating a new role for every user or permission combination.

What is the difference between static and dynamic RLS in Power BI?

Static RLS uses hardcoded values in DAX filter expressions — for example, [Region] = "West" — meaning each role sees a fixed subset of data. Dynamic RLS uses DAX functions like USERPRINCIPALNAME() or USERNAME() to automatically filter data based on the logged-in user identity, typically by joining a security table that maps users to their permitted data. Static RLS requires a separate role for each permission group, while dynamic RLS uses a single role with a security mapping table, making it far more scalable for enterprise. EPC Group recommends dynamic RLS for any deployment exceeding 10 distinct permission groups.

Does RLS work with DirectQuery in Power BI?

Yes, RLS works with DirectQuery in Power BI, but with important caveats. DAX filter expressions defined in roles are translated to SQL WHERE clauses and pushed to the source database, which means the filtering happens at the database level — providing both security and performance benefits. However, not all DAX functions translate cleanly to SQL. Functions like USERPRINCIPALNAME() work, but complex DAX calculations may not push down correctly, falling back to client-side evaluation which degrades performance. EPC Group recommends keeping DirectQuery RLS expressions simple and testing query pushdown behavior with SQL Profiler or Performance Analyzer.

How do you test RLS in Power BI Desktop?

In Power BI Desktop, test RLS using the "View as" feature: go to Modeling > View as Roles, select the role you want to test, and optionally check "Other user" to simulate a specific user identity for dynamic RLS testing. The report will refresh showing only data that the selected role/user would see. For enterprise testing, also test in Power BI Service by navigating to the dataset > Security tab > clicking the ellipsis next to a role > "Test as role." This tests with actual Azure AD identity resolution, which may differ from Desktop simulation in certain SSO and B2B guest scenarios.

What is Object-Level Security (OLS) in Power BI?

Object-Level Security (OLS) restricts access to entire tables or columns in a Power BI data model, complementing Row-Level Security which filters rows. OLS is configured using Tabular Editor (not available in the standard Power BI Desktop UI) by setting table or column permissions to "None" for specific roles. This is critical for scenarios where certain user groups should not even see that a column or table exists — such as hiding salary columns from non-HR users, or hiding PHI columns from non-clinical staff in healthcare. OLS and RLS can be combined: OLS hides columns/tables, RLS filters visible rows.

How does RLS work with Power BI Embedded?

For Power BI Embedded, RLS is enforced by passing an effective identity in the embed token generation API call. When generating a token using the Power BI REST API, include the EffectiveIdentity object specifying the username, roles, and datasets. The embedded report then renders with RLS applied for that identity — even though the end user may not have a Power BI license. This is essential for ISVs and customer-facing analytics applications. For "App Owns Data" scenarios, the service principal generates tokens with customer identity claims. For "User Owns Data," the user Azure AD token is passed through directly.

Does RLS impact Power BI performance?

RLS does impact performance, but the degree depends on implementation. Simple static RLS adds minimal overhead (1-3% query time increase). Dynamic RLS with USERPRINCIPALNAME() lookups against a security table typically adds 5-10% overhead. Complex hierarchical RLS with parent-child DAX calculations can add 15-30% overhead on large models. Performance optimization strategies include: keeping the security mapping table in Import mode even if the main model uses DirectQuery, indexing the security column in source databases, using SUMMARIZECOLUMNS instead of nested CALCULATE for hierarchical filters, and pre-computing user-to-data mappings in the ETL pipeline.

Can RLS enforce manager hierarchy security in Power BI?

Yes, Power BI RLS can enforce manager-hierarchy security using parent-child DAX functions. The pattern requires: 1) A dimension table with employee ID, manager ID, and email columns, 2) A DAX PATH function to build the hierarchy path for each employee, 3) A RLS filter using PATHCONTAINS to check if the current user exists in an employee hierarchy path. The DAX expression looks like: VAR currentUser = USERPRINCIPALNAME() VAR userEmployeeID = LOOKUPVALUE(Employee[EmployeeID], Employee[Email], currentUser) RETURN PATHCONTAINS(Employee[HierarchyPath], userEmployeeID). This ensures managers see data for their direct and indirect reports automatically.

Need Help Implementing RLS for Your Enterprise?

Schedule a free Power BI security assessment. We will review your current data model, recommend the optimal RLS architecture, and ensure compliance with your industry regulations.

Schedule Assessment (888) 381-9725