How to implement Page Level Security by using Row Level Security (RLS) in Power BI Desktop
By: Allen Tseng
Tags: Power Bi, Data Modelling, Tips And Tricks, Row Level Security, Microsoft Power Bi

Power BI’s May 2020 desktop update finally provides report builders the ability for users to perform page navigation conditionally. This means you’re able to use “page navigation” as an action on buttons rather than using a bookmark to navigate to a certain page on your report, an old school method. This button can be static or dynamic (conditionally formatted).

However, sometimes you may want to hide certain pages from specific users or user groups and though you can use the “Hide Page” option to hide a page, this will hide it from all users, which is not what we want. Although Microsoft hasn’t provided an official way to do this, if you combine this new conditional page navigation feature with row level security (RLS), you can custom create and enforce a page level security, or tab level security specific to the report.

I will illustrate how to do that using made up Avengers data:

Step 1: Import or create your user table

The user table only requires three columns: 1) the user’s login, 2) their email, and 3) a column called role that will be created using a formula. I recommend the SWITCH TRUE combination. The role can be whatever you want it to be, in our example it will be either Director, Main Avenger or Support Avenger.

Our little Avengers user table :)

Step 2: Create three new tables for: page level security, roles, and a bridge table for the previous two

The page level security table, which will ultimately conditionally control the visibility of pages to the users should comprise of: a page name column, a page order column (integers, so that you can sort the page name column by this column’s order), and as many columns as you have roles, so if you have three roles, have a column for each. You should end up with a matrix like below:

Page Level Security table

Under the columns that represent each role, fill out 1 or 0.

1 means the page is visible to the corresponding page name and role intersection. 0 means the page is not visible.

The role table is a one column table that is just distinct values of your roles, so if there are three roles, there are three records. In our example it looks like this:

Role table

And finally, the page-role bridge table. This table is simply a cross-join of the page level security table and the role table, but we only need to keep two columns: page name and role. If you’re familiar with database design, you may have also recalled hearing these as link tables. To create this table, we create it using DAX functions: SELECTCOLUMNS and CROSSJOIN.

Page-Role Bridge table

The highlighted code in red:

page-role bridge =

SELECTCOLUMNS (

CROSSJOIN ( 'page level security', role ),

"Page Name", 'page level security'[Page Name],

"Role", role[Role]

)

Now that we have our four tables, link them up:

page level security table — page-role bridge table — role table — user table

Your model should look like this:

Note: These tables should be hidden as they control the report’s navigation functionality.

Step 3: Create a navigation filter on page names

Create a filter and drop in the “page name” column from the page level security table. Be sure to set the filter selection option to “single select”.

This will serve as a navigation menu.

Step 4: Add an action button that uses conditional page navigation

Go to any page and add a button. Under the button’s visualization pane, go to “Action” and select page navigation. Under page navigation, select the “fx” button:

This will bring open a dialogue box that lets you set the conditional navigation for the destination of the page navigation. We want to select the page name column and set it to “First”:

Click OK once complete (cropped out of this photo).

Place the button next to the filter like below:

Select an option and press Ctrl + “GO”. You won’t need to press Ctrl once this is published to PowerBI Service or the Report Server.

Step 5: Turn on Row Level Security

The last step is to turn on and apply row level security, which cascades to enable our unofficial “page level security”.

In your menu, navigate to the Modelling pane and select “Manage roles”. When the dialogue box appears, click “Create” and create your roles. The name of these roles should be consistent with how you’ve named them in your tables in your report — it will make it easier to manage later on.

In the “tables” section of this dialogue box, select the page level security column.

In the table filter DAX expression section, write the name of role column surround in square brackets and = 1 (eg. [Director] = 1).

Example

Create as many of these as you have roles and write the corresponding column name in the DAX expression. Our next role to create would be “Main Avenger” and the expression would be [Main Avenger] = 1.

Once you are done, save and exit this pane.

To test it out, revisit your filter/button. As it stands now, it should show all the options.

While still on the modelling tab, click “View as” (this should be next to Manage roles) to select who you want to view it as and press “OK”.

Let’s view this as a Support Avenger.

Support Avenger can only view the Home Page.

The filter now only allows them to select the Home Page!

Voila!

We have now achieved page level security. Go ahead and test this out with other roles. In our example, Nick Fury will be able to access all pages, Main Avengers will be able to access 2/3, and Support Avengers can only access 1/3 — the home page.

NOTE: MAKE SURE TO HIDE ALL PAGES EXCEPT THE HOME PAGE or whichever page is okay for everyone to view, down to the lowest level.

TIP: Often times, I will incorporate a “landing page” as the only visible one. This serves no other purpose but to make a clean entry into your report regardless of their roles, like below:

Landing page.

Some final considerations of using Page Level Security:

Pros:

Page level security (sort of)! The same report can now be shown to different departments or levels within the organization.

Reduce the number of duplicate/similar reports in multiple places.

Cons:

Depending on your organizations active directory and/or standard operating procedure regarding privacy, there is a small learning curve as it may involve some data modelling using bridge tables.

There could be some maintenance involved.

It can only be changed from within the PBIX file, not on the report server or Power BI Service.

Users can still access a hidden page IF the page they land on contains a visual with a drill through that brings them to a page they’re not supposed to see.

What are your thoughts? Leave a comment below.

If you’d like to download the PBIX file, you can do so here.

Enjoy!

-Allen