
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.

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.

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_id, client_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);