]> Function App: Azure.Identity.AuthenticationFailedException 🌐:aligrant.com

Function App: Azure.Identity.AuthenticationFailedException

Alastair Grant | Thu 26 May 2022

I deployed an Azure Function App today, which when tested was producing this error:

ManagedIdentityCredential authentication failed: No MSI found for specified ClientId/ResourceId.

The error relates to Managed Identities in Azure.  In Azure, by default an app will have a system-assigned identity which it uses to authenticate itself to other resources.  This is assigned at the point of the resource creation and is destroyed when the resource is deleted.  Think of it as a service account just for that resource.  In this scenario the Function App was trying to retrieve a secret from Azure Key Vault; normally we would add in the system assigned Managed Identity with the relevant permissions into Azure Key Vault, but this deployment was being done via a scripted deployment.

In a scripted deployment you get yourself in a dependency loop: To configure an application you need it to access a key vault; to configure a key vault, you need the identity of the application.

The way around this is to use a user-assigned identity (you can have as many of these as you like, in addition to the system-assigned one too).  The difference is, this is an explicitly setup identity which isn't created or destroyed with resource creation, but on your own terms.  Think of a system-assigned identity as say the local system account on Windows, where a user-assigned is a service account you've already set up in your local directory.

It's in this scenario that I encountered the error.  When using a manual deployment and system-assigned identities all was fine, but using a user-assigned identity it did not work.


In the end a code change is needed to tell your app which identity it should be using.  Using Azure.Security.KeyVault.Certificates.CertificateClient you can provide a second constructor argument of Azure.Core.TokenCredential.  In almost all cases, you want to be using the DefaultAzureCredentialOptions class as your type.  This contains a property called ManagedIdentityClientId, which now you know it's there, is quite clearly where you need to specify the Client Id from the user-assigned identity you've previously created.

If you pop this as a configuration value, you can set this at deployment time with your ARM/Bicep template to pull the identity's "id" field.

Breaking from the voyeuristic norms of the Internet, any comments can be made in private by contacting me.