{"id":10291,"date":"2020-05-12T00:00:00","date_gmt":"2020-05-12T05:00:00","guid":{"rendered":"https:\/\/threecloud.wpengine.com\/post\/dynamic-row-level-security-in-power-bi-2\/"},"modified":"2022-11-30T09:24:43","modified_gmt":"2022-11-30T15:24:43","slug":"dynamic-row-level-security-in-power-bi","status":"publish","type":"post","link":"https:\/\/3cloudsolutions.com\/resources\/dynamic-row-level-security-in-power-bi\/","title":{"rendered":"Dynamic Row Level Security in Power BI"},"content":{"rendered":"<p><strong>Interested in learning how to set up row level security (RLS) in Power BI when you have varied criteria?<\/strong> In this post I\u2019ll walk through a scenario of <strong>setting up dynamic row level security in which your users have unique access needs<\/strong>. In other words, one user has access to the Northeast and Midwest regions, another has access to the Southeast, and two others overlap with access to the South and Northwest regions.<\/p>\n<p>In my demo (please check out my video for a detailed view and the code used) I have 4 tables, users, user regions, regions, and sales. These tables are connected in various ways such as the users table connected to a many to many or bridge table, users and regions connected, and the regions table connected to the sales table.<\/p>\n<p><strong>What I want to do is apply a filter or row level security to the users table, or to use information from the users table and pass that all the way down to the regions table.<\/strong> Because this is a many to many relationship, I can\u2019t do this just by saying who is logged in.<\/p>\n<p>One way to do this is to create bi-directional relationships but that introduces other problems, so it may not be accessible for your specific case. <strong>I\u2019m going walk you through doing this using DAX<\/strong>. I\u2019ve already built the measures, so what I\u2019ll show you is how to build this DAX expression from the pieces that comprise it.<\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Step 1: Retrieve User ID from Users Table<\/strong><\/span><\/p>\n<ul>\n<li>I do this by using the look up value measure. I\u2019m going to return the user ID using the users email as the match term and the username expression to pull that in from Power BI.<\/li>\n<li>This measure now gives user IDs a number, so I am now user ID 1. Once this measure is done, we can copy it as we are going to use it again.<\/li>\n<\/ul>\n<p><span style=\"text-decoration: underline;\"><strong>Step 2: Filter User Region Table Based on User ID<\/strong><\/span><\/p>\n<ul>\n<li>Now that we have the user ID, we\u2019ll go to that bridge table and we\u2019re going to filter that based on the user ID from Step 1.<\/li>\n<li>What I\u2019m doing here is coming to that user regions table and asking it to show me the information relevant for User ID 1, which will return a filtered result.<\/li>\n<li>To do this I\u2019ll use the filter expression to filter the user regions table where the user region user ID is equal to the value that\u2019s returned from the previous measure (so the look up value is equal to 1).<\/li>\n<\/ul>\n<p><span style=\"text-decoration: underline;\"><strong>Step 3: Select Columns of Region ID from Table Returned in Step 2<\/strong><\/span><\/p>\n<ul>\n<li>So, we\u2019ve filtered this table, and now we want to get a column from it. To do this, we use the select columns expression.<\/li>\n<li>This table filter is basically the combination of the two DAX expressions we just used.<\/li>\n<li>Now with the select columns expression, we\u2019re going to ask to use that table we filtered, but just get the column with the region IDs.<\/li>\n<li>This is the expression we\u2019ll use to set our row level security.<\/li>\n<\/ul>\n<p><span style=\"text-decoration: underline;\"><strong>Step 4: Set Up Role That Filters the Region Table Using All Region IDs Identified in Step 3<\/strong><\/span><\/p>\n<ul>\n<li>Next step is to take that combination expression and put it into our roles.<\/li>\n<li>To do this we go up to the modeling tab and select manage roles.<\/li>\n<li>Select the role and the tables, in this case user role and regions table.<\/li>\n<li>Under table filter DAX expression, we want to add a filter under user ID. Instead of value, I\u2019m going to paste in the measure that we used in step 3 or up to this point.<\/li>\n<li>To get this expression to work for our row level security, we\u2019ll have to replace the equal sign at the beginning of our DAX expression with the IN operator. This IN operator is similar to SQL where this expression or measure is returning multiple results.<\/li>\n<li>But we want to tell it, filter the region IDs that are going to be returned in this set.<\/li>\n<li>So, I\u2019ll set this role and now if I come in and view as that role, I should only see my regions. As I simulate that role, it will filter our sales table to show us those two regions.<\/li>\n<\/ul>\n<p><iframe loading=\"lazy\" src=\"https:\/\/www.youtube.com\/embed\/rGSMBASW5zw\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<p>This will work effectively across any organization structure, as long as the table is organized accordingly. It\u2019s<strong> an easy way to get information from our users table, pass it over a many to many relationship and introduce it to our sales table by using that IN operator and the select columns and filter combination<\/strong>.<\/p>\n<p><strong>Need further help? Our expert team and solution offerings can help your business with any Azure product or service, including Managed Services offerings. Contact us at 888-8AZURE or\u00a0 <a href=\"mailto:sales@3cloudsolutions.com\">sales@3cloudsolutions.com<\/a>.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Interested in learning how to set up row level security (RLS) in Power BI when&mldr;<\/p>\n","protected":false},"author":31,"featured_media":10776,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[260],"tags":[],"class_list":["post-10291","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data-ai","topics-blog"],"acf":[],"_links":{"self":[{"href":"https:\/\/3cloudsolutions.com\/wp-json\/wp\/v2\/posts\/10291","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/3cloudsolutions.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/3cloudsolutions.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/3cloudsolutions.com\/wp-json\/wp\/v2\/users\/31"}],"replies":[{"embeddable":true,"href":"https:\/\/3cloudsolutions.com\/wp-json\/wp\/v2\/comments?post=10291"}],"version-history":[{"count":0,"href":"https:\/\/3cloudsolutions.com\/wp-json\/wp\/v2\/posts\/10291\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/3cloudsolutions.com\/wp-json\/wp\/v2\/media\/10776"}],"wp:attachment":[{"href":"https:\/\/3cloudsolutions.com\/wp-json\/wp\/v2\/media?parent=10291"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/3cloudsolutions.com\/wp-json\/wp\/v2\/categories?post=10291"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/3cloudsolutions.com\/wp-json\/wp\/v2\/tags?post=10291"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}