Ravindra BagaleCourses & study guides मराठी Track your progress

26. Row-Level Security (RLS)

26.3 Dynamic RLS with USERPRINCIPALNAME in Power BI, with Example

Start with a problem

Next year there will be 60 cities. Ravindra cannot keep creating roles.

Explain simply

Dynamic RLS uses a security table (Email → City) and USERPRINCIPALNAME() to filter by the signed-in user.

Show the data

Email City
ravindra@example.com Pune
shraddha@example.com Nashik
zoya@example.com Kolhapur
salman@example.com Pune
salman@example.com Nashik

About this data: This table uses columns: Email, City. This table uses columns: User (email), City in security table, Rows visible, Total Sales (₹). This table uses columns: Other user, Cities visible. Values shown are the lesson examples already on this page (not a new dataset).

Fictional sample data. Practice file: rls_user_security.csv, visuals_orders_apr_may_2026.csv (source: src/practice/).

Demonstrate

  1. Import rls_user_security.csv as Security.
  2. Relate Security[City] to a City dimension (or Orders[City]) – Security filters City.
  3. Manage roles › role ByUser on Security: [Email] = USERPRINCIPALNAME().
  4. Ensure the filter flows to Orders (single direction City → Orders; Security → City).
  5. View as › Other user salman@example.com + role ByUser.

Show the result

Dynamic RLS with a security table, sample layout with fictional data

Your result should look like this (fictional sample):

User (email) City in security table Rows visible Total Sales (₹)
ravindra@example.com Pune 301, 302, 306 850
shraddha@example.com Nashik 303, 304, 307 800
zoya@example.com Kolhapur 305, 308 450
salman@example.com Pune, Nashik 6 orders 1,650
Rani (no role, workspace Viewer with all-cities role) All 301–308 2,100

Explain what happened

USERPRINCIPALNAME returns the email; the matching Security rows filter City, which filters Orders.

Explore further

  • Add a new manager by adding a row – no model change.

Detailed reference for this lesson:

Dynamic RLS with USERPRINCIPALNAME in Power BI with example — in 30 seconds

What: Dynamic RLS uses the signed-in e-mail. One role works for every manager.

Why: Six cities today, sixty tomorrow. You update a table, not the roles.

Tiny example: ravina@example.com is mapped to Pune and Mumbai, so she sees both.

First look at the data (before → after):

Dynamic RLS with USERPRINCIPALNAME in Power BI with example: before and after tables, fictional Blinkit Maharashtra data

Same before / after tables as text

Before — User Security table

Email City
ravindra.bagale@example.com Pune
shraddha.bagale@example.com Nashik
ravina@example.com Pune
ravina@example.com Mumbai

Formula / click path

[City] IN CALCULATETABLE(VALUES('User Security'[City]),
    'User Security'[Email] = USERPRINCIPALNAME())

After — View as › Other user

Other user Cities visible
ravindra.bagale@example.com Pune
shraddha.bagale@example.com Nashik
ravina@example.com Pune, Mumbai
new.user@example.com (nothing)

Do it step by step:

  1. Load the User Security table. Do not relate it (Option A).
  2. Manage roles › New → City Manager → table DarkStore → paste the rule.
  3. Save. Click View as. Tick Other user and type ravina@example.com. Tick City Manager.
  4. Check: Pune and Mumbai only.
  5. Hide the User Security table from report view.

USERPRINCIPALNAME() returns the sign-in name of the current user, usually their e-mail-style address (UPN), such as shraddha.bagale@example.com. The rule compares this to a column in the data.

Simple version – one manager per city

The DarkStore table has a Manager Email column (for example, every Pune store row has ravindra.bagale@example.com, every Nashik row has shraddha.bagale@example.com). Create one role called City Manager with this rule on the DarkStore table:

[Manager Email] = USERPRINCIPALNAME()

Now every manager, when signed in, sees fakt the dark stores – and therefore only the orders – where their e-mail matches.

Flexible version – a security (mapping) table

When a user may see several cities, or a city has several users, create a table User Security:

Email City
ravindra.bagale@example.com Pune
shraddha.bagale@example.com Nashik
shahrukh@example.com Nagpur
zoya@example.com Kolhapur
amir@example.com Mumbai
raja@example.com Sambhaji Nagar
ravina@example.com Pune
ravina@example.com Mumbai

Here Ravina (a regional lead in this example) can see both Pune and Mumbai.

Option A – without any relationship to the security table, use this rule on DarkStore:

[City]
    IN CALCULATETABLE(
        VALUES('User Security'[City]),
        'User Security'[Email] = USERPRINCIPALNAME()
    )

Option B – relate User Security to a City dimension, filter 'User Security'[Email] = USERPRINCIPALNAME(), and allow the filter to flow onwards (this usually requires a bi-directional relationship with Apply security filter in both directions enabled). Option A avoids bi-directional relationships and is usually simpler.

Hide the User Security table from report view (users do not need to see it).

USERNAME vs USERPRINCIPALNAME

USERNAME() in Power BI Desktop returns the Windows format DOMAIN\user, while in the Service it returns the UPN. USERPRINCIPALNAME() returns the UPN format consistently when users are signed in, so it is the usual choice for dynamic RLS.

A role that sees everything

For the state operations head (Rani in our sample), create a role (e.g. All Cities) with no filter – or give access in a way where RLS does not apply (see below).

Dynamic RLS is a little tricky, but do not worry. A security table and USERPRINCIPALNAME – there are only these two pieces.

Ravindra Bagale's Tip

Friends, the mistake I see most is an e-mail in the security table that doesn't match the user's sign-in name (an old domain, an alias or extra spaces; DAX text comparison ignores upper/lower case). Check USERPRINCIPALNAME() by showing it in a card while testing, and keep the security table's relationship filtering in the right direction. Practise, and it will feel very easy.

Fix common mistakes

Wrong result Reason Correction
Everyone sees blank Email mismatch (case/UPN differs) Use exact UPN; test with View as
Filter does not reach Orders Relationship direction Check the filter path
Salman sees one city Only one row Add both rows

Practise independently

Practice task

Add raja@example.com, Kolhapur. What does Raja see?

Hints
  • Kolhapur rows.
Solution

305, 308 – ₹450.

Think like a professional

Dynamic RLS is the scalable pattern – explain table + UPN + relationship.

Ravi Sir's Cards for this lesson

मराठी cards