Row-level security (RLS) in Power BI lets you show the right rows to the right people without creating separate reports for each user or region. In this tutorial, we’ll walk through what RLS is, when to use it, how to set it up (static and dynamic), and some best practices.
What is Row-Level Security in Power BI?
Row-level security in Power BI restricts which rows of data a user can see in a report or dataset. Instead of giving everyone access to all rows, you define rules so each user only sees data that belongs to them (for example, their region, department, or customers).
Typical scenarios:
- Sales reps should only see their own region’s sales.
- Managers should see their team’s data, not the whole company.
- External clients should only see their own data in a shared report.
RLS works at the model level. That means once you define it on the dataset, the same rules apply to all reports built on that dataset.
Check out Create Ribbon Chart in Power BI
Types of Row Level Security (RLS): Static vs Dynamic
There are two main ways to set up RLS in Power BI.
Static RLS
Static RLS uses hard-coded filters in your roles.
Example:
- Role:
US_East_Sales - Filter:
[Region] = "East"
Everyone assigned to this role will always see only East region data.
Static RLS is fine when:
- You have a small number of regions or groups.
- Access rules rarely change.
Dynamic RLS
Dynamic RLS uses the logged-in user’s identity (email or username) and a security table to work out what they can see.
Common patterns:
- Filter by user’s email using
USERPRINCIPALNAME(). - Map users to regions, departments, or branches in a separate “security” table and join it to your fact table.
Dynamic RLS is better when:
- You have many users.
- One user may have access to multiple regions or departments.
- Access rules change often, and you want to manage them in data, not in Power BI roles.
Read Power BI Slicer Filter Another Slicer
Before You Start: Prepare Your Data Model
RLS works best on a clean, relational model in Power BI.
Key points:
- Use a star schema where possible: fact table in the center (Sales), dimension tables around it (Date, Customers, Regions, Users).
- Put RLS filters on dimension tables (like Region or User) rather than fact tables.
- Make sure relationships are correctly defined and active so filters can propagate.
For dynamic RLS, you usually need a dedicated security table:
- Columns like:
UserEmail,Region,Department, orCustomerID. - Relationships from this table to the fact/dimension tables you want to secure.
This lets you change access simply by updating rows in the security table, instead of editing roles.
Check out Format Table Visual in Power BI
Step-by-Step: Static RLS in Power BI Desktop
Let’s start with a simple static RLS setup where each role can see only one region. For this, I have already created a Power BI report like the screenshot below.

1. Create a role
- Open your report in Power BI Desktop.
- Go to the Modeling tab.
- Click Manage roles.
- Click Create, and give the role a clear name, for example
Sales_RepsorRegion_East_Sales.
2. Add a table filter
- Under Tables, select the table you want to filter (for example,
CustomersorRegions). - Next to the table, choose Add filter and pick the column you want to use (for example,
Customer LocationorRegion). - In the DAX filter box, enter an expression that returns true/false, such as:
[Customer Location] = "Florida"- or
[Region] = "East"
- Click the check icon to validate, then select Save.

You can see the screenshot below the Table filter DAX expression.

Now, any user assigned to this role will only see rows where the filter expression is true.
3. Test the role in Desktop
- On the Modeling tab, click View as.
- Select the role you just created.
- Click OK and check your visuals. You should now only see the filtered region or locations.
- Click Stop viewing when done. Here is a screenshot for your reference.

This is a great way to confirm the filter logic is correct before publishing.

Check out Create Date Range Slicer in Power BI
Step-by-Step: Publish and Assign Users in the Service
RLS only takes effect for end users in the Power BI Service (or Report Server).
1. Publish the report
- In Power BI Desktop, go to Home > Publish.
- Choose a workspace (ideally a shared or app workspace, not My workspace) and publish.
2. Assign users/groups to roles
- Go to the Power BI Service.
- Open the workspace where you published the report.
- Find the dataset (not just the report), select the More (…) menu, and click Security.
- You’ll see the roles you created in Desktop.
- For each role, add users or security groups to the Members box and click Add / Save.

Like in the screenshot below:

Assigning groups instead of individual users makes maintenance easier over time.
Check out Replace Blank Values with Zero in Power BI Matrix Visual
Dynamic RLS with Username or Email
Static RLS breaks down when you have many users or frequently changing access rules. Dynamic RLS solves this by using the logged-in user’s identity.
Option 1: Simple dynamic filter on a column
If your table already has a column that matches the user’s email or login, you can filter directly on that.
Example:
- Your
SalesRepstable has a[LoginEmail]column. - Each row corresponds to one sales rep and their region.
Steps:
- In Manage roles, create a role like
Dynamic_Sales_Reps. - Add a filter on the
SalesRepstable. - Use a DAX filter such as:
[LoginEmail] = USERPRINCIPALNAME()
USERPRINCIPALNAME() returns the user’s login name (usually email) in the Power BI Service.
- Save the role and publish as before.
Now, when someone opens the report, Power BI will filter SalesReps to just their row, and that filter will flow to related tables.
Option 2: Security table for many-to-many access
Sometimes a user needs to see multiple regions, departments, or clients. In that case, use a separate security table that maps users to allowed values.
Example UserRegionSecurity table:
UserEmailRegionCode
You might have multiple rows per user if they cover multiple regions.
Steps:
- Add the security table to your model.
- Create a relationship between
UserRegionSecurity[RegionCode]and yourRegionorSalestable. - In Manage roles, create a role like
Dynamic_Region_Access. - Add a DAX filter on the security table, for example:
[UserEmail] = USERPRINCIPALNAME()
- Save, publish, and assign users as usual.
Now, each user will see all regions listed in UserRegionSecurity for their email.
Testing Dynamic RLS
You should always test dynamic RLS from the user’s point of view.
In Power BI Desktop:
- Use Modeling > View as and check Other user.
- Enter an email or username that exists in your security table.
- Confirm that only the expected rows show up.
In Power BI Service:
- On the dataset’s Security page, use Test as role.
- Pick a role and, if available, test as a specific user.
This helps catch mistakes like missing relationships or typos in emails.
Check out Hide or Remove Column Headers on Power BI Matrix Visual
Object-Level Security vs Row-Level Security
Row-level security limits which rows users can see; object-level security (OLS) limits which tables or columns they can see.
You might combine them when:
- Users can see sales numbers but not salary or cost columns.
- Users should not see certain lookup tables at all, even if they can see related facts.
OLS is defined in the model and lets you hide entire columns or tables from specific roles. It’s a useful extra layer when working with sensitive data.
Best Practices
A few practical tips to keep your RLS setup clean and performant:
- Keep role names clear and consistent, like
Region_East_SalesorDynamic_Region_Access. - Prefer filters on dimension or security tables instead of large fact tables to keep queries fast.
- Avoid unnecessary bidirectional relationships; enable “Apply security filter in both directions” only when you really need it.
- Centralize user-to-data mappings in security tables so you can change access by editing data, not roles.
- Use security groups (from Entra ID/Azure AD) in role memberships rather than adding individual users one by one.
- Document your roles, DAX filters, and security tables so someone else can understand and maintain them later.
A simple example setup that works well in real projects:
- Fact table:
Sales - Dimension tables:
Date,Customer,Region - Security table:
UserRegionSecurity (UserEmail, RegionCode) - Role:
Dynamic_Region_Accesswith filter[UserEmail] = USERPRINCIPALNAME()onUserRegionSecurity
This pattern scales easily as your number of users and regions grows. Once RLS is in place, you can safely share a single report with many users while keeping each person’s view limited to just their own data.
Conclusion
Row-level security is one of those features that quietly makes your Power BI reports production-ready. Once you set up the right roles and security tables, you can share a single report with many users and still control exactly what each person sees.
Start simple with static RLS, then move to dynamic RLS as your model and user base grow. With a bit of upfront planning, you get cleaner security, fewer duplicate reports, and a setup that’s much easier to maintain over time.
You may also like the following tutorials:
- 2 Various Ways to Change the Visual in Power BI
- Enable Multiple Selections in Power BI Slicer
- Convert Base64 to PDF Using Power BI
- Apply Conditional Formatting in Power BI Bar Chart

After working for more than 18 years in Microsoft technologies like SharePoint, Microsoft 365, and Power Platform (Power Apps, Power Automate, and Power BI), I thought will share my SharePoint expertise knowledge with the world. Our audiences are from the United States, Canada, the United Kingdom, Australia, New Zealand, etc. For my expertise knowledge and SharePoint tutorials, Microsoft has been awarded a Microsoft SharePoint MVP (12 times). I have also worked in companies like HP, TCS, KPIT, etc.
Hi. My report has more than 1 tabs and I want someone to see only 1 tab. How to do that since I don’t have the paid version of PowerBi and don’t have tabular editor in external tools?