11.1 Row-Level Security (RLS)
Key Takeaways
- Row-Level Security (RLS) restricts data access at the row level based on user identity and role membership.
- RLS roles are defined in Power BI Desktop using DAX filter expressions and tested with 'View as Role'.
- Static RLS uses hard-coded filter values (e.g., Region = 'West'); dynamic RLS uses USERPRINCIPALNAME() for identity-based filtering.
- RLS roles are assigned to users or security groups in the Power BI Service after publishing.
- OLS (Object-Level Security) hides entire tables or columns from specific roles, complementing RLS.
Row-Level Security (RLS)
Quick Answer: Row-Level Security (RLS) filters data rows based on who is viewing the report. Define roles in Desktop with DAX filter expressions, then assign users to roles in the Service. Static RLS hard-codes filter values; dynamic RLS uses USERPRINCIPALNAME() to automatically filter based on the logged-in user's identity. RLS is one of the most heavily tested topics on the PL-300.
What is Row-Level Security?
Row-Level Security (RLS) restricts which rows of data a user can see, based on their assigned role. Two users viewing the same report see different data based on their permissions.
Example:
- Manager for West region sees only West region data
- Manager for East region sees only East region data
- VP of Sales sees all regions
Creating RLS Roles
In Power BI Desktop
Modeling tab → Manage Roles
→ Create new role → Name it (e.g., "West Region")
→ Select table → Write DAX filter expression
Static RLS
Hard-coded filter values in the role definition:
// Role: "West Region"
// Table: Sales
[Region] = "West"
// Role: "East Region"
// Table: Sales
[Region] = "East"
Pros: Simple to set up Cons: Need separate roles for each filter value; doesn't scale well
Dynamic RLS
Uses the logged-in user's identity to filter automatically:
// Role: "Regional Manager"
// Table: Sales
// Assumes a UserRegion table maps users to their regions
[Region] = LOOKUPVALUE(
UserRegion[Region],
UserRegion[Email],
USERPRINCIPALNAME()
)
How it works:
- When a user opens the report, Power BI evaluates USERPRINCIPALNAME()
- This returns the user's email address (e.g., "john@contoso.com")
- The LOOKUPVALUE finds their assigned region in the UserRegion mapping table
- The filter restricts Sales rows to only that region
Dynamic RLS with Security Table
Step 1: Create a security mapping table:
| Region | |
|---|---|
| john@contoso.com | West |
| sarah@contoso.com | East |
| mike@contoso.com | North |
Step 2: Create a relationship between the security table and the data model
Step 3: Define the role with a filter on the security table:
// Role: "Dynamic Region"
// Table: UserRegion
[Email] = USERPRINCIPALNAME()
Because the UserRegion table has a relationship to the Sales table, the filter propagates automatically through the model.
Advantages of dynamic RLS:
- One role for all users
- Changes to permissions only require updating the mapping table
- Scales to hundreds or thousands of users
- No need to update roles when users change
Testing RLS
In Power BI Desktop
Modeling tab → View as Roles
→ Select role(s) to test
→ Optional: Enter a specific username for dynamic RLS testing
→ Click OK — report shows filtered data
Testing checklist:
- ✅ Users see only their allowed data
- ✅ Totals reflect only visible data (not grand totals)
- ✅ All visuals respect the RLS filter
- ✅ Cross-filtering between visuals works correctly
- ✅ DAX measures respect the filter context from RLS
Assigning Users to Roles
In the Power BI Service
Workspace → Dataset → Security (or "..." → Security)
→ Select role → Add members
→ Enter email addresses or security group names
→ Save
Best practices for assignment:
- Use Azure AD security groups instead of individual emails
- Assign groups to roles → manage group membership in Azure AD
- This centralizes access management and simplifies auditing
Role Assignment Rules
- Users not assigned to any role see all data (no RLS applied)
- Workspace Admins and Members always see all data regardless of RLS
- Only Viewers and Contributors (and app consumers) are subject to RLS
- A user can be assigned to multiple roles — their access is the UNION of all role filters
RLS with Different Configurations
RLS + DirectQuery
RLS works with DirectQuery, but:
- The RLS filter is added to every query sent to the source
- Source database must handle the additional filtering
- Performance may be impacted by complex RLS expressions
RLS + Live Connection to Analysis Services
- RLS is defined in the Analysis Services model, not in Power BI
- Power BI passes the user's identity to Analysis Services
- SSAS handles the row-level filtering
RLS + Shared Datasets
When a shared semantic model has RLS:
- All reports built on the shared model inherit the RLS
- Users see filtered data regardless of which report they use
- RLS is enforced at the dataset level, not the report level
Object-Level Security (OLS)
OLS hides entire tables or columns from specific roles:
- Defined in Tabular Editor or XMLA endpoint
- Users in restricted roles cannot see the hidden tables/columns
- Complements RLS (which filters rows, not columns/tables)
Example: Hide the Salary column from the Manager role while keeping it visible for the HR role.
On the Exam
The PL-300 frequently tests:
- Choosing between static and dynamic RLS
- Writing DAX filter expressions for RLS roles
- Understanding USERPRINCIPALNAME() in dynamic RLS
- Testing RLS with "View as Roles"
- Assigning users to roles in the Power BI Service
- Knowing that Admins/Members are not subject to RLS
A company has 50 regional managers, each of whom should only see data for their region. What is the most scalable RLS approach?
A workspace Admin opens a report that has RLS configured. The Admin is not assigned to any RLS role. What data do they see?
In a dynamic RLS setup, which DAX function returns the email address of the currently logged-in user?