This check flags Azure VM disks encrypted with a platform-managed key instead of your own customer-managed key (CMK). Without a CMK you have no control over the key lifecycle, rotation, or revocation. Fix it by creating a disk encryption set backed by an Azure Key Vault key and re-encrypting the disk against it.
Every managed disk in Azure is encrypted at rest by default. That sounds reassuring until you ask the obvious follow-up question: encrypted with whose key? By default, Azure handles the encryption keys for you using platform-managed keys (PMKs). It works, it requires zero setup, and for many low-sensitivity workloads it is perfectly fine. But the moment you need to prove control over your encryption keys, rotate them on your own schedule, or revoke access during an incident, platform-managed keys leave you with nothing to pull on.
The VM Disk Not Using Customer-Managed Key check identifies VM disks that rely on Azure's default platform-managed keys rather than a customer-managed key (also called BYOK, bring your own key). This post covers what that means, why it matters, and how to move your disks onto keys you actually control.
What this check detects
The check inspects each managed disk attached to your VMs and looks at how its server-side encryption is configured. Azure offers a few options for disk encryption at rest:
- Platform-managed keys (PMK): The default. Azure creates, stores, and rotates the encryption key entirely on its side. You never see it.
- Customer-managed keys (CMK / BYOK): You supply an RSA key stored in Azure Key Vault or Managed HSM. Azure uses it to wrap the data encryption key. You control its rotation, access policy, and revocation.
- Double encryption at rest: Two layers, one platform-managed and one customer-managed, for defense in depth.
This check fails when a disk falls into the first bucket: it is using server-side encryption with a platform-managed key and no disk encryption set is attached. In other words, Microsoft holds the only key, and your security and compliance teams have no way to manage it.
Note: Customer-managed keys for disks are wired up through a resource called a disk encryption set. The disk does not point directly at a Key Vault key. Instead it points at a disk encryption set, which in turn references a specific key version in Key Vault. This indirection is what lets you rotate keys without touching every disk.
Why it matters
Encryption at rest is only as meaningful as your control over the key. With a platform-managed key, you are trusting Microsoft to manage the entire key lifecycle, and you give up several capabilities that matter in real incidents and audits.
You cannot revoke access during an incident
Imagine you suspect a subscription has been compromised and an attacker may have cloned or copied disk data. With a customer-managed key, you can disable or delete the key version in Key Vault, and the disk becomes unreadable almost immediately. With a platform-managed key, you have no kill switch. The data stays decryptable for anyone with the right Azure permissions because the key is entirely outside your reach.
You cannot enforce your own rotation policy
Many compliance frameworks (PCI DSS, HIPAA-aligned controls, FedRAMP, internal crypto policies) require that you control and document key rotation. Platform-managed keys rotate on Microsoft's schedule, which you cannot configure or evidence in your own audit trail. A customer-managed key in Key Vault can be set to auto-rotate every 90 days, or whatever your policy dictates, with a clear log of every rotation event.
You lose separation of duties
With a CMK, the people who manage VMs and the people who manage encryption keys can be different teams with different RBAC roles. A VM admin cannot grant themselves access to the underlying key, and a key administrator cannot read disk data. Platform-managed keys collapse this separation because there is no key for your organization to administer at all.
Warning: Customer-managed keys do not protect against a fully privileged attacker who already controls both your VMs and your Key Vault. The benefit is in separation, revocation, and auditability, not in stopping someone who owns your entire tenant. Treat CMK as one layer in a broader access control strategy, not a silver bullet.
Audit and contractual obligations
If a customer contract or a regulator says "the customer must hold the encryption keys," platform-managed keys simply fail that requirement on paper. This check is often the difference between passing and failing a security questionnaire.
How to fix it
Moving a disk to a customer-managed key takes three pieces: a Key Vault with an RSA key, a disk encryption set that references that key, and the disk update itself. Here is the full sequence.
Step 1: Create a Key Vault and key
The Key Vault must have purge protection and soft delete enabled. Azure refuses to back a disk encryption set with a vault that lacks purge protection, because losing the key would make every disk permanently unrecoverable.
RG="rg-prod-vms"
LOCATION="eastus"
KV_NAME="kv-disk-cmk-prod"
KEY_NAME="vm-disk-key"
# Key Vault with purge protection (required for disk encryption sets)
az keyvault create \
--name "$KV_NAME" \
--resource-group "$RG" \
--location "$LOCATION" \
--enable-purge-protection true \
--enable-rbac-authorization true
# Create an RSA key for wrapping the disk encryption keys
az keyvault key create \
--vault-name "$KV_NAME" \
--name "$KEY_NAME" \
--kty RSA \
--size 2048
Step 2: Create the disk encryption set
DES_NAME="des-prod-vms"
KEY_ID=$(az keyvault key show \
--vault-name "$KV_NAME" \
--name "$KEY_NAME" \
--query "key.kid" -o tsv)
az disk-encryption-set create \
--name "$DES_NAME" \
--resource-group "$RG" \
--location "$LOCATION" \
--key-url "$KEY_ID" \
--source-vault "$KV_NAME"
The disk encryption set is created with a system-assigned managed identity. That identity needs permission to read the key from Key Vault.
DES_IDENTITY=$(az disk-encryption-set show \
--name "$DES_NAME" \
--resource-group "$RG" \
--query "identity.principalId" -o tsv)
KV_ID=$(az keyvault show \
--name "$KV_NAME" \
--resource-group "$RG" \
--query "id" -o tsv)
# Grant the DES identity the crypto role on the vault (RBAC mode)
az role assignment create \
--assignee "$DES_IDENTITY" \
--role "Key Vault Crypto Service Encryption User" \
--scope "$KV_ID"
Step 3: Re-encrypt the disk against the disk encryption set
Danger: Updating the encryption settings of an OS disk requires the VM to be deallocated, which means downtime. Plan this during a maintenance window. For attached data disks you also need to stop the VM. Never run this blind against a production VM during business hours.
VM_NAME="vm-prod-app-01"
DISK_NAME="vm-prod-app-01_OsDisk"
DES_ID=$(az disk-encryption-set show \
--name "$DES_NAME" \
--resource-group "$RG" \
--query "id" -o tsv)
# Deallocate the VM before changing OS disk encryption
az vm deallocate --name "$VM_NAME" --resource-group "$RG"
# Apply the customer-managed key via the disk encryption set
az disk update \
--name "$DISK_NAME" \
--resource-group "$RG" \
--disk-encryption-set "$DES_ID" \
--encryption-type EncryptionAtRestWithCustomerKey
# Start the VM again
az vm start --name "$VM_NAME" --resource-group "$RG"
Note: Existing disks can be migrated in place as shown above. For brand new disks, set the disk encryption set at creation time and you avoid any downtime entirely. The cheapest fix is the one you apply before the disk ever holds data.
Doing it in Terraform
If you manage infrastructure as code, encode the disk encryption set once and reference it from every disk. This is the cleanest long-term approach.
resource "azurerm_key_vault_key" "disk" {
name = "vm-disk-key"
key_vault_id = azurerm_key_vault.cmk.id
key_type = "RSA"
key_size = 2048
key_opts = ["wrapKey", "unwrapKey"]
}
resource "azurerm_disk_encryption_set" "vms" {
name = "des-prod-vms"
resource_group_name = azurerm_resource_group.prod.name
location = azurerm_resource_group.prod.location
key_vault_key_id = azurerm_key_vault_key.disk.id
identity {
type = "SystemAssigned"
}
}
resource "azurerm_managed_disk" "data" {
name = "vm-prod-app-01-data"
resource_group_name = azurerm_resource_group.prod.name
location = azurerm_resource_group.prod.location
storage_account_type = "Premium_LRS"
create_option = "Empty"
disk_size_gb = 256
disk_encryption_set_id = azurerm_disk_encryption_set.vms.id
}
How to prevent it from happening again
Fixing one disk is easy. Stopping the next hundred disks from launching with platform-managed keys is the real goal. Push the control upstream so nobody has to remember.
Use Azure Policy to deny non-compliant disks
There is a built-in policy that audits or denies managed disks that are not encrypted with a customer-managed key. Assign it at the subscription or management group level.
# "Managed disks should be double encrypted with both platform-managed
# and customer-managed keys" / CMK audit policies exist as built-ins.
az policy assignment create \
--name "require-disk-cmk" \
--display-name "Require customer-managed keys on managed disks" \
--policy "ca91455f-eece-41e2-a2f7-1caf8c30b9bf" \
--scope "/subscriptions/$SUBSCRIPTION_ID" \
--params '{ "effect": { "value": "Audit" } }'
Start in Audit mode to see your existing footprint, then switch the effect to Deny once teams have migrated. Deny mode blocks the creation of any new disk without a disk encryption set, which closes the gap permanently.
Tip: Roll out a Deny policy gradually. Apply it to a sandbox subscription first, confirm legitimate deployments still succeed when they reference a disk encryption set, then promote it to your production management group. A surprise deny policy across all of prod will generate a lot of broken pipeline tickets.
Gate it in CI/CD
If you deploy infrastructure through Terraform or Bicep, catch the problem before it reaches Azure. Tools like Checkov, tfsec, or Terrascan have rules for disk encryption sets. A simple pipeline step keeps PMK disks out of your codebase.
# Run Checkov against your Terraform plan in CI
checkov -d . --framework terraform \
--check CKV_AZURE_93 # Ensure managed disks use a customer-managed key
Bake it into your modules
The most durable fix is to make the secure path the only path. If every team consumes a shared Terraform module for VMs, set disk_encryption_set_id as a required variable inside that module. Then no consumer can create a disk without supplying one, and the question of platform versus customer-managed key never comes up at deploy time.
Best practices
- Enable key auto-rotation. Configure a rotation policy on the Key Vault key so it cycles on a fixed schedule. Disk encryption sets can be set to automatically pick up the latest key version.
- Always enable purge protection and soft delete on any vault backing a disk encryption set. Losing the key without purge protection means losing the data, with no recovery.
- Separate duties with RBAC. Give the disk encryption set identity only the Key Vault Crypto Service Encryption User role, nothing broader. Keep key administration with a separate team.
- Consider double encryption for highly sensitive workloads. Combining a platform-managed and customer-managed layer adds defense in depth at a modest performance cost.
- Monitor the key, not just the disk. Send Key Vault diagnostic logs to your SIEM so you can alert on key disable, delete, and access-denied events. A revoked key is meaningless if nobody notices the disk has gone dark.
- Apply the same pattern to snapshots and images. Snapshots created from a CMK disk should also use a disk encryption set, otherwise you reopen the gap every time someone takes a backup.
Tip: Use one disk encryption set per environment and region rather than one per disk. It keeps RBAC simple, makes rotation a single action, and gives you a clean inventory of which workloads share a key boundary.
Platform-managed keys are a reasonable default for throwaway and low-sensitivity workloads. But for anything that holds regulated, customer, or business-critical data, control of the key is control of the data. Moving your VM disks onto customer-managed keys gives you the revocation, rotation, and audit story that compliance teams expect and that incident responders will thank you for.

