Currently I am using a backend connection with a function key in the header to access my function apps. Instead of needing to store & pass around these keys, I would like to use a managed identity to implicitly grant access to my API Management, and reject any direct calls.
I've read through this and it seems that I should be able to do this by doing the following:
- Create User Managed Identity
- Give it Contributor role to all of my function apps
- Assign it to my API Management
- Update the API Policy to include the following:
<authentication-managed-identity
resource="${function_id}"
output-token-variable-name="msi-access-token"
ignore-error="false"
client-id="#{function_access_client_id}"
/>
Where
a. "function_id" is the ID of my function app (also tried https://management.azure.com/) b. "function_access_client_id" is the ID of my User Managed Identity
And this is where I now am confused.
- If for (a) I use https://management.azure.com/, then i am able to successfully get a token, but it fails to authenticate against the "Authentication" of the function app.
- If for (a) I use the ID of the function app, then i receive the following error:
"errorResponse": "System.InvalidOperationException: [MSAL] Authentication failed for ClientId: <user managed client id> Certificate: <certificate> AuthorizationUrl: https://login.windows.net/<id> resourceId: /subscriptions/<subscription>/resourceGroups/<res group>/providers/Microsoft.Web/sites/<function app name> ---> Microsoft.Identity.Client.MsalServiceException: AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope /subscriptions/<subscription>/resourceGroups/<res group>/providers/Microsoft.Web/sites/<function app>/.default is not valid.
I am able to make this work if I set the client_id
variable to be the value of the Authentication Identity Provider of the function app. I also noticed that if I remove the user managed identity from the API Management after this worked, then it fails because it says that APIM doesn't have management identities enabled.
I guess I'm just really confused with the logic of this. If this is set up correctly, that means I need
- A user assigned managed identity to say I can access the application. This Identity can create it's own JWT using it's client ID, but we don't use it
- An authentication on the function application requiring a JWT
- A policy which references the client ID of the authentication listed in step 2.
Is this set up wrong? It works it just feels very odd. What's the point of user managed identity?