Connecting to Dataverse from Azure Functions traditionally involved using App Registrations, which authenticate against Dataverse using the Service Principal ID and an App Registration secret. However, App Registration secrets have expiration dates and can pose significant security risks, such as potential exposure of secrets and the need for regular secret rotation.
With the introduction of Azure Managed Identities, we can now eliminate the use of App Registration secrets and access Dataverse using Microsoft Entra Identities.
This approach enhances security by removing the need for secret management and reduces the risk of credential exposure. Below are the steps to transition an existing Function App from using App Registrations to Managed Identities.
1. Azure - Create a Managed Identity and Associate it with an Azure Function
1.1 Create a Managed Identity
Navigate to the Managed Identities area and create a new Managed Identity
It is recommended to use appropriate naming conventions provided by your organization or Azure community https://www.azureperiodictable.com
Provisioning the Managed Identity will take a few seconds
Make a note of the Client ID, as it will be used in subsequent steps.
1.2 Associate the Managed Identity with the Azure Function
Navigate to the Function App > Settings > Identity > Assigned Identity > Add
Search for and select the newly created Managed Identity
1.3 Create an Environment Variable/App Configuration
Navigate to the Function App > Settings > Environment Variables > Add.
Set the name as AZURE_CLIENT_ID and the value as the Client ID of the Managed Identity.
2. Dataverse - Add Application User
To use the newly created Managed Identity, it must be added as an Application User in Dataverse.
In the Power Platform Admin Center, navigate to the Instance > Settings > User + Permissions > Application Users
Add a new Application User and search using the Client ID of the Managed Identity
Assign the relevant security roles to the newly created Application User
3. Code - Update the Authentication Logic in the Azure Function
Update the Azure Function code to use the Managed Identity. The following code snippet shows how to initiate a DefaultAzureCredential object and use it to create an instance of ServiceClient, which will be used to access the Dataverse API. The dataverse_url is an environment variable storing the Dataverse URL (e.g., https://contoso.crm4.dynamics.com)
var managedIdentity = new DefaultAzureCredential();
var environment = Environment.GetEnvironmentVariable("dataverse_url");
_serviceClient = new ServiceClient(tokenProviderFunction: async u => (await managedIdentity.GetTokenAsync(
new TokenRequestContext(new[] { $"{environment}/.default" }))).Token, instanceUrl: new Uri(environment));
if (!_serviceClient.IsReady)
{
throw new InvalidOperationException("Service client is not ready.");
}
What do you think? Does this approach seem feasible for your projects?
I look forward to your feedback!