Forum Discussion
Configure RLS for multiple external customers?
- 1 year ago
Hi BozPLR
Your current approach—creating a separate RLS role for each customer and manually assigning users by email—may work for a small number of customers, but it becomes unsustainable and difficult to manage at scale as the number of customers and users grows. Instead, the best practice for this kind of multi-tenant scenario is to use dynamic RLS with a mapping table that ties each user’s email (User Principal Name) to their respective customer ID or group. This approach allows you to maintain a single role in your Power BI semantic model and apply RLS based on the logged-in user's identity, greatly simplifying management.
Here’s how to implement it:
Create a security table that includes two columns: one for user email (UPN) and one for the customer ID they belong to. For example, SecurityTable = { UserEmail: "[email protected]", CustomerID: "Cust1" }.
Relate this table to your main data table (which should also have a CustomerID field) either directly or via a dimension table.
In the Power BI Model > Manage Roles, create a single role (e.g., CustomerAccess) and apply the DAX filter on the SecurityTable:
SecurityTable[UserEmail] = USERPRINCIPALNAME()
This ensures each user only sees data linked to their customer.
When you publish to the Power BI Service, you do not need to assign users to roles manually—Power BI automatically evaluates RLS based on who is logged in and what their UPN maps to in the table.
To share with external customers, you need to invite guest users into your tenant using Azure AD B2B (Business-to-Business), and assign them viewer permissions in the workspace or via Power BI Apps. Free users cannot view shared content unless the workspace is in Premium capacity.
This dynamic RLS setup is scalable, secure, and far easier to maintain than hardcoding roles per customer. It also accommodates future customers simply by updating the mapping table with new user-customer entries, without modifying the model itself.
Hi BozPLR
Your current approach—creating a separate RLS role for each customer and manually assigning users by email—may work for a small number of customers, but it becomes unsustainable and difficult to manage at scale as the number of customers and users grows. Instead, the best practice for this kind of multi-tenant scenario is to use dynamic RLS with a mapping table that ties each user’s email (User Principal Name) to their respective customer ID or group. This approach allows you to maintain a single role in your Power BI semantic model and apply RLS based on the logged-in user's identity, greatly simplifying management.
Here’s how to implement it:
Create a security table that includes two columns: one for user email (UPN) and one for the customer ID they belong to. For example, SecurityTable = { UserEmail: "[email protected]", CustomerID: "Cust1" }.
Relate this table to your main data table (which should also have a CustomerID field) either directly or via a dimension table.
In the Power BI Model > Manage Roles, create a single role (e.g., CustomerAccess) and apply the DAX filter on the SecurityTable:
SecurityTable[UserEmail] = USERPRINCIPALNAME()
This ensures each user only sees data linked to their customer.
When you publish to the Power BI Service, you do not need to assign users to roles manually—Power BI automatically evaluates RLS based on who is logged in and what their UPN maps to in the table.
To share with external customers, you need to invite guest users into your tenant using Azure AD B2B (Business-to-Business), and assign them viewer permissions in the workspace or via Power BI Apps. Free users cannot view shared content unless the workspace is in Premium capacity.
This dynamic RLS setup is scalable, secure, and far easier to maintain than hardcoding roles per customer. It also accommodates future customers simply by updating the mapping table with new user-customer entries, without modifying the model itself.
- BozPLR1 year agoFrequent Visitor
Thank you for your response! I have had trouble finding the tenant/viewer permissions, so I have not had a chance to fully test it out. Once I figure out how to get them to appear and test, I will accept this as a solution.
- BozPLR1 year agoFrequent Visitor
I have tried your approach, and I am having trouble getting it to filter my dashboard appropriately.
I have created a Security Table, and linked it to the table with all of our customers by Customer_ID. The Customer Master is linked to other tables such that selecting a customer from the Customer Master filters everything else. This works before interacting with the Security Table.
Within the Security Table, I have an email address mapped to a Customer ID for testing purposes.
I have created a security role and set the filter on the security table to account for USERPRINCIPALNAME()
However, when I test as that specific email, everything is hidden from me.
Do you have any suggestions?
- BozPLR1 year agoFrequent Visitor
This is resolved. The issue was that the Security Row filter was searching for the literal string "USERPRINCIPALNAME()". Switching to the DAX editor and removing the quotation marks had it pulled successfully.
Power BI really needs to clean up its interface. Switching between three languages is cumbersome.