Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

To celebrate FabCon Vienna, we are offering 50% off select exams. Ends October 3rd. Request your discount now.

Reply
rask
Frequent Visitor

Implementing Dynamic Product Name Masking Based on RLS in Power BI

In my Power BI report, I have:

  1. A Products table with ProductID, ProductName, ManagerEmailand Category

  2. A Sales table with SaleID, ProductID, Region, and Revenue (many-to-one relationship with Products)

  3. Row-Level Security (RLS) rules where:

    • Sales Manager by default have access to specific category. 
    • Sometime Sales manager is given access for other category temporarily.

I need to:

  • Display a table visual with ProductName, Category, Regionand Revenue

  • Dynamically mask product names based on RLS:

    • Show full name for products the Manager has access to category by default.

    • Show "####" for products names when a user has temporary access to other Category. 

 

MaskedProductName =
VAR currentUser = USERPRINCIPALNAME()
VAR loggedIn_user_Category= LOOKUPVALUE(Products[Category]), Products[ManagerEmail], currentUser)
RETURN
IF(
CONTAINSTRINGS(SELECTEDVALUE(Products[Category],loggedIn_user_Category),
SELECTEDVALUE(Products[ProductName]),
"####"
)

 

Issues Facing:

1) When Region is added the rows are duplicated according to regions.

2) Above measure doesn't work when the ProductName column is not added

1 ACCEPTED SOLUTION

Hello @rask,
Thank you for reaching out to the Microsoft Fabric Community Forum.

I have reproduced your scenario in Power BI and I got the expected behavior where:

  • The default category for each manager shows the real product name.
  • The additional categories (temporary access) display the product name as masked (####).

For your reference, I am attaching a sample .pbix file that demonstrates this solution end-to-end. You can open it in Power BI Desktop and test it using the “View as Role” option to simulate different managers (alice@company.com or bob@company.com)

 

Best Regards,
Ganesh singamshetty.

View solution in original post

6 REPLIES 6
v-ssriganesh
Community Support
Community Support

Hello @rask,

We hope you're doing well. Could you please confirm whether your issue has been resolved or if you're still facing challenges? Your update will be valuable to the community and may assist others with similar concerns.

Thank you.

v-ssriganesh
Community Support
Community Support

Hello @rask,

Hope everything’s going great with you. Just checking in has the issue been resolved or are you still running into problems? Sharing an update can really help others facing the same thing.

Thank you.

v-ssriganesh
Community Support
Community Support

Hi @rask,

Thank you for posting your query in the Microsoft Fabric Community Forum, and thanks to @DataNinja777 for sharing valuable insights.

 

Could you please confirm if your query has been resolved by the provided solutions? This would be helpful for other members who may encounter similar issues.

 

Thank you for being part of the Microsoft Fabric Community.

DataNinja777
Super User
Super User

Hi @rask ,

 

Your current approach is facing issues because its DAX logic and data structure are not ideal for this scenario. The main problem is trying to determine a user's default category directly from the large Products table, which is unreliable and inefficient. A much more robust solution involves creating a dedicated table specifically to manage user permissions. This change will simplify both your Row-Level Security (RLS) and the dynamic masking logic.

The first and most critical step is to create a new table, which we'll call ManagerAccess. You can create this using the "Enter Data" feature in Power BI. This table should have three columns: ManagerEmail, Category, and a crucial new column named AccessType. In the AccessType column, you'll explicitly state whether a manager's access to a given category is "Default" or "Temporary". For example, manager.a@company.com could have a row with the category "Electronics" and AccessType "Default," and another row for "Apparel" with AccessType "Temporary." Once this table is created, you must establish a relationship between ManagerAccess[Category] and Products[Category], with the ManagerAccess side being the "one" side of a one-to-many relationship.

With this new structure, your RLS rule becomes incredibly simple. You only need to create one role, perhaps named "Sales Manager," and apply a single DAX expression to the ManagerAccess table. This filter will handle all security for you.

[ManagerEmail] = USERPRINCIPALNAME()

This expression filters the ManagerAccess table to only the rows matching the logged-in user. Because of the data model relationship, this filter automatically propagates to the Products table and subsequently to your Sales table, correctly restricting the data view for both default and temporary access types.

Now, you can create the DAX measure that will dynamically mask the product names. This measure should be created in your Products table and will replace the original ProductName column in your report visuals.

MaskedProductName = 
VAR currentUser = USERPRINCIPALNAME()
VAR currentProductCategory = SELECTEDVALUE(Products[Category])

-- Find the user's single "Default" category, ignoring filters from the visual.
VAR userDefaultCategory =
    CALCULATE(
        SELECTEDVALUE(ManagerAccess[Category]),
        ManagerAccess[ManagerEmail] = currentUser,
        ManagerAccess[AccessType] = "Default",
        REMOVEFILTERS() -- This is crucial to get the global default setting for the user.
    )

RETURN
    IF(
        -- Check if the product's category matches the user's default category
        currentProductCategory = userDefaultCategory,
        SELECTEDVALUE(Products[ProductName]), -- If yes, show the full product name.
        "####"                                -- If no (it must be temporary access), mask it.
    )

This measure works by first identifying the category of the product in the current row of your visual. Then, using CALCULATE combined with REMOVEFILTERS, it looks up the user's single "Default" category from the ManagerAccess table, completely ignoring the visual's current filters. This is the key to avoiding context errors. Finally, it compares the product's category to the user's default category. If they match, it shows the full product name; otherwise, it displays "####". To use this, you must remove the original Products[ProductName] column from your table visual and add this new [MaskedProductName] measure in its place.

This refined approach directly solves your original problems. The row duplication issue with the Region column is resolved because the measure correctly evaluates at the proper granularity without interfering with the visual's context. Furthermore, the measure is self-contained and does not depend on the original ProductName column being present in the visual, as it fetches the name itself. This method represents a standard best practice for implementing this type of dynamic security and display logic in Power BI.

 

Best regards,

@DataNinja777  Thank you for your reply. I have created a separate Manager table as you suggested with two columns ManagerName and DefaultCategory . But regarding AccessType column, the Manager is given access to category dynamically. Its not possible to add AccessType column. For eg. In manager access table, Manager X has access to Electronics category by default. Later he is given access to Home decor and at some point later he is given access to Clothes. 

Can you provide a solution for this?

Hello @rask,
Thank you for reaching out to the Microsoft Fabric Community Forum.

I have reproduced your scenario in Power BI and I got the expected behavior where:

  • The default category for each manager shows the real product name.
  • The additional categories (temporary access) display the product name as masked (####).

For your reference, I am attaching a sample .pbix file that demonstrates this solution end-to-end. You can open it in Power BI Desktop and test it using the “View as Role” option to simulate different managers (alice@company.com or bob@company.com)

 

Best Regards,
Ganesh singamshetty.

Helpful resources

Announcements
September Power BI Update Carousel

Power BI Monthly Update - September 2025

Check out the September 2025 Power BI update to learn about new features.

August 2025 community update carousel

Fabric Community Update - August 2025

Find out what's new and trending in the Fabric community.

Top Kudoed Authors