Row-Level Security (RLS) is a data-filtering feature in Power BI that ensures each user sees only the rows of data they are authorised to view. It matters for the PL-300 exam because you will be asked to create, test, and troubleshoot RLS rules in real reports, and the exam directly tests your ability to identify the correct way to set up role-based filters and dynamic security using Microsoft Entra ID.
Jump to a section
A simple way to picture Row-Level Security (RLS)
A busy restaurant kitchen on a Friday night. Three waiters hand order slips to the head chef, but the chef refuses to cook until each slip is parsed through a special filter. The chef does not see the full menu or the total orders—only the dishes assigned to his section. One waiter submits a ticket for table 4: two steaks, one pasta. The filter checks the chef’s ID badge, sees he’s assigned to ‘Grill Section’, and shows him only the steak orders. The pasta order disappears from his view entirely. Another waiter at the same table orders a dessert. The filter routes that to the pastry chef, not to the head chef. The map to the filter works like this: each chef has a role (e.g., ‘Grill Chef’, ‘Pastry Chef’). The system uses a ‘role filter’ to decide what orders each chef can see. The head chef never sees the full order for table 4—only the part relevant to him. This is exactly how Row-Level Security (RLS) works in Power BI. The ‘orders’ are rows of data. The ‘chefs’ are users. The ‘filter’ is an RLS rule built in DAX. The rule checks who the user is (usually their email or user principal name) and hides any rows they are not allowed to see. The user never knows the hidden rows exist—they get a perfectly complete-looking report that simply does not contain the forbidden data.
Row-Level Security, or RLS, is a way to restrict what data a specific user can see inside a Power BI report. Instead of building separate reports for each department, manager, or region, you build one report and then tell Power BI, ‘User A sees only rows where Region = West, and User B sees only rows where Region = East.’ Power BI does the hiding automatically at the row level.
To understand RLS, you need to know a few key terms. A ‘role’ is a named group with a set of permissions. For example, ‘Sales Managers’ could be one role. A ‘rule’ is a DAX expression that returns either TRUE or FALSE for each row. DAX stands for Data Analysis Expressions, the formula language of Power BI. The rule says, ‘Only show this row if the current user’s email matches the email in this column.’ DAX expressions look like this: [SalesRepEmail] = USERPRINCIPALNAME(). USERPRINCIPALNAME() is a built-in DAX function that returns the email address of the user viewing the report. When the rule evaluates each row, it checks if the email in that row matches the logged-in user’s email. If it matches, the row is visible. If not, the row is completely hidden.
RLS works only after a report is published to the Power BI Service, not in Power BI Desktop. In Desktop you define the roles and rules, but you cannot see the filtering until you ‘View As’ a specific role. When you publish the report, you then go to the Power BI Service, open the dataset settings, and assign users (from Microsoft Entra ID) to the roles you created. Microsoft Entra ID is the identity service that holds all user accounts for a Microsoft cloud environment. It used to be called Azure Active Directory.
There are two main approaches to RLS: static and dynamic. Static RLS means you define a rule that uses a fixed value, like [Region] = ‘West’. Every user in the role gets the same filter. Dynamic RLS means the rule uses the current user’s identity, like USERPRINCIPALNAME() = [Email]. Each user sees only their own data. Dynamic is more flexible because you do not need a separate role for each person.
RLS replaced the old method of creating multiple copies of the same report with different data sources or filters for each audience. That approach was slow, error-prone, and cluttered. RLS makes data governance simpler: one report, one dataset, but different views for different people. It is important to know that RLS does not encrypt or secure data at rest—it only controls what is visible in the report. A determined user with access to the underlying dataset could still extract the full data if they have other permissions. RLS is a reporting-layer control, not a database security measure.
Another critical detail: RLS applies to measures and calculated tables, but it cannot limit access to the data model itself if someone connects directly to the dataset with an external tool (like Excel or a dashboard in a different app). That is why organisations often combine RLS with other security controls, like object-level security (OLS) and data-source permissions.
When you create an RLS rule in Power BI Desktop, you use the Manage Roles button in the Modelling tab. You give the role a name, then choose a table and write a DAX expression that returns TRUE or FALSE. The expression is evaluated per row. You can use any standard DAX function: FILTER, CALCULATE, KEEPFILTERS, and the security-related functions like USERNAME(), USERPRINCIPALNAME(), and CUSTOMDATA(). USERNAME() returns the user’s Windows logon (not usually useful for cloud reports), so USERPRINCIPALNAME() is the one you will use most often.
After publishing, in the Power BI Service, you go to the dataset, click Security, then add individuals or groups from Microsoft Entra ID to each role. A person can belong to multiple roles, and if they do, they see the union of all rows allowed by all their roles. Be careful: if the rule hides a whole table because of a relationship error, the user sees a blank report. This is a common trap in the exam.
RLS is also respected when a report is embedded in a custom application (Power BI Embedded) or shared via a Power BI App. However, if you allow users to Build permissions (create their own reports from your dataset), they might bypass RLS unless you also apply RLS at the dataset level. The exam tests this nuance: RLS is bypassed when someone builds a new report using the dataset unless restrictive permissions are in place.
Identify the data table and the user attribute to filter on
First, decide which table has the rows you want to hide (e.g., Sales) and which column in that table identifies the user (e.g., SalesRepEmail). You also need a separate table that maps each user’s identity (email from Microsoft Entra ID) to their filter value (e.g., region). This step is crucial because without a mapping table, dynamic RLS (using USERPRINCIPALNAME()) cannot work.
Create a role in Power BI Desktop using Manage Roles
In the Modelling tab, click Manage Roles. Give the role a descriptive name like ‘RegionalManager’. Select the table you want to filter (Sales). Then write a DAX expression, e.g., [Region] = LOOKUPVALUE(Users[Region], Users[Email], USERPRINCIPALNAME()). This expression tells Power BI to look up the current user’s email in the Users table, grab their region, and then show only sales rows where the region matches.
Test the role with View As in Power BI Desktop
Click View As, check the role you created, and optionally provide a test user principal name (like ‘west@shopco.com’). Power BI Desktop temporarily applies the filter. You must confirm that the report displays only the expected rows. This step catches logic errors before you publish—for example, if a test user sees no data, you know the LOOKUPVALUE failed or the mapping table is incomplete.
Publish the report and navigate to dataset Security settings in the Power BI Service
Once you are satisfied with the test, publish the report to your Power BI workspace. Then go to the Workspace, find the dataset, click the three dots (More options), and select Security. This is the only place where you assign actual users or groups to roles. The roles you defined in Desktop will appear here automatically.
Assign users or Microsoft Entra ID security groups to the role
Under the role name, click Add Members. Type the email addresses of individuals or the name of a security group from Microsoft Entra ID. Using a security group is the recommended approach because when a company hires a new regional manager, the IT team simply adds that person to the Entra ID group—Power BI inherits the membership without any manual update.
Verify by signing in as the assigned user and viewing the report
Open a private browser session (incognito) or sign out of your normal Power BI account. Sign in with the test user’s credentials and open the report. Confirm that the visuals show only that user’s permitted rows. Also test a user not in any role—they should receive an error or see nothing depending on sharing permissions, but they should not see data they should not.
Monitor and troubleshoot using the dataset’s security logs and DAX queries
If a user reports seeing incorrect data, check whether they belong to multiple roles (which creates a union). Use the ‘View As’ feature again in Desktop—simulate their exact user identity. If the data is still wrong, examine the relationship between the mapping table and the filtered table. A missing or inactive relationship is the most common cause of RLS failure.
Imagine you are a Power BI analyst at a national retail company called ShopCo. The company has 30 regional sales managers, each responsible for one region. The CEO wants one master sales report that every manager can use, but each manager must see only their own region’s data. You cannot build 30 separate reports—that would be a maintenance nightmare. Instead, you build one report with RLS.
Here is what you actually do, step by step. First, you open the dataset in Power BI Desktop. You have a table called ‘Sales’ with columns: Region, SalesRep, Revenue, Date. You also have a table called ‘Users’ with columns: Email, Region, Role. You build a relationship between Users[Region] and Sales[Region].
Second, you click Manage Roles in the Modelling tab. You create a role called ‘Regional Manager’. In the DAX formula bar, you write: [Region] = LOOKUPVALUE(Users[Region], Users[Email], USERPRINCIPALNAME()). This reads the current user’s email, finds their region in the Users table, and then filters the Sales table to show only rows where the Region matches.
Third, you test the role using the ‘View As’ button under the ribbon. You select the role, then type in or select a test user’s principal name. Power BI Desktop shows you exactly what that user would see—you can confirm the data is filtered correctly. You also test a user who should see no data to ensure the rule does not break (it should show a blank visual, not an error).
Fourth, you publish the report to the Power BI Service. You navigate to the dataset, click the Security icon. You see your ‘Regional Manager’ role listed. You click Add Members and type the email addresses of the actual regional managers from Microsoft Entra ID. You can add individuals or security groups. Using security groups is better administration because you manage access in Microsoft Entra ID when a manager leaves or joins.
Fifth, you share the report with all managers by giving them Viewer access through a Power BI App. You do not give Build permission or Contributor access to the dataset, because that would let them bypass RLS by creating their own reports from the same dataset. You only give them App Viewer access.
Now each manager logs into Power BI, opens the app, and sees the exact same sales report—but with different numbers. The Western manager sees only rows where Region = West. The Eastern manager sees only East. The CEO, if added to a special role with no filter (or to a role where the rule allows all rows), sees the entire dataset. If a bug happens—like a manager seeing no data—you troubleshoot by checking three things:
Is the user’s email correctly spelled in the Users table?
Is the relationship between Users and Sales active and correct?
Has the user been assigned to the role in the dataset Security settings?
If a manager accidentally sees another region’s data, the most likely cause is a missing or incorrect relationship, or a DAX expression that evaluates to TRUE for more rows than intended. You would use DAX Studio or run DAX queries to debug the expression.
The PL-300 exam tests RLS in several specific ways. Expect multiple-choice questions, case studies, and drag-and-drop tasks. The most common question pattern gives you a scenario—e.g., ‘A regional manager must see only their own region’s data’—and asks you to choose the correct implementation or identify why an existing RLS setup is broken.
Key exam topics you must memorise:
The difference between static and dynamic RLS. Static RLS uses a fixed value in the rule (e.g., [Region] = ‘West’). Dynamic RLS uses a function like USERPRINCIPALNAME() to match the current user to a data column. The exam will ask you to identify which method is appropriate for a given scenario. Dynamic is correct for most real-world cases unless the scenario explicitly says all members of a role share one filter.
The correct DAX function to identify the current user. The answer is nearly always USERPRINCIPALNAME(). They might show you USERNAME() in a distractor; USERNAME() returns the Windows logon string, not the email, and is rarely correct for cloud Power BI. Also know that CUSTOMDATA() exists but requires a custom token passed in an embedded scenario—not common in the exam.
The requirement that RLS is applied after publish. They often trap you with a statement like ‘You can test RLS for all users directly in Power BI Desktop.’ That is false. Desktop only lets you test one role at a time via ‘View As’.
The fact that RLS is bypassed when users have Build permission on the dataset. The exam loves asking: ‘A user can see only 5 rows in the report, but when they create a new report using the same dataset, they see all 1000 rows. Why?’ The answer is Build permission bypasses RLS. The correct fix is to remove Build permission and share the report only through an App with Viewer rights.
The behaviour when a user belongs to multiple roles. They see the union of visible rows. Not the intersection. Not a single role. The exam might give you two roles, one filtering to Region = West and one to Region = East, and ask what a user in both roles sees—they see all rows for both regions.
The error condition: a blank report. If a user has no matching data after RLS filters, they see empty visuals, not an error message. The exam might present this as ‘a user complains the report is blank’ and ask you how to troubleshoot—you check if the user is assigned to a role, if the DAX rule is correct, and if the user’s email appears in the lookup table.
The restriction that RLS cannot filter on measures or calculated columns that are not in the row context. It works on row-level data in tables. If a rule tries to filter on a measure, it will give an error or not apply as expected.
The relationship between RLS and DirectQuery. When the dataset uses DirectQuery (querying a live SQL database), the RLS rule is sent to the source database as part of the query. This can be a security advantage because the source controls the data, but it can also cause performance issues if the rule is complex.
The exam’s trap patterns:
They give an RLS rule that looks correct but uses a different column name than the one in the Users table. The correct answer is ‘The relationship is incorrect or missing.’
They describe a scenario where a manager should see only their own data, but the proposed solution creates a role for each manager individually (static separate roles). That is an anti-pattern. The correct answer is one dynamic role with USERPRINCIPALNAME().
They suggest using the ‘Security’ tab in Power BI Desktop to assign users. That tab does not exist—assignment happens in the Power BI Service only.
Memorise this: RLS = Manage Roles (Desktop) + Security (Service) + USERPRINCIPALNAME() + DAX rule returning TRUE/FALSE per row.
Row-Level Security (RLS) is a data-filtering technique that restricts which rows of a table a user can see and is defined using DAX rules in the Manage Roles dialog of Power BI Desktop.
The DAX functions USERPRINCIPALNAME() and USERNAME() return the identity of the current report viewer; USERPRINCIPALNAME() is the appropriate choice for cloud-based Power BI Service deployments.
RLS rules are only enforced after a report is published to the Power BI Service and users are assigned to roles within the dataset’s Security settings.
Users assigned to multiple roles see the union (not intersection) of all rows allowed by each role they belong to.
RLS does not apply when someone uses Build permission to create their own report from the same dataset—this is a common security gap that the PL-300 exam tests heavily.
When a user sees a completely blank report after RLS is applied, the most likely cause is that the DAX rule returns FALSE for every row, often due to a missing email in the lookup table or an incorrect relationship.
Dynamic RLS uses the current user’s identity to filter rows, making it scalable; static RLS uses a fixed value and is only appropriate when all users in a role share exactly the same filter.
RLS cannot be added on top of a Power BI dataset that uses a live connection to an external Analysis Services model—security must be handled at the source.
The ‘View As’ feature in Power BI Desktop is used for testing roles before publication and does not require real users—you can type any test email address.
Always use Microsoft Entra ID groups instead of individual user accounts for role membership to simplify administration and keep the PL-300 examination scenario clean.
These come up on the exam all the time. Here's how to tell them apart.
Static RLS
Uses a fixed value in the DAX rule (e.g., [Region] = 'West')
Requires a separate role for each distinct filter value
Does not use any user-identity function like USERPRINCIPALNAME()
Dynamic RLS
Uses the current user's identity to determine the filter (e.g., USERPRINCIPALNAME())
Requires only one role regardless of how many filter values exist
Needs a supporting mapping table that links user identities to filter values
Row-Level Security (RLS)
Hides or shows entire rows of data based on a DAX filter
Defined using Manage Roles in Power BI Desktop
Cannot hide individual columns or tables
Object-Level Security (OLS)
Hides or shows entire columns or tables (objects) from certain roles
Defined using Tabular Editor (external tool) or XMLA endpoints
Can make a column completely invisible while leaving rows visible
RLS in Import Mode
Data is cached in Power BI; the DAX rule runs locally on the cached data
Performance is predictable because all data is already in memory
Requires re-import if underlying data changes (scheduled refresh)
RLS in DirectQuery Mode
Data stays in the source database; the DAX rule is sent to the source as part of the query
Performance depends on the source database’s ability to handle the filter pushdown
Always uses the latest data from the source, but can be slower if the rule is complex
Microsoft Entra ID User (Individual)
Must be manually added to each RLS role one by one
If a user leaves, you must remove them from all RLS roles individually
Harder to audit and manage at scale
Microsoft Entra ID Security Group
Add the group once to the RLS role; group membership is managed in Entra ID
When a user leaves, remove them from the group, and they lose access instantly from all resources
Simpler administration for organisations with many users or frequent changes
USERPRINCIPALNAME()
Returns the user’s email address from Microsoft Entra ID
The correct choice for cloud Power BI Service reports
Works consistently across enterprise and external guest accounts
USERNAME()
Returns the user’s Windows domain\username string
Primarily used for on-premises reports connected to SQL Server or SSRS
Does not return a useful email for cloud scenarios
RLS at Dataset Level
Defined in the dataset Security tab; applies to all reports built on that dataset
Can be bypassed if a user has Build permission on the dataset
Persists even if the report is exported or embedded
RLS at App Level (Power BI App Permissions)
Only controls who can see the App containing specific reports
Does not apply RLS filtering by itself—it only controls access to the App
Must be combined with dataset-level RLS for actual row filtering
Mistake
RLS in Power BI Desktop works automatically after I publish, without doing anything in the Service.
Correct
RLS rules are defined in Desktop, but users must be assigned to roles in the Power BI Service under dataset Security settings. The rules alone block nothing until a user is mapped to a role.
Desktop is a development environment. It has no actual user identities from Microsoft Entra ID, so it cannot know who will view the report. The mapping has to happen in the cloud.
Mistake
If I set up RLS, the hidden data is encrypted and cannot be extracted by any user.
Correct
RLS only controls what is visible in the report. Any user with direct access to the dataset (e.g., through SQL Server Management Studio, Excel, or Build permissions) can bypass RLS and see all rows.
RLS is a presentation-layer filter, not a data encryption or access control on the data source itself. Beginners conflate authentication (who can log in) with authorisation (what data they can see).
Mistake
A user who sees a blank report after RLS means the user has no role assigned.
Correct
A blank report usually means the user has a role, but the DAX rule returns FALSE for all rows (no data matches), OR the user’s email is missing from the lookup table. A user with no role at all would get a permission error, not a blank report.
Beginners see a blank visual and assume the user is not authorised, when the real issue is usually a data mismatch or a typo in the email lookup.
Mistake
You can apply RLS to a Power BI report that uses a live connection to a SQL Server Analysis Services (SSAS) tabular model directly from the Power BI Service.
Correct
When a Power BI dataset uses a live connection to an external data source like SSAS, the security is managed at the source, not by Power BI. Power BI RLS cannot be added on top of a live connection. You must use the source’s own row-level security.
This is a classic exam trick. The dataset says ‘Live Connection’, and the proposed answer includes defining an RLS role in Power BI. That will not work. The student must know the limitation.
Mistake
RLS filters apply equally to all visual types, including tooltips and drillthrough pages.
Correct
RLS does apply to all parts of a report, but drillthrough pages and tooltips respect the same role filters as the main report—unless the drillthrough target uses a different security context. It is possible to accidentally expose hidden data if a drillthrough page does not inherit the filter.
Power BI’s drillthrough behaviour is not obvious. Beginners may think once RLS is set, it protects everywhere, but a badly designed drillthrough page that uses a different table or column could bypass the filter.
Mistake
I can test RLS by publishing a report and signing in as a different user in my browser without changing anything in the Service.
Correct
To test RLS for a different user, you must either use the ‘View As’ feature in Power BI Desktop (which works with any test email) OR assign that user to the role in the Service and then sign in as that user—you cannot just switch accounts without the role assignment.
Beginners think publishing itself enables all roles automatically. They do not realise that the role definition on Desktop is just a blueprint; the Service holds the actual membership list.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
USERNAME() returns the user’s Windows domain and username (for on-premises data sources), while USERPRINCIPALNAME() returns the user’s email-style identifier (e.g., user@company.com) from Microsoft Entra ID. For cloud-based Power BI Service reports, always use USERPRINCIPALNAME().
Yes, but only if the live connection is to a Power BI dataset that itself uses a data source that supports RLS. If the live connection goes directly to a SQL Server Analysis Services (SSAS) tabular model, the security must be defined in the SSAS model, not in Power BI Desktop. Power BI RLS cannot be added on top of a live connection to SSAS.
Yes, RLS is respected during exports because the export process runs in the same security context as the report viewer. The exported file contains only the rows the user is allowed to see. However, if the user has direct access to the dataset via a different tool, they could still get the full data.
The user will see the union of rows allowed by each role. For example, if Role A filters to Region = West and Role B filters to Region = East, the user sees both West and East data. It is not an intersection—Power BI combines all rows that pass at least one role’s filter.
The most common causes are: the user’s email in the mapping table is misspelled, the relationship between the mapping table and the filtered table is missing or inactive, or the user was added to the role in the Power BI App but not in the dataset Security settings. Double-check the dataset Security tab, not the App permissions.
RLS filters apply to regular tables and can affect calculated tables that depend on those tables, but you cannot write an RLS rule directly on a calculated table or on a measure. The filter must be applied to a row-level table. Measures are dynamic aggregations and are not row-level objects.
No. You should use dynamic RLS with the USERPRINCIPALNAME() function and a mapping table that contains each user’s email and the filter value (e.g., region). This way you need only one role, and the DAX expression automatically picks the right filter for whoever is viewing. Creating individual roles is an anti-pattern that does not scale.
You've finished Row-Level Security (RLS). Continue through the PL-300 study guide to build a complete picture of the exam.
Done with this chapter?