How to use a service principal in Power BI Admin REST APIs in Power Automate

I’m writing a blog post of how to use the Power BI GetActivityEvents REST API call in Power Automate and while writing that I noticed that the first hurdle is to get the service principal authorization settings correct. I’m quite sure someone else has had problems with this as well so here is a short walkthrough of the application settings in Azure, Power BI admin portal and the workflow in Power Automate to get an access token for a service principal.
The steps are:
- Create a service principal (app registration) in Azure and create a security group for it
- Add that security group to Admin API settings in Power BI admin portal
- Create the flow
In my flow I also use an Azure Key Vault to store the client secret and that is advisable instead of revealing the secret in your flow. But the Key Vault part is not mandatory.
App registration
I’Il say the most important part first. DO NOT give any permissions to your application in Azure. This is something that Microsoft will hopefully make clearer in the future. Service principals using the ADMIN APIs, do not need any permissions in Azure because they are given through the Power BI admin portal admin API settings. Read this documentation carefully Enable service principal authentication for read-only admin APIs – Power BI | Microsoft Docs

Otherwise, you create the application as any other.


Security group
Then you create a security group and add previously created application as a member.

Admin API settings
Next step is to navigate to powerbi.com and to the admin portal and add the security group here:

And finally, we get to Power Automate
Here’s the flow. I have a bunch of actual REST API calls in separate flows, all requiring authorization, so this is a child flow for those. In my next post I’ll show how to call the child flow ?

To get the access token, create a POST method HTTP action. The URI for creating an access token is https://login.microsoftonline.com/InsertYourTenantIdHere/oauth2/token. Tenant Id can be found for example in Azure Portal Azure Active Directory Overview page.

Header:
Content-Type = application/x-www-form-urlencoded
Body:
grant_type=client_credentials
&resource=https://analysis.windows.net/powerbi/api
&client_id=InsertYourApplicationIdHere
&client_secret=InsertYourApplicationSecretHere
&scope=https://analysis.windows.net/powerbi/api/.default
Last bit of the authorization process is to parse the HTTP output to get the token_type and access_token parameters.

Here’s the parse JSON schema for your convenience.
{
"properties": {
"access_token": {
"type": "string"
},
"expires_in": {
"type": "string"
},
"expires_on": {
"type": "string"
},
"ext_expires_in": {
"type": "string"
},
"not_before": {
"type": "string"
},
"refresh_token": {
"type": "string"
},
"resource": {
"type": "string"
},
"scope": {
"type": "string"
},
"token_type": {
"type": "string"
}
},
"type": "object"
}
Authorization in the (actual) REST API call
In the next HTTP call, where you for example GetGroupsAsAdmin, you need to add another header for the authorization.
Authorization = token_type “THE MOST IMPORTANT SPACE IN YOUR FLOW” access_token. (Really, it will not work without the space between token_type and access_token).
In my flow I create the authorization value as a response to my parent flow but if you just want to run one flow you add the header directly to the HTTP action as below. All REST API calls are different and might require a bit different settings so remember to read the documentation.

That’s it! Your Admin API calls should run with these settings. If not, leave a comment below or contact us.
In my next post I’ll walk you through the Get Activity Events REST API call where we need to create some do while loops for the continuation token and large data volumes handling.
Thanks, the first part about getting the token was helpful.
This is awesome, thank you so much for putting this together!
Hi, greate post! Will you be so kind to list all the permissions you had to activate in azure? I’m having some trubles and I’m not sure if it is because I just have Tenant.Read.All instead of Tenant.ReadWrite.All. Thanks!
Mijalis
Wooooowwwww…… been trying to figure this out for ages, thank you.