0

I'm experiencing an issue when I try to use an User Assigned Managed Identity to obtain a custom TLS/SSL certificate for my API Management instance from Azure Key Vault, as described here: Obtain a custom TLS/SSL certificate for the API Management instance from Azure Key Vault. The difference with the documentation is that my Key Vault has network access rules enabled. Specifically the combination of User Assigned Managed Identity and the key vault's firewall is troublesome.

Steps:

  1. Create vnet + subnet for APIM
  2. Create User Assigned Managed Identity
  3. Create key vault. Allow network access from APIM's subnet and create GET/LIST access policies on secrets for the User Assigned Managed Identity
  4. Generate self-signed certificate and import it in the key vault
  5. Deploy APIM (Developer SKU, internal vnet mode, with user assigned managed identity, with custom hostname configuration using ssl certificate from key vault)

Error

This results in the following error message. The message is misleading as given identity does have GET permissions.

Failed to access KeyVault Secret https://kv-xxx.vault.azure.net/secrets/gateway-certificate/58542d0de4094c60856f97482a9b2e69 using Managed Service Identity (http://aka.ms/apimmsi) of Api Management service. Check if Managed Identity of Type: UserAssigned, ClientId: 2fa6db22-xxxx-xxxx-xxxx-xxxxxxxxxxxx and ObjectId: 91f8fa07-xxxx-xxxx-xxxx-xxxxxxxxxxxx has GET permissions on secrets in the KeyVault Access Policies.

Success scenarios

As mentioned, it seems to be specifically this combination of a user assigned managed identity and a key vault with network access rules that is troublesome. The following does work:

  • system assigned managed identity + firewall on key vault
  • user assigned managed identity + no firewall on key vault

Deployment

I deploy my resources with Bicep, but I get the same issue via the Portal.

The bicep module for APIM:

@description('Name of APIM service')
param apimName string

@description('Location')
param location string = resourceGroup().location

@allowed([
  'Basic'
  'Consumption'
  'Developer'
  'Isolated'
  'Premium'
  'Standard'
])
@description('SKU name of APIM')
param skuName string

@description('Capacity of the SKU (number of deployed units of the SKU)')
param skuCapacity int

@description('Id of the subnet')
param subnetId string

@description('Publisher email')
param publisherEmail string

@description('Publisher name')
param publisherName string

@description('Id of the managed identity')
param managedIdentityId string

@description('Client id of the managed identity')
param managedIdentityClientId string

@description('Reference to the Key Vault certificate')
param certificateKeyVaultId string

@description('Reference to the Key Vault certificate')
@secure()
param certificateKeyVaultPassword string

@description('Hostname of the gateway')
param gatewayHostname string

resource apim 'Microsoft.ApiManagement/service@2021-08-01' = {
  name: apimName
  location: location
  sku: {
    capacity: skuCapacity
    name: skuName
  }
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${managedIdentityId}': {}
    }
  }
  properties: {
    hostnameConfigurations: [
      {
        type: 'Proxy'
        hostName: gatewayHostname
        defaultSslBinding: true
        certificateSource: 'KeyVault'
        identityClientId: managedIdentityClientId
        keyVaultId: certificateKeyVaultId
        certificatePassword: certificateKeyVaultPassword
      }
    ]
    publisherEmail: publisherEmail
    publisherName: publisherName
    virtualNetworkConfiguration: {
      subnetResourceId: subnetId
    }
    virtualNetworkType: 'Internal'
  }
}

Links:

t.amsing
  • 169
  • 7
  • 1
    Please enable the AKV logs and find the HTTP response of the failed request. It will give a lot of insight into the problem. – Matt Small Jan 31 '22 at 21:44
  • @MattSmall Thanks, I have looked into the logs and noticed that calls for the certificate are made from the same IP every time: 51.145.179.78. This IP is used by Azure APIM and mentioned here: https://learn.microsoft.com/en-us/azure/api-management/virtual-network-reference?tabs=stv2#control-plane-ip-addresses. Access works when I whitelist this IP, solving my issue. But I do wonder why I don't have to whitelist this IP when using system assigned managed identity and whether there is a better approach. – t.amsing Feb 01 '22 at 14:34
  • Does it use the same IP address when using the system assigned managed identity? – Matt Small Feb 01 '22 at 14:42
  • I am running into a similar deployment issue. Based on your scenario confused what is meant by assigning the Identity an "access policy" Are you using RBAC? Based on your error it looks to me APIM could have certificate access but not secret access. If you export your Key Vault I bet you will in the ARM template a reference to a secret you don't see in the portal. I believe this related to how certificates are configured. – DreadedFrost Mar 23 '22 at 00:29

1 Answers1

0

As it is mentioned here. If Key Vault firewall is enabled on your key vault, You must use the API Management instance's system-assigned managed identity to access the key vault.

To get around this you can try this (If you don't want to explicitly white list APIM control plane IP):

  1. Deploy APIM without custom domains
  2. Add APIM system-assigned identity to ssl certificates key vault
  3. Redeploy APIM with custom domains
Ahmed El Kilani
  • 345
  • 1
  • 8