[BUG] ManagedServiceIdentity does not use local MSI endpoint when retrieving access token scoped to app registration
See original GitHub issueLibrary name and version
Azure.Identity 1.8.1
Describe the bug
We have multiple function apps deployed to an Elastic Premium plan using vnet integration with vnet route all enabled and a default route to an Azure Firewall that blocks all network traffic to public IPs. All function apps connect to other PaaS services like Cosmos DB and Azure Service Bus using private endpoints deployed inside the same vnet as our Functions.
We are trying to make an HTTP request from Function App A to Function App B where Function App B has App Service Authentication enabled and the “User Assignment Required” option set to true on the app registration used for App Service Authentication. The MSI of Function App A has been assigned the appropriate role on the app registration of Function App B so that it has permission to request access tokens scoped to the app registration. We are using ManagedIdentityCredential.GetTokenAsync(new TokenRequestContext(scopes: new string[] { <App ID of Function App B's App Registration> + "/.default" })
in Function App A to request an access token with the correct scope, but the request is being blocked by our Firewall as the request is trying to access “login.windows.net”. The documentation for this method states that GetTokenAsync “Obtains an AccessToken from the Managed Identity service” which lead us to believe that the request should use the function app’s local managed identity endpoint and not hit any of the public AAD endpoints.
We are able to use the same ManagedIdentityCredential to retrieve an access token for Cosmos DB and Service Bus using the appropriate SDKs without being affected by our firewall rules.
Is this expected behaviour, or should the ManagedIdentityCredential use the local MSI endpoint without making any requests to public endpoints? If it is expected behaviour, how does this scenario differ to retrieving an access token scoped to a Cosmos account or a Service Bus namespace?
Expected behavior
ManagedIdentityCredential should use the local MSI endpoint to retrieve an access token without making requests to public AAD endpoints.
Actual behavior
A request is made to login.windows.net which is rejected by Azure firewall.
Reproduction Steps
- Deploy 2 x Function Apps to Elastic Premium plan with vnet integration and the vnet route all option enabled.
- Create default route to an Azure Firewall with no rules configured
- Setup App Service Authentication on one Function App
- Use ManagedIdentityCredential.GetTokenAsync() to retrieve an access token scoped to the app registration used for App Service Auth of the second Function App
Environment
Azure Functions running in an Elastic Premium EP1 plan with vnet integration enabled.
Issue Analytics
- State:
- Created 7 months ago
- Comments:7 (3 by maintainers)
Top GitHub Comments
Thanks @christothes. After further testing I can confirm the ManagedIdentityCredential is using the local endpoint to retrieve an access token from AAD as we expected and that this request is being allowed by the firewall. The actual issue sits with Easy Auth on the Function App. During the validation of the access token the Easy Auth service is sending requests to login.windows.net which are being blocked by our firewall. There’s a related Github issue asking for clarity in the documentation around what endpoints Easy Auth uses https://github.com/MicrosoftDocs/azure-docs/issues/104505
I believe step 6 of the diagram in the article linked above explains this: