How to use an Azure Function to regenerate or set the primary & secondary keys of an Azure API Management (APIM) subscription programmatically.

resetApimSubscriptionPrimaryKeyFunction

In my GitHub repo, I want to programmatically change the API Management subscription key. APIM doesn’t have a built-in way to rotate keys on a periodic basis, but we can write one ourselves.

Our client (an Azure Function) needs an identity (service principal) in the same AAD tenant where our APIM is hosted. We need to grant that service principal access to request a token from the Service Management API’s service principal. We can then pass that token to our APIM’s Management REST API, which will validate the token and authorize updating the key.

How to authenticate

First, we need to grant the service principal of our Azure Function (the client) access to the Service Management API. This is done through the App Registration blade in Azure AD. Click on the API permissions blade and then click on Add a permission. You can then select the Azure Service Management API and the specific scope you want (in this case, the user_impersonation scope). This will allow the client service principal to get an access token to the Service Management API.

regenerateKeyAppRegistration

Second, you need to grant the client service principal access to your specific APIM. You can do this on the Access Control blade of the APIM. Click on Add and grant your client service principal the API Management Service Contributor RBAC role.

apimRBAC

You can now request a token to the Service Management API and submit it to the APIM Management REST API. There are 2 methods in the /update-primary-key/UpdateApimKeys.cs file, one to regenerate the key & one to allow you to set it to something specific.

In the constructor of the Azure Function, we need to initialize the ConfidentialClientApplication so it can request a token. The client_idclient_secret, etc are pulled from the Azure Function configuration.

public UpdateApimKeys() {
  confidentialClientApplication = ConfidentialClientApplicationBuilder.Create(System.Environment.GetEnvironmentVariable("AzureAD__ClientID"))
    .WithClientSecret(System.Environment.GetEnvironmentVariable("AzureAD__ClientSecret"))
    .WithAuthority(new Uri($"{System.Environment.GetEnvironmentVariable("AzureAD__Instance")}/{System.Environment.GetEnvironmentVariable("AzureAD__Tenant")}"))
    .Build();
  ...

In the RegeneratePrimaryKey function, we need to get an access token from the client service principal to the Service Management API resource.

var tokenResult = await confidentialClientApplication.AcquireTokenForClient(new List<string>{"https://management.azure.com/.default"}).ExecuteAsync();

We can now either regenerate the API subscription primary key or set it to a specific value.

using(var requestMessage = new HttpRequestMessage(HttpMethod.Post, $"{APIM_MANAGEMENT_ENDPOINT}/regeneratePrimaryKey?api-version=2020-12-01")) {
  requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokenResult.AccessToken);

  var apimRegeneratePrimaryKeyResult = await httpClient.SendAsync(requestMessage);

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *