Secure Key Release with Confidential VMs How To Guide

The below article describes how to perform a Secure Key Release from Azure Key Vault when your applications are running with an AMD SEV-SNP based confidential virtual machine. To learn more about Secure Key Release and Azure Confidential Computing, go here..

SKR requires that an application performing SKR shall go through a remote guest attestation flow using Microsoft Azure Attestation (MAA) as described here.

Overall flow and architecture

To allow Azure Key Vault to release a key to an attested confidential virtual machine, there are certain steps that need to be followed:

  1. Assign a managed identity to the confidential virtual machine. System-assigned managed identity or a user-assigned managed identity are supported.
  2. Set a Key Vault access policy to grant the managed identity the "release" key permission. A policy allows the confidential virtual machine to access the Key Vault and perform the release operation. If using Key Vault Managed HSM, assign the "Managed HSM Crypto Service Release User" role membership.
  3. Create a Key Vault key that is marked as exportable and has an associated release policy. The key release policy associates the key to an attested confidential virtual machine and that the key can only be used for the desired purpose.
  4. To perform the release, send an HTTP request to the Key Vault from the confidential virtual machine. The HTTP request must include the Confidential VMs attested platform report in the request body. The attested platform report is used to verify the trustworthiness of the state of the Trusted Execution Environment-enabled platform, such as the Confidential VM. The Microsoft Azure Attestation service can be used to create the attested platform report and include it in the request.

Diagram of the aforementioned operations, which we'll be performing.

Deploying an Azure Key Vault

Set up AKV Premium or AKV mHSM with an exportable key. Follow the detailed instructions from here setting up SKR exportable keys


@description('Required. Specifies the Azure location where the key vault should be created.')
param location string = resourceGroup().location

@description('Specifies the Azure Active Directory tenant ID that should be used for authenticating requests to the key vault. Get it by using Get-AzSubscription cmdlet.')
param tenantId string = subscription().tenantId

resource keyVault 'Microsoft.KeyVault/vaults@2021-11-01-preview' = {
  name: 'mykeyvault'
  location: location
  properties: {
    tenantId: tenantId
    sku: {
      name: 'premium'
      family: 'A'

ARM template

      "type": "Microsoft.KeyVault/vaults",
      "apiVersion": "2021-11-01-preview",
      "name": "mykeyvault",
      "location": "[parameters('location')]",
      "properties": {
        "tenantId": "[parameters('tenantId')]",
        "sku": {
          "name": "premium",
          "family": "A"

Deploy a confidential virtual machine

Follow the quickstart instructions on how to "Deploy confidential VM with ARM template"

Enable system-assigned managed identity

Managed identities for Azure resources provide Azure services with an automatically managed identity in Microsoft Entra ID. You can use this identity to authenticate to any service that supports Microsoft Entra authentication, without having credentials in your code.

To enable system-assigned managed identity on a CVM, your account needs the Virtual Machine Contributor role assignment. No other Microsoft Entra directory role assignments are required.

  1. Whether you sign in to Azure locally or via the Azure portal, use an account that is associated with the Azure subscription that contains the VM.

  2. To enable system-assigned managed identity, load the template into an editor, locate the Microsoft.Compute/virtualMachines resource of interest and add the "identity" property at the same level as the name: vmName property. Use the following syntax:

         type: 'SystemAssigned'
  3. Add the resource details to the template.

     resource confidentialVm 'Microsoft.Compute/virtualMachines@2021-11-01' = {
       name: vmName
       location: location
         type: 'SystemAssigned'
       // other resource provider properties