Row-level security (RLS) has become a cornerstone of enterprise data governance in self-service business intelligence platforms. As organizations scale Power BI deployments across departments, geographies, and partner ecosystems, the ability to restrict data access at the row level—without fragmenting models or duplicating reports—is no longer a nicety but a necessity. Enterprises face mounting pressure to comply with data residency, privacy regulations, and internal segmentation policies while still delivering agile analytics. RLS addresses this tension by enabling a single semantic model to serve diverse user groups, each seeing only the data they are authorized to consume. For consulting teams and IT leaders, understanding the architectural nuances, implementation patterns, and governance implications of RLS is essential to designing secure, scalable, and maintainable Power BI environments—especially as the platform extends into Microsoft Fabric and supports complex connection modes such as DirectQuery, Direct Lake, and live connections.
Architecture and Capabilities of RLS in Power BI and Microsoft Fabric
The architectural foundation of Row-level security in Power BI rests on DAX-based filter expressions attached to named roles. Unlike column-level security, which masks or restricts access to specific columns, RLS operates at the row level, completely removing rows that do not evaluate to TRUE for the active role. This means that from the perspective of the semantic model, filtered rows simply do not exist for the unauthorized user. The engine evaluates the DAX expression for each row during query execution, and only rows returning TRUE are projected into the result set. This design has profound implications for query optimization, caching, and model performance, as the underlying engine can push filters down to the data source when using DirectQuery or Direct Lake modes.
In the context of Microsoft Fabric, RLS support extends to Direct Lake semantic models, which leverage the native lakehouse engine for in-memory analytics. When a DAX query against a Direct Lake model falls back to DirectQuery mode—due to unsupported DAX functions or calculation entities—RLS filters still apply, but the performance characteristics shift. The fallback may introduce additional network round-trips or alter the query plan, making it critical for administrators to monitor query fallback behavior through the Fabric capacity metrics app. This visibility allows teams to identify patterns where RLS might be inadvertently causing performance degradation and to tune the model or DAX expressions accordingly.
Power BI also supports RLS on imported semantic models and DirectQuery connections, including relational data sources such as SQL Server, Azure SQL Database, and other certified connectors. For Analysis Services or Azure Analysis Services live connections, row-level security must be configured within the source model, not in the Power BI service. The security option simply does not appear for live connection semantic models, as the enforcement responsibility resides in the on-premises or Azure AS instance. This distinction is often a source of confusion during migrations or hybrid deployments, and consulting teams must ensure that RLS policies are mirrored or translated appropriately when shifting between import, DirectQuery, and live connection modes.
How Row-Level Security Works Internally
The mechanics of RLS are deceptively simple but carry important operational details. When a role is defined and published, the Power BI service embeds the DAX filter expression into the user’s session context. Upon every query, the engine checks the active user’s membership in assigned roles and applies the corresponding filter. If a user belongs to multiple roles, the expressions are combined using OR logic by default—meaning the user sees rows that satisfy any one of their assigned roles. This OR-combination behavior can lead to unexpected data exposure if not carefully modeled, particularly when roles overlap in their scope.
By default, RLS filtering uses single-directional cross-filtering, respecting the relationship direction configured in the model (single or bi-directional). However, Power BI provides a checkbox labeled “Apply security filter in both directions” on the relationship settings. Enabling this option engages bi-directional cross-filtering for the selected relationship, which can be necessary when dynamic RLS is implemented at the server level based on username or login ID. However, this setting has a critical limitation: if a table participates in multiple bi-directional relationships, the “Apply security filter in both directions” checkbox can only be selected for one of those relationships. Attempting to enable it on more than one results in an error. This constraint necessitates careful modeling of relationship topologies and often requires redesigning the star schema or using bridge tables to untangle conflicting cross-filter directions.
Performance considerations are paramount when bi-directional security filtering is enabled. Models with many relationships or large datasets can experience query latency increases, as the engine must evaluate filter propagation across multiple paths. Microsoft explicitly warns that enabling bi-directional security filtering can negatively impact query performance, and recommends thorough testing in a staging environment before any production deployment. In practice, many enterprise architectures avoid bi-directional RLS altogether, opting instead for carefully designed role hierarchies or DAX patterns such as USERELATIONSHIP()—though the latter carries its own caveats, as discussed in the limitations section.
Implementation Considerations
Implementing RLS typically follows a high-level workflow: define roles and rules in Power BI Desktop using DAX filter expressions, publish the semantic model and report to the Power BI service, add members to roles in the service, and validate the implementation using the Test as role feature. Role definitions are created within the Modeling tab of Power BI Desktop, under Manage Roles. Here, analysts can toggle between a default drop-down interface and a full DAX editor. The default editor provides a user-friendly interface for constructing simple filters, but it has significant limitations. Not all RLS filters supported by Power BI can be expressed using the default editor; dynamic rules involving USERNAME(), USERPRINCIPALNAME(), or other user-dependent functions require the DAX interface. When a role definition relies on such functions, switching to the default editor triggers a warning that information may be lost, and the only safe path forward is to continue editing in the DAX interface.
DAX expressions in the RLS filter box return a TRUE or FALSE value for each row. A common static pattern takes the form: [Region] = "West", which restricts users assigned to that role to rows where the Region column equals “West”. For dynamic scenarios, the expression might reference the signed-in user: USERPRINCIPALNAME() = "user@contoso.com" or [Entity ID] = USERPRINCIPALNAME(), where the latter references a column in the model that stores user identifiers. The DAX editor includes IntelliSense autocomplete, expression validation via a checkmark, and a revert (X) button for experimental changes. An important formatting note: within the expression box, commas must separate DAX function arguments regardless of the locale’s default separator (e.g., French or German locales normally use semicolons). This quirk often trips up developers migrating models across regions.
Within Power BI Desktop, the USERNAME() function returns the user in DOMAIN\username format, while USERPRINCIPALNAME() returns user@contoso.com format. However, upon publication to the Power BI service, both functions return the user’s UPN (User Principal Name), which resembles an email address. This behavioral shift means that DAX expressions authored in Desktop using USERNAME() may produce different results after publish, and teams must audit their filter expressions post-migration. Additionally, when a Power BI Desktop report is published to a workspace, RLS roles are applied to members assigned the Viewer role in that workspace. Even Viewers who are granted Build permissions to the semantic model remain subject to RLS filtering—for instance, when using “Analyze in Excel.” Conversely, workspace members with Admin, Member, or Contributor roles have edit permission for the semantic model and, consequently, RLS does not apply to them. To ensure RLS takes effect for workspace users, those users must be assigned the Viewer role exclusively.
For organizations leveraging Microsoft Fabric, RLS management shifts slightly. Within a Fabric workspace, users can access the Row-Level Security page by hovering over a semantic model and selecting the More options menu, then Security. Here, members can be added to existing roles by email address or name. However, only users with the workspace Contributor role or higher (and who also have semantic model ownership or Build permissions, depending on the scenario) can see and use the Security option. If a semantic model lacks RLS roles defined in Power BI Desktop or via the Power BI service editor, the Security page will not appear, underscoring the necessity of defining roles at the model authoring layer before they can be administered in the service.
Security and Governance Implications
Row-level security intersects with multiple layers of enterprise governance, including identity management, data classification, and audit requirements. From an identity perspective, RLS integrates with Microsoft Entra ID for user and group membership. The Power BI service supports adding Microsoft Entra security groups to RLS roles, as well as direct email addresses of individual users. Notably, Microsoft 365 groups are not supported for RLS role membership; only the specific group types listed by Microsoft—primarily Microsoft Entra security groups—are permissible. This restriction has implications for organizations that have standardized on Microsoft 365 groups for role-based access control across the Microsoft ecosystem. Admins must either convert group types or assign members individually, which can increase administrative overhead.
A significant governance concern arises when RLS roles include external B2B guest users. Microsoft Entra security groups that contain B2B guests might not be correctly evaluated by the Power BI service when enforcing RLS filters, particularly when the guest account is of guest-type rather than member-type. In such configurations, the guest’s group membership may not be resolved, leading to either no data being visible or, conversely, data leakage if the group evaluation is inconsistent. Microsoft’s recommended workaround is to add external users directly to RLS roles by email address, bypassing group membership resolution entirely. The email address is resolved to the user’s B2B account, ensuring a deterministic match when RLS filters are applied.
For dynamic RLS using USERPRINCIPALNAME(), the identity returned by the function may vary depending on tenant configuration. In B2B scenarios, USERPRINCIPALNAME() can return either the external user’s email address (e.g., user@partner.com) or a tenant-resolved value in the #EXT# format (e.g., user_partner.com#EXT#@tenant.onmicrosoft.com). The exact format is not guaranteed and must be validated in the specific environment. If the user-mapping table stored in the semantic model uses a different identifier format than what USERPRINCIPALNAME() returns for guest users, the filter expression will not match, and the guest will see no data or incorrect data. A pragmatic mitigation is to store identifiers in the mapping table using the email address format and to create a test measure displaying USERPRINCIPALNAME() in a card visual, viewed by the external user to confirm the returned value.
The USERNAME() function exhibits similar behavior for B2B guests; it often returns a UPN-like identifier rather than a traditional domain\username format. Because USERNAME() and USERPRINCIPALNAME() frequently return the same value for B2B guests, most implementations standardize on USERPRINCIPALNAME() for consistency. However, if an organization’s existing dynamic RLS uses USERNAME(), administrators must verify what value the function returns for guest users in their environment before sharing content externally. The safest approach is to align the user-mapping table with the output of USERPRINCIPALNAME(), typically using an email-style column, and to test with actual guest accounts rather than relying on the Test as role feature.
Test as role is a powerful validation tool, but it has strict limitations that govern its usefulness in governance workflows. The feature uses the current signer’s identity when evaluating dynamic RLS expressions, meaning USERPRINCIPALNAME() will return the signer’s UPN, not that of the simulated user. This makes Test as role incapable of revealing what a specific B2B guest user or service principal would see. Additionally, Test as role does not work for DirectQuery semantic models with single sign-on (SSO) enabled, paginated reports, Q&A visualizations, Quick insights, or Copilot suggestions. For DirectQuery models with SSO, the only reliable validation method is to sign in as an actual Viewer-role user and observe the data filtering in situ. Furthermore, Test as role only reports on reports located within the same workspace as the semantic model; dashboards and reports in other workspaces are not accessible through this feature. Organizations must therefore incorporate manual sign-in validation as part of their RLS deployment pipeline, especially for external user scenarios.
Service principals—a common pattern for embedded analytics and automated data pipelines—face an additional governance barrier. Service principals cannot be added to RLS roles, and consequently, RLS is not applied for apps using a service principal as the final effective identity. In these scenarios, dynamic RLS functions such as USERPRINCIPALNAME() and USERNAME() return the service principal’s application ID or an empty string, not an end user’s identity. This means per-user filtering based on these functions is fundamentally unworkable in service principal embedding scenarios, and alternative identity-passing mechanisms (such as CUSTOMDATA() passed via the Power BI REST API) must be employed.
Another often-overlooked limitation involves the USERELATIONSHIP() function. When RLS is enabled, using USERELATIONSHIP() in DAX queries and measures might cause unexpected errors. The recommended workaround is to redesign DAX expressions to avoid USERELATIONSHIP() and instead rely on model-level relationships or alternative DAX patterns. This constraint affects many advanced analytics patterns that depend on dynamic relationship switching and requires careful DAX refactoring during the RLS enablement process.
For Direct Lake models in Microsoft Fabric, RLS is supported, but as noted earlier, query fallback to DirectQuery mode alters performance characteristics. Additionally, the Test as role feature does not fully replicate the authentication context of other users, and certain visualization types (Q&A, Quick insights, Copilot) cannot be validated through this tool. Administrators should complement automated testing with manual user acceptance testing, particularly for reports intended for external or guest audiences.
Why This Matters to Enterprise IT
For enterprise IT leaders, Row-level security is not merely a feature toggle; it is a strategic enabler of data governance at scale. As organizations consolidate analytics workloads onto Power BI and Microsoft Fabric, the volume of semantic models grows exponentially. Without RLS, each business unit or regulatory requirement would necessitate a separate model, report, or data mart, inflating infrastructure costs, increasing maintenance overhead, and fragmenting the analytics user experience. RLS collapses this multiplicity by allowing a single, well-modeled semantic server to serve diverse audiences while respecting granular data boundaries. This consolidation directly translates to lower storage costs, simpler upgrade cycles, and a more cohesive semantic layer that serves as a single source of truth across the enterprise.
Moreover, RLS is a critical control for compliance with privacy regulations such as GDPR, CCPA, and HIPAA. By ensuring that users only access rows containing data they are authorized to see, RLS reduces the risk of unauthorized data exposure and supports data minimization principles. IT teams can demonstrate to auditors that access controls are enforced at the model layer, rather than relying on network-level permissions or report-level hiding, which are more easily circumvented. In regulated industries, the ability to produce a test measure showing USERPRINCIPALNAME() output and validate that RLS filters match the user-mapping table provides a tangible artifact for compliance evidence.
The extension of RLS into Microsoft Fabric also reshapes the governance landscape. Fabric’s lakehouse architecture introduces Direct Lake semantic models, which bring real-time lake query capabilities into the Power BI ecosystem. RLS on Direct Lake models must coexist with the lakehouse’s open table formats, OneLake storage, and shortcut-based data ingestion. IT teams must understand how RLS filters are translated into lake query predicates, especially when fallback to DirectQuery occurs. Monitoring tools within the Fabric capacity metrics app become essential observability pillars, complementing traditional Power BI monitoring. For organizations adopting a Fabric-first strategy, RLS governance policies must be updated to cover lakehouse tables, warehouse objects, and the interplay between Power BI RLS and lake-level security mechanisms such as Azure Synapse row-level security or Microsoft Entra object-level permissions.
Finally, the operational reality of managing RLS across hybrid environments—import, DirectQuery, Direct Lake, and live connection models—demands a unified governance framework. Inconsistent RLS implementation across connection modes can create blind spots where certain user groups see data they shouldn’t, or vice versa. A comprehensive RLS strategy should inventory all semantic models, document the connection mode and RLS status for each, and establish standardized role-naming conventions, DAX expression patterns, and testing procedures. This framework reduces the risk of configuration drift and ensures that RLS policies evolve in tandem with data model changes.
EBS Consulting Perspective
From a consulting standpoint, the most common RLS implementation we encounter is a hybrid of static and dynamic patterns, often under-scoped during the initial design phase. Many organizations begin with static roles—fixed DAX expressions that restrict data to a constant value—and later discover that maintenance becomes burdensome as the user base grows or organizational hierarchies shift. Dynamic RLS, particularly when powered by USERPRINCIPALNAME(), offers a scalable alternative, but it shifts the complexity from role management to user-mapping table maintenance. The user-mapping table, which links each user’s sign-in identifier to the data rows they should see, must be kept in sync with Microsoft Entra ID changes, name changes, group membership updates, and B2B guest lifecycle events. Failure to maintain this mapping is the single most frequent root cause of RLS failures we observe in production.
Our experience also suggests that teams frequently underestimate the impact of workspace role interactions on RLS behavior. A prevalent anti-pattern is assigning Build or Contributor permissions to workspace users who should only view data. Because RLS only applies to Viewer-role members, those with higher workspace permissions will see the unfiltered dataset regardless of their assigned RLS role. We routinely advise clients to audit workspace permissions in tandem with RLS configuration, and where possible, restrict edit permissions to a small superuser group while granting the majority of users the Viewer role. This alignment simplifies the security model and ensures that RLS functions as intended without requiring users to toggle between roles or permissions.
Another area where we see avoidable rework is the handling of B2B guest access. Many clients initially attempt to add external users to RLS roles via Microsoft Entra security groups, only to encounter the group resolution limitations documented by Microsoft. The workaround—adding guests by email address—is simple but requires a one-time addition per external user, which can be administratively heavy for organizations with thousands of partner users. In these cases, we recommend a hybrid approach: use dynamic RLS with USERPRINCIPALNAME() and a centrally maintained user-mapping table, supplemented by a process to periodically synchronize the mapping table with Entra ID attributes (such as the Mail or UserPrincipalName fields). For high-volume B2B scenarios, we also explore embedding patterns that pass CUSTOMDATA() from the host application, which bypasses the need for RLS roles entirely by encoding the effective identity in the request context. However, this approach requires coordination between the Power BI developer and the embedding application team, and it foregoes the centralized role-management benefits of the Power BI service.
Finally, we counsel clients to treat the Test as role feature as a developmental validation tool, not a governance or compliance validation tool. The feature’s limitations—particularly its inability to simulate B2B guests, service principals, or DirectQuery SSO scenarios—mean that it should be used early in the development cycle to catch syntax errors, broken column references, or role-combination issues. For pre-production and production validation, sign-in as actual users representing each audience segment is non-negotiable. We help clients build automated testing scripts that cycle through a roster of test user accounts (created in a dedicated test tenant or Azure AD domain) and capture screenshots or data snapshots for regression testing. This approach provides a repeatable validation pipeline that integrates with CI/CD tools for Power BI deployments, ensuring that RLS policies remain intact as models evolve.
Practical Next Steps
For organizations beginning or revisiting their RLS journey, we recommend the following sequential actions:
- Audit the current semantic model landscape. Inventory all Power BI and Fabric semantic models, documenting the connection mode (import, DirectQuery, Direct Lake, live connection), existing RLS status, and workspace role assignments. Identify models that lack RLS and prioritize them based on data sensitivity and user volume.
- Standardize role naming and DAX expression patterns. Establish a naming convention for RLS roles (e.g., "RLS_[Department]_[Region]") and a library of approved DAX patterns for static and dynamic filtering. Document these standards in a governance wiki to ensure consistency across development teams and prevent the proliferation of ad-hoc role definitions.
- Refactor user-mapping tables for dynamic RLS. If adopting dynamic RLS, design or refactor the user-mapping table to store identifiers in the format returned by
USERPRINCIPALNAME()—typically an email address. Validate the mapping against a sample of internal and external users, using a test measure displayingUSERPRINCIPALNAME()in a card visual. Document the mapping strategy and build a reconciliation process to keep the table aligned with Entra ID changes. - Implement workspace permission alignment. Review workspace permissions for each semantic model ensuring that users who should only view data are assigned the Viewer role, and that edit permissions are restricted to a minimal, audited group. This alignment is foundational to RLS taking effect and avoids the common pitfall of higher-permission users bypassing filters.
- Configure RLS in Power BI Desktop first, then publish. Define all roles and DAX filter expressions in Power BI Desktop using the DAX editor for any dynamic rules. Publish the model to the Power BI service, and only then add members to roles via the Service Security page. This order ensures that role definitions are transported as part of the model metadata and reduces the risk of roles being created in the service without corresponding DAX expressions.
- Establish a testing protocol that includes real-user validation. While Test as role is useful for development, create a formal validation step where test users from each audience segment (internal employees, B2B guests, service-principal-driven apps) sign in and verify data filtering. For B2B guests, explicitly check the
USERPRINCIPALNAME()output and confirm it matches the mapping table. Log these validations as part of the deployment checklist. - Monitor query fallback and performance in Fabric. If using Direct Lake semantic models in Microsoft Fabric, enable the capacity metrics app and track query fallback rates. Investigate any reports where RLS filters coincide with increased DirectQuery fallback, and consider model optimization or DAX refinements to reduce fallbacks. Set up alerts for sustained performance degradation that coincides with RLS-enabled queries.
- Plan for service principal and embedded analytics scenarios. If the organization embeds Power BI reports in custom applications using service principals, recognize that RLS based on
USERPRINCIPALNAME()orUSERNAME()will not function. Design the embedding flow to pass CUSTOMDATA() via the Power BI REST API, and ensure that the application context provides the effective identity required for per-user filtering. Document this pattern and socialize it with both the Power BI and development teams.
By following these steps, enterprises can move from ad-hoc RLS implementations to a governed, scalable framework that balances security, usability, and operational efficiency. The investment in proper role design, mapping table hygiene, and validation processes pays dividends in reduced support tickets, smoother compliance audits, and a more trustworthy analytics platform.
Row-level security in Power BI and Microsoft Fabric is a powerful, nuanced capability that sits at the intersection of data modeling, identity management, and performance engineering. Mastery of its architectural details, implementation patterns, and governance constraints distinguishes mature BI operations from those still struggling with data silos and access leaks. For enterprise IT leaders, the cost of misconfigured RLS is not merely filtered reports—it is regulatory risk, eroded user trust, and escalating infrastructure complexity. The path forward requires a disciplined approach: standardize role definitions, align workspace permissions, maintain user-mapping tables with rigor, and validate against real user identities rather than simulated contexts. When these practices are embedded into the analytics lifecycle, RLS becomes a reliable foundation for secure, scalable self-service BI across the enterprise.
Escape Business Solutions consulting teams are available to assist with RLS assessments, role design workshops, user-mapping table implementation, and Fabric-integrated governance frameworks. Reach out to discuss how we can help secure your analytics estate while unlocking the full value of your data.
EBS Consulting Advice
If your organization is evaluating Row-level security (RLS) with Power BI - Microsoft Fabric, do not treat the technology decision in isolation. Start with the business outcome, current architecture, security and identity controls, operational constraints, migration dependencies and governance requirements. A practical assessment should identify the current-state gaps, prioritize the risks and define an implementation roadmap with measurable outcomes.
EBS can help assess the environment, develop the architecture and modernization roadmap, and translate the technical options into an actionable business plan. Relevant EBS services: Microsoft Azure consulting Escape Cloud Microsoft Solution Assessments.
Have a technology challenge? Email info@escapebusinesssolutions.com to describe your situation. We welcome questions, consulting discussions and requests for a proposal.
Discover more from Escape Business Solutions
Subscribe to get the latest posts sent to your email.
