Thumbnail Calling Entra ID secured Azure Functions from Power Automate

Calling Entra ID secured Azure Functions from Power Automate

Can you call an Entra ID secured Azure Function from Power Automate? Well, yes you can. In several ways. This blog post describes using the “HTTP With Microsoft Entra ID” connector to do it. I recently had an interesting digging session to get it to work. If you know how it works it’s quite easy though! (As it usually is)

Calling Azure Functions or other API’s from Power Automate is a quite useful and normal usecase. Some things are just hard to achieve in low code and would be much easier to develop in (for example) a .NET application. Or it may be that certain things have already been built for your company and deployed as an Azure Function, and you don’t want to do the work all over again by building the same in a Power Automate flow. No worries: just call that API!

Now such API’s often are Entra ID secured, to be able to leverage the context of the calling user or just as a security measure to keep business data inside the company. So how can you call these API’s from Power Automate? Well, one possibility is to build your own Custom Power Automate Connector. But there’s also an easier route, using a built-in connector. The scenario in this post is to do just that, and to leverage the user’s identity to call the API so that we would be able to give back security trimmed results based on who the user is.

Ok, so what I did for this blog post is create an Azure Function in VS Code with an HttpTrigger and just boilerplate code. Nothing fancy. I deployed that to Azure. I then secured it with Entra ID. You can do that in the Authentication blade.

Function App Auth

I added an identity provider and followed the steps, which automatically created an App Registration for me with an API Resource ID: api://618dfcd5-b7b3-433b-9e15-f869157e2993 and a user_impersonation scope. I configured the following settings in the Function App identity provider:

Function App Identity Provider Settings

Note: Take note that I opened it up for all calling applications, which is not recommended. But that's just for now. We'll restrict it to 'just Power Automate' later.

If we call the HTTPTrigger from Postman or some other tool, we’ll now get a nice 401 Unauthorized response. Time to head over to Power Automate and see how we can call this API.

For many people the first thing that comes to mind when calling an API from Power Automate is the HTTP Connector:

HTTP Connector

And that’s a good thought. The HTTP Connector is a very powerful tool that can be used to call any API. But in this case, we’re calling an API that is secured with Entra ID. And that’s where the HTTP Connector falls short.

It does in fact support Entra ID authentication, but only using an application identity. As you can see in the following screenshot, the HTTP Connector requires you to provide a Client Secret or a Certificate, which would mean application authentication. The Power Automate flow would call the API as the application itself. And that’s not what we want. We want to call the API on behalf of the user that is running the Power Automate flow.

HTTP Connector configuration

But there’s another connector: The HTTP with Microsoft Entra ID connector. This connector is specifically designed to call API’s that are secured with Entra ID. And it does so by leveraging the identity of the user that’s signed in. It’s a premium connector though, so you’ll need a premium license to use it.

HTTP with Entra ID Connector

Adding the “Invoke an HTTP request” action from this connector to a Power Automate flow triggers a configuration dialog that requires you to provide the URL and Application ID URI. Now that’s quite simple, that information is available in our Function App and corresponding App Registration.

Connection Setup

However, when we try to establish the connection, we get an interesting error message: “Failed to create OAuth connection: ClientError: AADSTS650057: Invalid resource. The client has requested access to a resource which is not listed in the requested permissions in the client’s application registration. Client app ID: d2ebd3a9-1ada-4480-8b2d-eac162716601(PowerPlatform-webcontentsv2-Connector).”

Error message

It basically says that the app Power Automate will use to call our API, does not have permissions to that API. Which is actually quite logical. We did not grant the Power Automate app permissions to call our API. We only created the app registration for our API. In a good Entra ID Setup you have at least two applications, One app for the API and one app for the client that calls the API. That client app should have permissions on the API app.

The error message mentions a client ID: d2ebd3a9-1ada-4480-8b2d-eac162716601. This is apparently the client ID of the Power Automate app that will call the API. We can look this up in the Entra ID Portal. But now something interesting occurs: the app cannot be found!

App not found

Usually, Microsoft client applications have an identity in Entra ID by default. But in this case it does not. Which is odd. The documentation for the connector has a lengthy article on this and even references a PowerShell script of 300+ lines that can be used to manage permissions.

🔌 It’s apparently not really plug and play. 😁

I checked Microsoft’s PowerShell script and saw that it first creates the application if it doesn’t yet exist. That’s apparently how it should be. And it’s part of the 300+ lines! Well, I think I can do the same in just a couple of lines: using the CLI for Microsoft 365 we can create an enterprise application or service principal for the Power Automate app, using the client ID. And after creating it we can assign it permissions to our API app. The following script does just that. (You’ll need the appropriate role to be able to do this: Global Admin or Cloud Application Developer or some such)

# Create the missing enterprise app / service principal
$app = m365 entra enterpriseapp add --id "d2ebd3a9-1ada-4480-8b2d-eac162716601" --output json | ConvertFrom-JSON

# Assign delegated permissions to the enterprise app / service principal
m365 entra oauth2grant add --clientId $app.id --resourceId "<object-id-of-our-api-enterprise-app>" --scope "user_impersonation"

# This code was tested using version 9 and 10 of the CLI for Microsoft 365
What ID to use?: Take note that the 'm365 entra oauth2grant add' command requires you to fill in Object ID's of enterprise apps / service principals. Not Client ID's and not Object ID's of app registrations. I know, it's confusing. We're working to make it a little easier.

After running the script, we can now see the missing application appear in the Entra ID Portal, complete with a name that we did not fill in ourselves, confirming that we created the right thing:

App now available

And it also has the required permissions on our API app:

App permissions

Now that we have the missing app in place, we can try to establish the connection again. This time it works! The connection is established and we’re shown a screen where we can fill in the parameters for the API call:

Configuring the request

After filling in the parameters, we can run the flow. And we get a nice 200 OK response from our API:

HTTP call and response

The last step is what I wrote about in the beginning: We don’t just want any app to call our Function App. There’s an extra configuration step we can take to make sure that only the Power Automate app can call our API. We can do this by adding the Power Automate app to the list of authorized client applications in the Function App identity provider settings:

Function app authorized client applications

Calling an Entra ID secured API can be done using the HTTP with Microsoft Entra ID connector in Power Automate. However, it’s not plug-n-play. You’ll need some initial steps to make sure that the client app that Power Automate uses to call the API exists and has the required permissions on the API app. This can all be done in several ways, for example using the CLI for Microsoft 365. However, after we’ve configured this once, it’s actually quite easy. We can freely call our API and work with the results in Power Automate flows.

Happy (low-)coding!!


azurefunction powerautomate entraid
Support me by sharing this

More

More blogs

Running .NET Function Apps or App Services accessing Microsoft 365
Running .NET Function Apps or App Services accessing Microsoft 365

A guide on how to create a .NET application that can access SharePoint and the Microsoft Graph through Entra ID.

Read more
Logging and tracing with Azure Durable Functions
Logging and tracing with Azure Durable Functions

Durable functions are awesome... this post shows how to see what happened end-to-end in a durable function instance.

Read more
How not to forget all those pesky Client Id's with PnP PowerShell
How not to forget all those pesky Client Id's with PnP PowerShell

The PnP Management Shell Entra ID App has gone away. Which means we'll now have to remember our Client Id's ourselves. This is a way to do just that.

Read more

Thanks

Thanks for reading

Thanks for reading my blog, I hope you got what you came for. Blogs of others have been super important during my work. This site is me returning the favor. If you read anything you do not understand because I failed to clarify it enough, please drop me a post using my socials.


Warm regards,
Martin

Microsoft MVP | Microsoft 365 Architect

Microsoft MVP horizontal