Using a certificate from a keyvault in azure app service in an azure managed application deployment - Stack Overflow

admin2025-04-18  3

I am creating an Azure Managed Application that will be made available in the azure marketplace for deployment into customer's tenants. Among other things, the managed resource group includes a keyvault and an app service. In the keyvault, there is an ssl certificate that I want to use for Azure AppService.

I have created a user assigned managed identity for the appservice and granted it access in the keyvault's access policy. The bit that I am stuck with is that I also need to grant 'get' permissions for certificates and secrets to the service principal for the Microsoft Azure App Service resource provider. (docs here: #import-a-certificate-from-key-vault) In order to do this, I need the objectid (required property for the access policy) of the service principal which is different in every customer tenant. The known information I have is the applicationId for the Microsoft Azure App Service resource provider abfa0a7c-a6b6-4736-8310-5855508787cd which is consistent accross azure. I'm stumped as to how to proceed here. Does anyone have any inspiration?

resource keyVault 'Microsoft.KeyVault/vaults@2023-02-01' = {
  name: keyVaultName
  location: location
  properties: {
    enabledForDeployment: false
    enabledForDiskEncryption: false
    enabledForTemplateDeployment: true
    enableRbacAuthorization: false
    tenantId: tenantId
    enableSoftDelete: true
    softDeleteRetentionInDays: 90
    sku: keyVaultSku
    networkAcls: {
      defaultAction: 'Allow'
      bypass: 'AzureServices'
    }
    accessPolicies:[
       {
         objectId: keyVaultReferenceIdentity.properties.principalId
         permissions: {
           certificates: [
             'get', 'list', 'getissuers', 'listissuers', 'update', 'create', 'import'
           ]
           keys: [
             'get', 'list', 'decrypt', 'unwrapKey', 'verify', 'getrotationpolicy', 'update', 'create', 'import'
           ]
           secrets: [
             'get', 'list', 'set'
           ]
         }
         tenantId: tenantId
       }
       {
         objectId: //what can I put here for the Microsoft Azure App Service resource provider?
         permissions:{
           certificates: ['get']
           secrets:['get']
         }
         tenantId: tenantId
       }
     ]
  }
}

resource keyVaultReferenceIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: keyVaultReferenceIdentityName
  location: location
}

I am creating an Azure Managed Application that will be made available in the azure marketplace for deployment into customer's tenants. Among other things, the managed resource group includes a keyvault and an app service. In the keyvault, there is an ssl certificate that I want to use for Azure AppService.

I have created a user assigned managed identity for the appservice and granted it access in the keyvault's access policy. The bit that I am stuck with is that I also need to grant 'get' permissions for certificates and secrets to the service principal for the Microsoft Azure App Service resource provider. (docs here: https://learn.microsoft.com/en-us/azure/app-service/configure-ssl-certificate?tabs=apex%2Caccesspolicy#import-a-certificate-from-key-vault) In order to do this, I need the objectid (required property for the access policy) of the service principal which is different in every customer tenant. The known information I have is the applicationId for the Microsoft Azure App Service resource provider abfa0a7c-a6b6-4736-8310-5855508787cd which is consistent accross azure. I'm stumped as to how to proceed here. Does anyone have any inspiration?

resource keyVault 'Microsoft.KeyVault/vaults@2023-02-01' = {
  name: keyVaultName
  location: location
  properties: {
    enabledForDeployment: false
    enabledForDiskEncryption: false
    enabledForTemplateDeployment: true
    enableRbacAuthorization: false
    tenantId: tenantId
    enableSoftDelete: true
    softDeleteRetentionInDays: 90
    sku: keyVaultSku
    networkAcls: {
      defaultAction: 'Allow'
      bypass: 'AzureServices'
    }
    accessPolicies:[
       {
         objectId: keyVaultReferenceIdentity.properties.principalId
         permissions: {
           certificates: [
             'get', 'list', 'getissuers', 'listissuers', 'update', 'create', 'import'
           ]
           keys: [
             'get', 'list', 'decrypt', 'unwrapKey', 'verify', 'getrotationpolicy', 'update', 'create', 'import'
           ]
           secrets: [
             'get', 'list', 'set'
           ]
         }
         tenantId: tenantId
       }
       {
         objectId: //what can I put here for the Microsoft Azure App Service resource provider?
         permissions:{
           certificates: ['get']
           secrets:['get']
         }
         tenantId: tenantId
       }
     ]
  }
}

resource keyVaultReferenceIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: keyVaultReferenceIdentityName
  location: location
}
Share edited Jan 30 at 10:18 Thomas 30.1k6 gold badges98 silver badges141 bronze badges Recognized by Microsoft Azure Collective asked Jan 30 at 8:23 renrutsirhcrenrutsirhc 2703 silver badges14 bronze badges 0
Add a comment  | 

3 Answers 3

Reset to default 1

I came to the conclusion that this is not a trivial problem to solve and that I could reach my desired end result much quicker and more easily by using an App Service Managed Certificate and thus eliminating the need for App Service to get certificates from the KV. This worked great. Not a terribly satisfying answer so if anyone comes up with something better, I'd love to hear it.

Bicep now supports Microsoft Graph (see documentation) so you could get a reference to the app service resource provider and grab the object id like that:

extension microsoftGraphV1

...

// Get a reference to app service resource provider
resource appServiceResourceProvider 'Microsoft.Graph/[email protected]' existing = {
  appId: 'abfa0a7c-a6b6-4736-8310-5855508787cd'
}

resource keyVault 'Microsoft.KeyVault/vaults@2023-02-01' = {
  name: keyVaultName
  location: location
  properties: {
    ...
    accessPolicies:[
       ...
       {
         objectId: appServiceResourceProvider.id
         permissions:{
           certificates: ['get']
           secrets:['get']
         }
         tenantId: tenantId
       }
     ]
  }
}

Microsoft is painfully vague on the details of this but:

  1. Add a role assignment to your key vault in the IAM tab.

  2. Choose Key Vault Certificate User (or whatever role you chose)

  3. For users choose "Users, group, or service principal". In the selection menu search for "microsoft azure app service". This will bring up the built-in service SPN which is needed to bind the certificate in Key Vault (you'll notice its application id is abfa0a7c-a6b6-4736-8310-5855508787cd).

I don't think you even need the user assigned managed identity once this in-built SPN is set up but you can test that.

转载请注明原文地址:http://www.anycun.com/QandA/1744931713a89659.html