Azure Citadel
  • Blogs

  • Azure Arc
    • Overview
    • Azure Arc-enabled Kubernetes
      • Prereqs
      • Background
      • Deploy Cluster
      • Connect to Arc
      • Enable GitOps
      • Deploy Application
      • Enable Azure AD
      • Enforce Policy
      • Enable Monitoring
      • Enable Azure Defender
      • Enable Data Services
      • Enable Application Delivery
    • Azure Arc-enabled Servers
      • Prereqs
      • Scenario
      • Hack Overview
      • Azure Landing Zone
      • Arc Pilot resource group
      • Azure Monitoring Agent
      • Additional policy assignments
      • Access your on prem VMs
      • Create onboarding scripts
      • Onboarding using scripts
      • Inventory
      • Monitoring
      • SSH
      • Windows Admin Center
      • Governance
      • Custom Script Extension
      • Key Vault Extension
      • Managed Identity
    • Useful Links
  • Azure CLI
    • Install
    • Get started
    • JMESPATH queries
    • Integrate with Bash
  • Azure landing zone
    • Overview
    • Run the ALZ Accelerator
      • Prereqs
      • Elevate
      • Bootstrap
      • Demote
      • Browse the deployed resources
    • Deploy an Azure landing zone
      • What is the Azure landing zone?
      • Create an initial ALZ config
      • Add a local override library
      • Test locally
      • Run through the CI/CD workflow
    • Understanding libraries
      • What is a library?
      • Policies, Assignments and Roles
      • Archetypes, Overrides and Architecture
      • Metadata and Policy Default Values
      • Custom libraries
    • Reference configs
      • Azure landing zone library
      • Azure landing zone library with overrides
  • Azure Lighthouse
    • Minimal Lighthouse definition
    • Using service principals
    • Privileged Identity Management
  • Azure Policy
    • Azure Policy Basics
      • Policy Basics in the Azure Portal
      • Creating Policy via the CLI
      • Deploy If Not Exists
      • Management Groups and Initiatives
    • Creating Custom Policies
      • Customer scenario
      • Policy Aliases
      • Determine the logic
      • Create the custom policy
      • Define, assign and test
  • Customer Managed Keys
    • Sovereignty scenarios
    • Key management options
    • 🧪 Azure Key Vault Premium
    • L2: Encryption at rest with CMK
    • 🧪 CMK for Storage
    • 🧪 CMK for VM Disks and AKS
  • Marketplace
    • Introduction
      • Terminology
      • Offer Types
    • Partner Center
    • Offer Type
    • Publish a VM Offer HOL
      • Getting Started
      • Create VM Image
      • Test VM Image
      • VM Offer with SIG
      • VM Offer with SAS
      • Publish Offer
      • Other VM Resources
    • Publish a Solution Template HOL
      • Getting Started
      • Create ARM Template
      • Validate ARM Template
      • Create UI Definition
      • Package Assets
      • Publish Offer
    • Publish a Managed App HOL
      • Getting Started
      • Create ARM Template
      • Validate ARM Template
      • Create UI Definition
      • Package Assets
      • Publish Offer
    • Managed Apps with AKS HOL
    • Other Managed App Resources
    • SaaS Offer HOLs
    • SaaS Offer Video Series
      • Video 1 - SaaS Offer Overview
      • Video 2 - Purchasing a SaaS Offer
      • Video 3 - Purchasing a Private SaaS Plan
      • Video 4 - Publishing a SaaS Offer
      • Video 5 - Publishing a Private SaaS Plan
      • Video 6 - SaaS Offer Technical Overview
      • Video 7 - Azure AD Application Registrations
      • Video 8 - Using the SaaS Offer REST Fulfillment API
      • Video 9 - The SaaS Client Library for .NET
      • Video 10 - Building a Simple SaaS Landing Page in .NET
      • Video 11 - Building a Simple SaaS Publisher Portal in .NET
      • Video 12 - SaaS Webhook Overview
      • Video 13 - Implementing a Simple SaaS Webhook in .NET
      • Video 14 - Securing a Simple SaaS Webhook in .NET
      • Video 15 - SaaS Metered Billing Overview
      • Video 16 - The SaaS Metered Billing API with REST
  • Microsoft Fabric
    • Theory
    • Prereqs
    • Fabric Capacity
    • Set up a Remote State
    • Create a repo from a GitHub template
    • Configure an app reg for development
    • Initial Terraform workflow
    • Expanding your config
    • Configure a workload identity
    • GitHub Actions for Microsoft Fabric
    • GitLab pipeline for Microsoft Fabric
  • Packer & Ansible
    • Packer
    • Ansible
    • Dynamic Inventories
    • Playbooks & Roles
    • Custom Roles
    • Shared Image Gallery
  • Partner Admin Link
    • Understanding PAL
    • User and guest IDs
    • Service principals with credentials
    • CI/CD pipelines & OpenID Connect
    • Using AzAPI in Terraform
    • PAL tagging with a service principal
    • Azure Lighthouse & PAL
    • PAL FAQ
  • REST API
    • REST API theory
    • Using az rest
  • Setup
  • Sovereign landing zone
    • Overview
    • Run the ALZ Accelerator
      • Prereqs
      • Elevate
      • Bootstrap
      • Demote
      • Components
    • Deploy Sovereign landing zone
      • Create an initial SLZ config
      • Add a local override library
      • Test locally
      • Run through the CI/CD workflow
    • Understanding libraries
      • What is a library?
      • Policies, Assignments and Roles
      • Archetypes, Overrides and Architecture
      • Metadata and Policy Default Values
      • Custom libraries
    • Reference configs
      • Sovereign landing zone
      • Sovereign landing zone library with overrides
      • SLZ extended with a country pack
  • Terraform
    • Fundamentals
      • Initialise
      • Format
      • Validate
      • Plan
      • Apply
      • Adding resources
      • Locals and outputs
      • Managing state
      • Importing resources
      • Destroy
    • Get set up for Terraform
      • Cloud Shell
      • macOS
      • Windows with PowerShell
      • Windows with Ubuntu in WSL2
    • Using AzAPI
      • Using the REST API
      • azapi_resource
      • Removing azapi_resource
      • azapi_update_resource
      • Data sources and outputs
      • Removing azapi_update_resource
  • Virtual Machines
    • Azure Bastion with native tools & AAD
    • Managed Identities

  • About
  • Archive
  1. Home
  2. Customer Managed Keys
  3. 🧪 Azure Key Vault Premium
🧪 Azure Key Vault Premium
🧪 Azure Key Vault Premium
Customer Managed Keys
Sovereignty scenarios
Key management options
🧪 Azure Key Vault Premium
L2: Encryption at rest with CMK
🧪 CMK for Storage
🧪 CMK for VM Disks and AKS
  • Objectives
  • Access
  • Why we use Key Vault Premium for these labs
  • Select a suitable region
  • Resource Group
  • Creating an Azure Key Vault Premium
  • Add an RBAC role assignment
  • Summary
  • Securing Azure Key Vault Premium
  • Managed HSM differences

🧪 Azure Key Vault Premium

Lab to create an Azure Key Vault Premium and generate keys for use in the later labs. Also links through to the Bring Your Own Key (BYOK) pages if you wish to import a key rather than generate.

Table of Contents

  • Objectives
  • Access
  • Why we use Key Vault Premium for these labs
  • Select a suitable region
  • Resource Group
  • Creating an Azure Key Vault Premium
  • Add an RBAC role assignment
  • Summary
  • Securing Azure Key Vault Premium
  • Managed HSM differences

Objectives

By the end of this lab you will have:

  • Determined a sensible Azure region for these labs.
  • Created a resource group.
  • Created an Azure Key Vault Premium and assigned yourself the Key Vault Crypto Officer role.

There is also some additional information on this page about securing vaults and some of the key differences in creating, activating and managing a Managed HSM instead.

Access

The labs assume you are either Owner or have Contributor plus Role Based Access Control Administrator on an Azure subscription as they create resources and RBAC role assignments.

They are also designed for the Azure CLI in a Bash context.

Why we use Key Vault Premium for these labs

Managed HSM would be the production-grade choice for dedicated HSM isolation, but can become dangerously expensive. It runs to thousand USD per month for a minimum cluster.

💀 Deleted Managed HSMs are chargeable until permanently purged after the retention period.

  • The current usage fee per HSM pool is $3.20 per hour. ($76.80 per day, or $2,336 per Azure month of 730 hours.)
  • A Managed HSM has enforced soft delete and purge protection for customer managed key scenarios.
  • A deleted Managed HSM would charge an additional $6,912 over the default retention period of 90 days.
  • You may specify a shorter retention period at creation time.
  • Retention times are immutable properties and cannot be changed.
  • The minimum retention period is 7 days which equates to $537.60.

Key Vault Premium replicates the experience closely enough: same API, same SKR flow, same CMK integration patterns across Azure services. Where a real Managed HSM deployment would differ (security domain, HSM RBAC, backup/recovery), we highlight it in each lab.

Key Vault Premium does not have a fixed charge itself. It charges purely for the keys and their operations. The HSM backed keys are a little more expensive, but in practice the cost for lab exercises is relatively small.

Note that Azure Key Vault Standard does not support Secure Key Release which is required for the Confidential Compute labs.

References

  • Azure Key Vault pricing (Standard and Premium)
  • How to choose the right Azure key management solution

Select a suitable region

The Secure Key Release (SKR) lab later on requires a Confidential VM from the DCasv5 or DCasv6 (AMD SEV-SNP), so we will work in a region where they are available.

Not all regions support these sizes — check the Azure products available by region page to find a region that works for you, and verify your subscription quota before starting.

  1. List all regions where DC2as virtual machines are available without any restrictions.

    az vm list-skus --size Standard_DC2as_v --location '' --query "sort_by([?restrictions==\`[]\`],&locations[0])[].{name:name,location:locations[0]}" -o table
    

    This command will take a little time to run as it is checking all regions. You can also specify the previous generation

    Example output:
    Name               Location
    -----------------  -------------
    Standard_DC2as_v5  ItalyNorth
    Standard_DC2as_v6  ItalyNorth
    Standard_DC2as_v6  WestUS3
    Standard_DC2as_v6  australiaeast
    Standard_DC2as_v5  eastus
    Standard_DC2as_v5  northeurope
    Standard_DC2as_v5  southeastasia
    Standard_DC2as_v6  uksouth
    Standard_DC2as_v6  westcentralus
    Standard_DC2as_v5  westus
    Standard_DC2as_v6  westus
    
  2. Check current quota and usage in a specific region (e.g., italynorth):

    az vm list-usage --location italynorth --query "[?contains(localName, 'DCas') || contains(localName, 'DCAS')]" -o table
    
    Example output:
    CurrentValue    Limit    LocalName
    --------------  -------  ----------------------------
    0               100      Standard DCASv5 Family vCPUs
    0               0        Standard DCasv6 Family vCPUs
    

Use these commands to select your region and VM SKU.

Italy North and Standard_DC2as_v5 will be used within these labs.

Resource Group

Set your default region and create a resource group for the labs. The AZURE_DEFAULTS_LOCATION and AZURE_DEFAULTS_GROUP environment variables are recognised by the Azure CLI and remove the need to pass --location and --resource-group on every command.

  1. Login and select your subscription.

  2. Set the default region.

    export AZURE_DEFAULTS_LOCATION=italynorth
    
  3. Create the resource group and set it as the default.

    az group create --name cmk
    export AZURE_DEFAULTS_GROUP=cmk
    
    Example output:
    {
      "id": "/subscriptions/73568139-5c52-4066-a406-3e8533bb0f15/resourceGroups/cmk",
      "location": "italynorth",
      "managedBy": null,
      "name": "cmk",
      "properties": {
        "provisioningState": "Succeeded"
      },
      "tags": null,
      "type": "Microsoft.Resources/resourceGroups"
    }
    

Creating an Azure Key Vault Premium

Standard tier does not support HSM-backed keys or Secure Key Release, so Premium is required. Key Vault names must be globally unique.

  1. Create a unique name and create the vault.

    resource_group_id=$(az group show --name $AZURE_DEFAULTS_GROUP --query id -o tsv)
    uniq=$(md5sum <<< $resource_group_id | cut -c1-8)
    key_vault_name=cmk-lab-${uniq}
    echo "$key_vault_name"
    
    Example output:
    cmk-lab-bd36f48c
    
  2. Create the vault.

    az keyvault create --name $key_vault_name \
      --sku premium \
      --enable-rbac-authorization true \
      --enable-purge-protection true \
      --retention-days 7
    
    Example output:
    {
      "id": "/subscriptions/73568139-5c52-4066-a406-3e8533bb0f15/resourceGroups/cmk/providers/Microsoft.KeyVault/vaults/cmk-lab-bd36f48c",
      "location": "italynorth",
      "name": "cmk-lab-bd36f48c",
      "properties": {
        "accessPolicies": [],
        "createMode": null,
        "enablePurgeProtection": true,
        "enableRbacAuthorization": true,
        "enableSoftDelete": true,
        "enabledForDeployment": false,
        "enabledForDiskEncryption": false,
        "enabledForTemplateDeployment": false,
        "hsmPoolResourceId": null,
        "networkAcls": null,
        "privateEndpointConnections": null,
        "provisioningState": "Succeeded",
        "publicNetworkAccess": "Enabled",
        "sku": {
          "family": "A",
          "name": "premium"
        },
        "softDeleteRetentionInDays": 7,
        "tenantId": "ac40fc60-2717-4051-a567-c0cd948f0ac9",
        "vaultUri": "https://cmk-lab-bd36f48c.vault.azure.net/"
      },
      "resourceGroup": "cmk",
      "systemData": {
        "createdAt": "2026-03-31T12:15:08.937000+00:00",
        "createdBy": "admin@MngEnvMCAP520989.onmicrosoft.com",
        "createdByType": "User",
        "lastModifiedAt": "2026-03-31T12:15:08.937000+00:00",
        "lastModifiedBy": "admin@MngEnvMCAP520989.onmicrosoft.com",
        "lastModifiedByType": "User"
      },
      "tags": {},
      "type": "Microsoft.KeyVault/vaults"
    }
    

    The --enable-rbac-authorization true switch sets the vault in RBAC mode. The labs use role assignments (rather than access policies) for the Azure services’ managed identities for the customer managed key wrap/unwrap actions.

Add an RBAC role assignment

By default you will have no ability to create keys within the key vault. (Note that the access control models for vaults is different to managed HSMs.)

  1. Add Key Vault Crypto Officer role assignment

    key_vault_id=$(az keyvault show --name $key_vault_name --query id -otsv)
    object_id="$(az ad signed-in-user show --query id -otsv)"
    az role assignment create --assignee "$object_id" --scope "$key_vault_id" --role "Key Vault Crypto Officer"
    
    Example output:
    {
      "condition": null,
      "conditionVersion": null,
      "createdBy": null,
      "createdOn": "2026-03-31T12:28:24.828012+00:00",
      "delegatedManagedIdentityResourceId": null,
      "description": null,
      "id": "/subscriptions/73568139-5c52-4066-a406-3e8533bb0f15/resourceGroups/cmk/providers/Microsoft.KeyVault/vaults/cmk-lab-bd36f48c/providers/Microsoft.Authorization/roleAssignments/83c8494f-039f-45c9-8feb-3d1800ccf91b",
      "name": "83c8494f-039f-45c9-8feb-3d1800ccf91b",
      "principalId": "74afa9e2-d243-414b-bab2-db8dd242827f",
      "principalType": "User",
      "resourceGroup": "cmk",
      "roleDefinitionId": "/subscriptions/73568139-5c52-4066-a406-3e8533bb0f15/providers/Microsoft.Authorization/roleDefinitions/14b46e9e-c2b7-41b4-b07b-48a6ebf60603",
      "scope": "/subscriptions/73568139-5c52-4066-a406-3e8533bb0f15/resourceGroups/cmk/providers/Microsoft.KeyVault/vaults/cmk-lab-bd36f48c",
      "type": "Microsoft.Authorization/roleAssignments",
      "updatedBy": "74afa9e2-d243-414b-bab2-db8dd242827f",
      "updatedOn": "2026-03-31T12:28:25.527015+00:00"
    }
    
    Got a token error? Click here.

    If you got the following error from the az ad signed-in-user command:

    Continuous access evaluation resulted in challenge with result:
    InteractionRequired and code: TokenCreatedWithOutdatedPolicies
    
    1. Clear your token cache and reauthenticate.

      az account clear
      az login
      
    2. Reapply the command block to create the role assignment.

References

  • https://learn.microsoft.com/azure/key-vault/general/rbac-guide

  • https://learn.microsoft.com/azure/role-based-access-control/built-in-roles/security#key-vault-crypto-officer

    The dataActions for Key Vault Crypto Office:
    "dataActions": [
      "Microsoft.KeyVault/vaults/keys/*",
      "Microsoft.KeyVault/vaults/keyrotationpolicies/*"
    ]
    

Summary

As a reminder, here are the objectives achieved in this lab.

  • Determined a sensible Azure region for these labs.
  • Created a resource group.
  • Created an Azure Key Vault Premium and assigned yourself the Key Vault Crypto Officer role.

OK, you’re set! You can move onto the next page if you like, or continue reading the additional information below.

Securing Azure Key Vault Premium

For these labs, the vault keeps public network access enabled so that the CLI steps work without additional networking setup. That is convenient for learning, but it would not usually be the production-ready posture.

For a production deployment, review the following controls:

  • Restrict public access with the Key Vault firewall, trusted services, or private endpoints.
  • Limit RBAC role assignments to the smallest practical scope and use separate identities for users, workloads, and automation.
  • Keep purge protection enabled and use a retention period that matches your recovery requirements.
  • Send diagnostic logs to Log Analytics, Event Hub, or Storage for audit and alerting.
  • Apply Azure Policy so vault networking, purge protection, and RBAC requirements are enforced consistently.
  • Review Microsoft Defender for Cloud recommendations and the Azure security baseline for Key Vault.

Note that the Azure Policy in the Azure Landing Zone and Sovereign Landing Zone sections provides a good set of guardrails.

References

  • https://learn.microsoft.com/azure/key-vault/general/network-security
  • https://learn.microsoft.com/azure/key-vault/general/private-link-service
  • https://learn.microsoft.com/azure/key-vault/general/soft-delete-overview
  • https://learn.microsoft.com/azure/key-vault/general/howto-azure-policy
  • https://learn.microsoft.com/azure/key-vault/general/logging
  • https://learn.microsoft.com/security/benchmark/azure/baselines/key-vault-security-baseline

Managed HSM differences

The Azure Key Vault Managed HSM has its own documentation area including a CLI quickstart.

Key creation differences

  • uses --hsm-name rather than --name
  • no need to specify the SKU; this is implicit in the switch above
  • mandatory requirement for --administrators with your object ID (or indeed a comma delimited list of object IDs)
  • no --enable-rbac-authorization as local RBAC is used to defined all data plane access
  • the URI endpoint changes to https://<hsm-name>.managedhsm.azure.net

After provisioning completes, the HSM must be activated by downloading the security domain before it can be used. You specify the RSA public keys (min 3, max 10) for encrypting the security domain and then it downloads. You also specify the minimum number of private keys required to achieve quorum for decryption.

You need to use the local RBAC model for data plane access. See the links below. Your managed identities will usually need the Managed HSM Crypto Service Encryption User role.

The Managed HSM is under your control and you have increased responsibilities. It is imperative that you safely store the security domain file and the RSA key pairs.

These are used for diaster recovery, or for creating additional Managed HSM instances in the same security domain if they are sharing keys.

References

  • https://learn.microsoft.com/azure/key-vault/managed-hsm/
  • https://learn.microsoft.com/azure/key-vault/managed-hsm/quick-create-cli
  • https://learn.microsoft.com/azure/key-vault/managed-hsm/security-domain
  • https://learn.microsoft.com/azure/key-vault/managed-hsm/access-control
  • https://learn.microsoft.com/azure/key-vault/managed-hsm/built-in-roles
  • https://learn.microsoft.com/security/benchmark/azure/baselines/key-vault-managed-hsm-security-baseline
  • https://learn.microsoft.com/azure/key-vault/managed-hsm/backup-restore

Treat this list as a good start, rather than exhaustive! If you are the administrator on your own Managed HSM then you should be familiar with all of the documentation in the https://learn.microsoft.com/azure/key-vault/managed-hsm area.

Source: https://www.azurecitadel.com/cmk/lab-akvp/
Published: 06 Mar 2026
Printed:
Key management options 🧪 Azure Key Vault Premium L2: Encryption at rest with CMK