Row-Level Security in Power BI: how to make sure the right people see the right data

You have built a powerful Power BI report. The data is clean, the visuals are sharp, and the insights are exactly what your organisation needs. But then comes the question that every data professional eventually faces: how do you make sure that each user only sees the data that is relevant to them, and nothing more?

The answer is Row-Level Security. In this guide, we explain what it is, how it works, and how to implement it correctly, from basic static roles to dynamic RLS with complex data models.


What is Row-Level Security in Power BI?

Row-Level Security, commonly abbreviated as RLS, is a feature in Power BI that restricts data access at the row level within a dataset. Rather than creating separate reports for different user groups, RLS allows you to build a single report and control what each user or role can see, based on rules you define.

In practice, this means a sales manager in Germany sees only German revenue figures, while their counterpart in France sees only French data, even though both are looking at the exact same report. The underlying dataset is shared, but the view is personalised and secured.

RLS is applied at the dataset level, not at the report or dashboard level. This is an important distinction: even if a user accesses the data through a different report or via the Power BI API, the security rules still apply.


Static RLS vs. Dynamic RLS

Power BI offers two approaches to Row-Level Security: static and dynamic. Understanding the difference is essential before you start building.

Static RLS

With static RLS, you manually define roles and assign fixed filter rules to each role. For example, you create a role called “Germany” and apply the filter [Country] = "Germany" to the relevant table. You then assign specific users to this role in the Power BI Service.

Static RLS is straightforward to set up and works well for a limited number of fixed user groups. However, it becomes unmanageable quickly. If your organisation has fifty regional teams, maintaining fifty separate roles, each with manually assigned users, is not a scalable solution.

Dynamic RLS

Dynamic RLS solves the scalability problem by using the identity of the logged-in user to filter data automatically. Instead of hardcoded filter values, you use the DAX function USERPRINCIPALNAME() or USERNAME() to retrieve the email address or username of the current user, and match it against a security table in your data model.

A typical setup looks like this: you have a dedicated security table in your dataset that maps each user’s email address to the data they are allowed to see, for example a region, a department or a customer ID. The RLS rule then filters the data based on this mapping, dynamically, for every user, without any manual role assignment.

Dynamic RLS is more complex to set up initially, but it is far more powerful and maintainable. Adding a new user simply means adding a row to the security table, rather than modifying roles in Power BI Desktop and republishing the report.


Setting up Row-Level Security: a step-by-step guide

Step 1: Design your data model

Before writing a single DAX expression, think carefully about your data model. RLS works best when your security logic is clean and centralised. If you need dynamic RLS, make sure you have a dedicated security table that contains at minimum two columns: the user identifier (typically the email address) and the value used to filter the data (such as a region, department or customer ID).

Ensure this security table has a relationship to the fact table or dimension table you want to filter. The relationship direction matters: in most cases, a single-direction relationship from the security table to the dimension table is sufficient.

Step 2: Define your roles in Power BI Desktop

Open your report in Power BI Desktop and navigate to the Modelling tab. Click on “Manage Roles” to open the role editor.

For static RLS, create a new role and enter a DAX filter expression directly on the relevant table. For example, to restrict data to Germany, select the Geography table and enter:

[Country] = "Germany"

For dynamic RLS, the expression will reference the current user’s identity. A typical dynamic filter on a security table looks like this:

[UserEmail] = USERPRINCIPALNAME()

This tells Power BI to filter the security table so that it only returns rows where the UserEmail column matches the email address of the logged-in user. Because of the relationship between the security table and your fact or dimension tables, this filter propagates automatically through the model.

Step 3: Test your roles in Power BI Desktop

Before publishing, always test your roles using the “View as” feature in Power BI Desktop. This allows you to preview the report exactly as a specific user or role would see it. Navigate to the Modelling tab, click “View as Roles”, select the role you want to test, and verify that the data is filtered correctly.

For dynamic RLS, you can simulate a specific user by entering their email address in the “Other user” field. This is invaluable for catching issues before they reach production.

Step 4: Publish and assign users in the Power BI Service

Once you are satisfied with your roles, publish the report to the Power BI Service. In the Service, navigate to the dataset settings, select “Security”, and assign users or Azure Active Directory groups to each role.

For dynamic RLS, the assignment is simpler: typically all users are assigned to a single dynamic role, and the DAX expression handles the filtering based on their individual identity. You do not need to create a separate role for each user.


Common pitfalls and how to avoid them

Bidirectional relationships and RLS

One of the most common sources of confusion with RLS involves bidirectional relationships in the data model. By default, Power BI applies filters in one direction along a relationship. If you enable bidirectional cross-filtering, filters can propagate in both directions, which can sometimes bypass RLS rules in unexpected ways.

The safest approach is to avoid bidirectional relationships on tables that are subject to RLS, unless you fully understand the implications. If you need bidirectional filtering for specific measures, consider using DAX functions like CROSSFILTER within the measure itself, rather than enabling it at the model level.

RLS and calculated tables

Calculated tables in Power BI are computed at report load time and do not support dynamic RLS filtering in the same way as regular tables. If your security logic depends on calculated tables, test thoroughly to ensure the filters apply as expected.

RLS does not apply to dataset owners

An important limitation to be aware of: users who are assigned the Admin, Member or Contributor role on a workspace in the Power BI Service are considered dataset owners and bypass RLS entirely. RLS only applies to users who access the report as a Viewer. This is by design, but it means your internal data team will always see unfiltered data, regardless of any RLS rules you have configured.

Performance considerations

RLS filters are applied at query time, which means they add overhead to every query. For large datasets with complex security tables, this can impact report performance. To mitigate this, ensure your security table is as small and clean as possible, and that the join columns are indexed in the underlying data source where applicable. Using DirectQuery with RLS requires particular attention, as every user interaction triggers a live query to the data source with the RLS filter applied.


RLS and external report sharing

Row-Level Security works seamlessly when reports are shared within the Power BI Service, but what happens when you want to share reports with people outside your Microsoft 365 tenant, such as clients, partners or external stakeholders?

This is where things get more complex. Standard Power BI sharing requires recipients to have either a Power BI Pro licence or access to a Premium capacity. For external users, this typically means either purchasing licences for everyone who needs access, setting up Azure Active Directory B2B guest accounts, or using a dedicated sharing solution that handles external access and RLS enforcement independently.

Each of these approaches has trade-offs in terms of cost, complexity and user experience. The right choice depends on the number of external users, how frequently they access the reports, and how much control you need over the data they see.


Practical recommendations

Row-Level Security is a powerful feature, but it requires thoughtful design to work well at scale. A few recommendations to keep in mind:

Start with dynamic RLS wherever possible. The initial setup takes more time, but the long-term maintainability is vastly superior to managing dozens of static roles.

Keep your security table in the data source, not in Power BI. If your user-to-data mapping lives in your data warehouse or a SQL table, you can update it without touching the Power BI report or dataset. This separates security management from report development.

Document your RLS design. As reports evolve and team members change, undocumented security logic becomes a liability. A simple diagram showing which tables are filtered and how users are mapped to data goes a long way.

Test with real user accounts before going live. The “View as” feature is useful, but nothing replaces testing with actual accounts to confirm that the correct data is visible, and that no data leaks occur through measures, tooltips or drillthrough pages.


Taking RLS further with a branded sharing portal

Once your RLS setup is solid, you may find that the challenge shifts from securing the data to distributing the reports. Sharing reports externally at scale, while maintaining RLS enforcement, branding consistency and a smooth user experience, is a challenge that goes beyond what the standard Power BI Service offers out of the box.

Solutions like Webdashboard are built specifically for this scenario. They sit on top of your existing Power BI environment, respect the RLS rules you have already defined, and allow you to share reports through a branded portal without requiring recipients to have Power BI licences. If you are at the point where your data security is solid but your distribution setup is holding you back, it is worth exploring what dedicated sharing solutions can offer.


Conclusion

Row-Level Security is one of the most valuable features in Power BI for any organisation that needs to share data with multiple audiences. When implemented correctly, it allows you to maintain a single, well-governed dataset while giving each user a personalised and secure view of the data.

The key to success lies in choosing the right approach for your use case, designing a clean data model from the start, testing thoroughly before deployment, and keeping your security logic maintainable as your organisation grows.

Done well, RLS becomes invisible to your users. They simply see their data, and nothing else.


Webdashboard helps organisations share Power BI reports securely with internal and external users, with RLS fully respected. Learn more at webdashboard.nl.