Embed PowerBI in Appfarm
This guide outlines the necessary configurations in Entra, Power BI, and Appfarm to successfully embed Power BI reports in an Appfarm app.
Part 1: Entra and Power BI Configurations
Most of these steps are already configured, but it's crucial to understand their requirements.
1. App Registration in Entra
An application needs to be registered in Entra.
Required API Permissions (Minimum):
Dataset.Read.All: Delegated permission to "View all datasets".
Report.Read.All: Delegated permission to "Make API calls that require read permissions on all reports".
Generate Embed Token - REST API: This process is used to generate the embed token.
2. Security Group in Entra
A security group in Entra must be created for use in the Power BI Admin center.
The Entra App created above needs to be added to this security group.
3. Power BI Admin Center Settings
Ensure the security group is added to the necessary developer and admin settings within the Power BI Admin center.
Developer Settings: Select "Service principals can use Power BI APIs".
Admin API Settings: Select "Service principals can access read-only admin API".
Part 2: Appfarm Configuration
These Appfarm configurations are necessary.
1. Secrets in Appfarm Create
Two secrets need to be created:
Entra PBI App ID
Entra PBI App Secret
2. Whitelist PBI Script Source
In the Environment Config (for each environment), add the Power BI Script source to the environment whitelist (Content Security -> Script Sources).

The URL for the script is:
https://cdn.jsdelivr.net/npm/[email protected]/dist/powerbi.min.js
Part 3: Power BI Report Setup and Configuration
1. Workspace Access
The Entra App (not the Security Group) must have access to the workspace where the Power BI report is located.
The app's role in the workspace must be either "Member" or "Admin".
2. Identify IDs and Roles
Note down the IDs for the Dataset, Report, and Workspace (also known as Group ID).
If Row-Level Security (RLS) is used, note the names of the roles in the report.
Part 4: Appfarm App Configuration
1. Create App Variables
Create two App Variables in your Appfarm application:
One to store the Access Token.
One to store the Embed Token.
2. On-App Load Action with web request to generate access token
Create an "On - App Load" action.
Add a Web Request action node to generate the Access Token.
Base URL:
https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
(You can copy the endpoint from the Entra App for accuracy)Method:
POST
.Auth:
No auth
.Body Type:
URL-encoded
.Body Content:
Add 4 Form Data entries the following Keys and Values
grant_type=client_credentials client_id=${entraPBIAppID} // Use the secret variable for App ID client_secret=${entraPBIAppSecret} // Use the secret variable for App Secret scope=https://analysis.windows.net/powerbi/api/.default
Result mapping: Select App Variables data source, and type in path
access_token
on the property mapping for the access token app variable.
3. Web request to generate Embed Token
Add another Web request action node to generate the Embed Token.
Base URL:
https://api.powerbi.com/v1.0/myorg/GenerateToken
.Authorization:
Bearer
Auth Token:
App Variables.Access Token
Prefix Bearer Keyword: ✅
Method:
POST
.Body Type:
Raw
.Body Content (JavaScript):
Define the following function (add currentUserEmail as function parameter)
return { datasets: [ { "id": "<dataset ID>", "xmlaPermissions": "ReadOnly" } ], reports: [ { "id": "<report ID>" } ], identities: [ { username: currentUserEmail, roles: ["<PBI Role Name>"], // If using RLS datasets: ["<dataset ID>"] } ] };
Result mapping: The following response is received. Select App Variables as Data Source, and type in "token" for the property mapping og the Embed Token app variable.
{ "token": "H4sIAAAAAAAEAMtIzcnJVyjPL8pJUeJUeJRxAgCCzQNLFAAAAA==", "tokenId": "46f04cfb-5c66-4e12-8d4e-0bc3498b9733", "expiration": "2025-07-09T12:36:00.123Z" }
Part 5: Embed Visual in Appfarm App using Coded Component
1. Configure Coded Component
Add a Coded Component (UI Component) to your View
In the Coded Component, go to the right-hand pane.
2. Add Resource Property (Resources -> click +
)
+
)Name:
PBI
(or any other descriptive name).Type:
Script URL
.Script URL:
https://cdn.jsdelivr.net/npm/[email protected]/dist/powerbi.min.js
.
3. Add Data Property (Data -> click +
)
+
)Name:
embedToken
(If you use a different name, update the JavaScript accordingly).Value Type:
Value
.Value: Set this to the Appfarm variable that holds your embed token value (
App Variables.Embed Token
).
4. Copy and Paste HTML Code
Add the following HTML code to the HTML Content section of your coded component. You can adjust the
style
settings as needed:<body> <div id="embedContainer" style="height: 600px; width: 100%;"></div> </body>
5. Copy and Paste JavaScript Code
Add the following JavaScript code to the Script section of your coded component.
Remember to update the values of the variables
embedUrl
andembedReportId
://Script: let loadedResolve, reportLoaded = new Promise((res, rej) => { loadedResolve = res; }); let renderedResolve, reportRendered = new Promise((res, rej) => { renderedResolve = res; }); let models = window['powerbi-client'].models; function embedPowerBIReport() { let accessToken = appfarm.data.embedToken.get(); //CHANGE THIS IF YOU RENAME THE EMBED TOKEN DATA INPUT let embedUrl = "https://app.powerbi.com/reportEmbed?reportId=<Report ID>&groupId=<group/workspace ID>"; //CHANGE EMBED URL let embedReportId = "<Report ID>"; //CHANGE REPORT ID let permissions = models.Permissions.Read; //CHANGE PERMISSIONS IF USER NEED OTHER RIGHTS. THESE INCLUDES READ, READWRITE, COPY, CREATE, ALL. let tokenType = models.TokenType.Embed; let config = { type: 'report', tokenType: tokenType == '0' ? models.TokenType.Aad : models.TokenType.Embed, accessToken: accessToken, embedUrl: embedUrl, id: embedReportId, permissions: permissions, settings: { panes: { filters: { visible: true }, pageNavigation: { visible: true } }, bars: { statusBar: { visible: true } } } }; let embedContainer = document.getElementById('embedContainer'); let report = powerbi.embed(embedContainer, config); report.off("loaded"); report.on("loaded", function () { loadedResolve(); report.off("loaded"); }); report.off("error"); report.on("error", function (event) { console.log(event.detail); }); report.off("rendered"); report.on("rendered", function () { renderedResolve(); report.off("rendered"); }); } embedPowerBIReport();
Last updated
Was this helpful?