Row-Level-Security (RLS) in Power BI Embedded

In our sample report, we have a Store Table which is linked to Sales Data via the _StoreID column. In our Store table, we have a column StoreName on which we want to create RLS roles. In Power BI Desktop, we have created a role called Blue Store which filters the StoreName by 'Blue Store'
The displayed Profit is now much lower than before because the tested role only has access to one Store.
In the Power BI Service, Entra Security Groups (recommended) or users can be added to each of the created roles.1// Import necessary modules
2const msal = require('@azure/msal-node');
3const axios = require('axios');
4
5// Function to generate an embed token with RLS applied
6async function getEmbedToken(reportId, datasetIds, targetWorkspaceId = null) {
7 // Authentication configuration for Azure AD
8 const config = {
9 auth: {
10 clientId: '<YOUR_CLIENT_ID>', // Azure AD Application Client ID
11 authority: 'https://login.microsoftonline.com/<YOUR_TENANT_ID>', // Azure AD Tenant ID
12 clientSecret: '<YOUR_CLIENT_SECRET>', // Azure AD Application Client Secret
13 },
14 };
15
16 // Create a Confidential Client Application object
17 const cca = new msal.ConfidentialClientApplication(config);
18
19 // Define the scope for the Power BI REST API
20 const tokenRequest = {
21 scopes: ['https://analysis.windows.net/powerbi/api/.default'],
22 };
23
24 try {
25 // Acquire an access token to authenticate the API call
26 const authResult = await cca.acquireTokenByClientCredential(tokenRequest);
27 const accessToken = authResult.accessToken;
28
29 // Define the Effective Identity for RLS
30 const effectiveIdentity = {
31 username: 'static_user@example.com', // Static username for RLS
32 roles: ['Blue Store'], // RLS role to apply
33 datasets: datasetIds, // List of dataset IDs
34 };
35
36 // Create the request body for generating the embed token
37 const generateTokenRequestBody = {
38 datasets: datasetIds.map((id) => ({ id: id })), // Dataset IDs
39 reports: [{ id: reportId }], // Report ID
40 targetWorkspaces: targetWorkspaceId
41 ? [{ id: targetWorkspaceId }] // Target workspace if provided
42 : null,
43 identities: [effectiveIdentity], // RLS identities
44 };
45
46 // Make the API call to generate the embed token
47 const embedTokenResponse = await axios.post(
48 'https://api.powerbi.com/v1.0/myorg/GenerateToken',
49 generateTokenRequestBody,
50 {
51 headers: {
52 'Content-Type': 'application/json',
53 Authorization: `Bearer accessToken`, // Bearer token authentication
54 },
55 }
56 );
57
58 // Return the generated embed token
59 return embedTokenResponse.data.token;
60 } catch (error) {
61 console.error('Error generating embed token:', error.response ? error.response.data : error.message);
62 throw error;
63 }
64}
65
66// Example usage of the getEmbedToken function
67(async () => {
68 // Replace these placeholder values with your actual IDs
69 const reportId = '<YOUR_REPORT_ID>'; // GUID of the report to embed
70 const datasetIds = ['<YOUR_DATASET_ID>']; // Array of dataset GUIDs
71 const targetWorkspaceId = '<YOUR_WORKSPACE_ID>'; // GUID of the target workspace (optional)
72
73 try {
74 // Call the function to get the embed token
75 const embedToken = await getEmbedToken(reportId, datasetIds, targetWorkspaceId);
76 console.log('Embed Token:', embedToken);
77 } catch (error) {
78 console.error('Failed to retrieve embed token:', error);
79 }
80})();


