Azure Lesson 65 of 137

Azure Managed HSM and Secure Key Release: Attestation-Gated Keys for Confidential Workloads

In a nutshell

Imagine a bank vault that will only open for an armored truck - and not just any truck, but one that a trusted notary has inspected, sealed, and certified on the spot as genuinely armored: right doors, right guards, right serial number. If a plain van pulls up claiming to be the armored truck, the vault stays shut, because the notary refuses to vouch for it. Secure Key Release (SKR) is that vault. The key lives inside dedicated hardware (Azure Managed HSM), and the HSM refuses to release it until an independent notary - Microsoft Azure Attestation (MAA) - cryptographically confirms that the machine asking for the key is genuinely a locked confidential enclave (a CPU-encrypted VM) running exactly the software you expect. No certification from the notary, no key.

Why does this even need to exist? Ordinary encryption protects data at rest (on disk) and in transit (on the wire), but the instant an application decrypts and uses a key, that key sits in plain memory - where a cloud operator, a compromised hypervisor, or a malicious host could in principle read it. Confidential computing closes that last gap by encrypting memory in use, inside the CPU, and attestation is how a remote party (here, the HSM) gets hard proof of that before trusting the machine with anything valuable. Put the two together and you get a key that is not merely stored securely but is physically unusable anywhere except inside one verified enclave - which is exactly what a regulator means when they demand that “the cloud provider’s own operators must not be able to use this key.”

If you are new to all this, you do not need to build it to understand it. Read for the shape of the trust - who proves what, to whom, and in what order - and the commands will click on a second pass. The three moving parts are always the same: a confidential VM (the thing that must prove itself), an attestation service (the notary), and a Managed HSM (the vault that checks the notary’s certificate against a policy before releasing the key).

Level: Expert · Time: ~46 min

Prerequisites: You should be comfortable with Azure Key Vault, managed identities, and secret retrieval, the basics of confidential computing on Azure, and how customer-managed keys and double encryption work - because a recurring theme here is how SKR differs from CMK. Familiarity with RSA public-key wrapping, RBAC, and reading a JWT’s claims will help.

After this lesson you can:

Secure Key Release: attested confidential VM → MAA token → Managed HSM releases the key

Left to right: the confidential VM asks its CPU for a hardware attestation report, Microsoft Azure Attestation validates it and signs a short-lived token of claims, the VM’s managed identity presents that token to Managed HSM, and only if the token’s claims satisfy the key’s release_policy does the HSM hand back the key - wrapped so it is usable only inside that one attested enclave.

Standard Key Vault gives you a multi-tenant, HSM-backed key store that Microsoft operates for you. That is the right tool for most workloads, and the wrong tool when your threat model says Microsoft operators must never be able to touch your key material, when a regulator demands a single-tenant HSM at FIPS 140-3 Level 3, or when you want a key to be physically unusable outside a CPU you have cryptographically verified. That is the territory of Azure Managed HSM with Secure Key Release (SKR): a key that exists only inside dedicated HSM hardware and is released, wrapped, only to a confidential VM whose AMD SEV-SNP report you have attested.

This is an expert path involving a quorum key ceremony, an offline security domain, and an attestation pipeline. Read it end to end before provisioning anything - some decisions here are irreversible.

1. When you actually need Managed HSM

Reach for Managed HSM, not the Premium SKU of Key Vault, when at least one of these is true:

Cost and operational weight are real. A Managed HSM pool is billed per hour regardless of key count and obligates you to custody of the security domain backup. Do not provision one to hold three secrets. Provision one to be the root of trust for an estate.

2. Provision and activate the pool

Managed HSM has two phases: the resource is provisioned (created in ARM, but cryptographically inert) and then activated (the security domain is generated and downloaded). Between those two steps you supply the quorum of RSA public keys.

Create the pool. The --administrators flag takes Entra object IDs that become the initial local RBAC administrators. --retention-days sets the soft-delete window and cannot be lowered after creation.

az keyvault create --hsm-name kv-mhsm-prod \
  --resource-group rg-security-core \
  --location eastus2 \
  --retention-days 90 \
  --administrators "$(az ad signed-in-user show --query id -o tsv)"

Provisioning returns once the pool exists but reports securityDomain as not activated. Generate three or more RSA key pairs for the quorum holders. In production these private keys live on separate hardware tokens held by separate humans; here we generate them for illustration.

for i in 1 2 3; do
  openssl req -newkey rsa:2048 -nodes -keyout sd-key-$i.key \
    -x509 -days 3650 -subj "/CN=sd-holder-$i" -out sd-cert-$i.cer
done

Activate with a quorum. --sd-quorum 2 means any two of the three certificate holders must cooperate to ever decrypt the security domain.

az keyvault security-domain download --hsm-name kv-mhsm-prod \
  --sd-wrapping-keys sd-cert-1.cer sd-cert-2.cer sd-cert-3.cer \
  --sd-quorum 2 \
  --security-domain-file kv-mhsm-prod-SD.json

The downloaded kv-mhsm-prod-SD.json is the security domain, encrypted such that 2-of-3 private keys are required to recover it. This file plus the private keys are the only way to recover the HSM into a new pool after a disaster. Lose them and the keys are gone permanently - that is the design, not a bug.

3. Design the quorum and key ceremony

The quorum is a governance decision, not a technical default. Get it wrong and you either cannot recover (quorum too high, holders unavailable) or you have weak custody (quorum too low). A workable pattern for a regulated estate:

Role Count (N) Quorum (M) Custody
Security domain holders 5 3 FIPS-validated tokens, 3 sites
HSM administrators (RBAC) 3-4 n/a Break-glass + PIM-elevated

Run the activation as a formal ceremony: witnessed, scripted, with each private key generated on its holder’s token and never exported. Record certificate thumbprints in your CMDB. The output you protect forever is the SD file plus the holders’ private keys, stored separately so no single location can both decrypt and reach the file.

After activation, switch the data-plane authentication to local RBAC. Managed HSM does not use Azure RBAC for data operations - it has its own built-in role model evaluated by the HSM itself. Assign the narrowest roles. A crypto user can use keys but not manage them; only an administrator can change role assignments.

# Service identity that will only *use* keys, never manage them
az keyvault role assignment create --hsm-name kv-mhsm-prod \
  --role "Managed HSM Crypto User" \
  --assignee "<app-managed-identity-object-id>" \
  --scope /keys
# Separate identity allowed to import keys (BYOK)
az keyvault role assignment create --hsm-name kv-mhsm-prod \
  --role "Managed HSM Crypto Officer" \
  --assignee "<key-import-pipeline-object-id>" \
  --scope /keys

4. Import on-prem keys with BYOK and verify provenance

If a key was generated on your on-premises HSM and policy says it must never have existed in software, you import it under wrap (BYOK) so the plaintext key never transits Azure unencrypted. The flow:

  1. Download the Key Exchange Key (KEK) public key from the target HSM. The KEK is an RSA-HSM key generated inside the Managed HSM with import in its key operations.
  2. On your on-prem HSM, wrap the target key to that KEK using the vendor’s BYOK tool, producing a Key Transfer Blob.
  3. Upload the blob. The Managed HSM unwraps it inside the cryptographic boundary.

Create the KEK inside the HSM first - note it is hardware-backed (RSA-HSM) and marked for import:

az keyvault key create --hsm-name kv-mhsm-prod \
  --name byok-kek --kty RSA-HSM --size 4096 \
  --ops import \
  --immutable false

Your HSM vendor’s BYOK tooling consumes the KEK public key and emits a transfer blob (key-transfer.byok). Import it:

az keyvault key import --hsm-name kv-mhsm-prod \
  --name payments-wrap-key \
  --byok-file key-transfer.byok

To prove provenance to an auditor, request the key’s attestation - Managed HSM can return a signed statement, chained to the Microsoft HSM vendor root, asserting the key is non-exportable and resident in the HSM. Pull it and validate the certificate chain offline:

az keyvault key get-attestation --hsm-name kv-mhsm-prod \
  --name payments-wrap-key \
  --file payments-wrap-key.attest

The attestation bundle contains the certificate chain plus the attestation blobs. Validate the chain against the vendor root certificate published by Microsoft; that is what turns “we promise it’s in the HSM” into a verifiable claim.

5. Configure the secure key release policy

This is the heart of the design. A key marked exportable with a release policy can be exported - but only when the caller presents an attestation token from Microsoft Azure Attestation (MAA) whose claims satisfy the policy. The key leaves the HSM only as a wrapped blob bound to that attested environment.

Write the policy as a BearerToken-grammar JSON document. The authority must match your MAA instance, and allOf/anyOf express the claim conditions. A minimal policy that gates on a SEV-SNP confidential VM:

{
  "version": "1.0.0",
  "anyOf": [
    {
      "authority": "https://sharedeus2.eus2.attest.azure.net",
      "allOf": [
        {
          "claim": "x-ms-isolation-tee.x-ms-attestation-type",
          "equals": "sevsnpvm"
        },
        {
          "claim": "x-ms-isolation-tee.x-ms-compliance-status",
          "equals": "azure-compliant-cvm"
        }
      ]
    }
  ]
}

Create the releasable key with that policy attached. The --exportable flag is meaningless without --policy; together they mean “exportable only under attestation.”

az keyvault key create --hsm-name kv-mhsm-prod \
  --name cvm-data-key --kty RSA-HSM --size 3072 \
  --exportable true \
  --policy @skr-policy.json

x-ms-compliance-status: azure-compliant-cvm is doing heavy lifting: it asserts MAA validated the SEV-SNP report against Azure’s baseline (genuine AMD silicon, expected firmware, secure boot state). Pin additional claims - x-ms-sevsnpvm-hostdata to bind to a specific guest image measurement, or x-ms-sevsnpvm-bootloader-svn to enforce a minimum firmware version - when you need to tie release to one exact workload.

6. Release the key inside a confidential VM

On the confidential VM (a DCasv5/ECasv5-series SEV-SNP guest), the workload obtains an MAA token and exchanges it for the wrapped key. The clean path uses the Azure SKR tooling, which talks to the in-guest attestation client to fetch a fresh SEV-SNP report and have MAA sign it.

Boot a confidential VM with a Microsoft-defaulted attestation configuration:

az vm create --resource-group rg-confidential \
  --name cvm-payments-01 \
  --image "Canonical:ubuntu-24_04-lts:cvm:latest" \
  --size Standard_DC4as_v5 \
  --security-type ConfidentialVM \
  --enable-vtpm true --enable-secure-boot true \
  --os-disk-security-encryption-type DiskWithVMGuestState \
  --admin-username azureuser --generate-ssh-keys

Inside the guest, perform the release. The AzureAttestSKR helper (shipped in Microsoft’s confidential-computing CVM guest-attestation repo) fetches the report, gets the MAA token, calls the /keys/{name}/release endpoint, and returns the key:

sudo ./AzureAttestSKR \
  -a https://sharedeus2.eus2.attest.azure.net \
  -k https://kv-mhsm-prod.managedhsm.azure.net/keys/cvm-data-key \
  -c imds \
  -u  # unwrap into the guest TEE

If you are wiring this into your own service, the data-plane call is the REST release operation with the MAA JWT in the body. The HSM re-validates the token’s signature and claims against the key’s policy before responding with the wrapped key:

POST https://kv-mhsm-prod.managedhsm.azure.net/keys/cvm-data-key/release?api-version=7.4
Content-Type: application/json

{ "target": "<MAA-attestation-jwt>" }

The response is the key wrapped to the attested environment. A request from a non-attested host, or one whose SEV-SNP report fails MAA validation, never gets a usable key - the HSM refuses the release.

7. Lock down the perimeter

The cryptographic controls above are worthless if the management and data planes are reachable from anywhere. Three controls, all mandatory for production:

Private endpoint. Put the HSM behind Private Link and set public network access to disabled so the data plane is only reachable from your VNets.

az network private-endpoint create --name pe-mhsm \
  --resource-group rg-security-core \
  --vnet-name vnet-hub --subnet snet-privatelink \
  --private-connection-resource-id "$(az keyvault show --hsm-name kv-mhsm-prod --query id -o tsv)" \
  --group-id managedhsm \
  --connection-name mhsm-conn
az keyvault update-hsm --hsm-name kv-mhsm-prod \
  --resource-group rg-security-core \
  --public-network-access Disabled

Purge protection. With purge protection on, even a soft-deleted HSM cannot be permanently removed before the retention window elapses - this defeats a ransomware-style “delete the keys” attack. It is irreversible once enabled.

az keyvault update-hsm --hsm-name kv-mhsm-prod \
  --resource-group rg-security-core \
  --enable-purge-protection true

Least-privilege RBAC. Keep the administrator role count tiny and behind PIM. Crypto Officers import and rotate; Crypto Users only sign, wrap, and release. No identity should hold both Administrator and Crypto Officer in steady state.

8. Operational runbook

Treat the HSM as a system with a lifecycle, not a vault you fill and forget.

Full backup. Back up the entire HSM (all keys, versions, and RBAC) on a schedule to a storage container the HSM identity can write to:

az keyvault backup start --hsm-name kv-mhsm-prod \
  --blob-container-name mhsm-backups \
  --storage-account-name stsecbackups \
  --use-managed-identity true

Disaster recovery. Recovery into a brand-new pool in another region requires the security domain file and the quorum of private keys - this is the only path, which is why custody of those artifacts is the single most important control you own. Provision a fresh pool, then upload the SD with the quorum to reconstitute it.

Key lifecycle. SKR keys should rotate on a defined cadence. A new version inherits the release policy; old versions stay readable for in-flight unwraps until you disable them. Drive this with a rotation policy and watch the audit log.

Going deeper

Everything above is the how. This section is the why underneath - the internals, edge cases, and design forks that separate a lab that works once from a system an auditor signs off on.

Managed HSM vs Key Vault Premium - the differences that matter

Both are “HSM-backed key stores,” so they look interchangeable on a feature grid. They are not. The distinctions are about the trust boundary, not the API.

Property Key Vault Premium Managed HSM
Tenancy of the HSM Multi-tenant (shared pool, per-key HSM protection) Single-tenant - a dedicated pool of partitions is yours alone
FIPS validation 140-2 Level 3 140-3 Level 3
Data-plane authorization Azure RBAC + optional access policies Local RBAC, evaluated by the HSM, separate from Azure RBAC
Root-of-trust custody Microsoft-held Security domain you own under an M-of-N quorum
Secure Key Release Supported Supported
Billing Per-operation + per-key (Premium HSM keys) Per-hour for the pool, regardless of key count
Cross-region HA Microsoft-managed replication Pool spans availability zones in-region; cross-region DR is manual (SD restore)

The one that trips people up is authorization. On Key Vault, you grant “Key Vault Crypto User” as an Azure role and it shows up in your subscription’s access reviews. On Managed HSM, the equivalent grant is invisible to Azure RBAC - it lives inside the HSM, is assigned with az keyvault role assignment create --hsm-name ..., and is scoped either to the whole HSM (/) or to keys (/keys). Your governance tooling that reads Microsoft.Authorization/roleAssignments will simply not see it. Plan for that: local RBAC needs its own review process.

The security domain and quorum, mechanically

The security domain (SD) is what makes “Microsoft cannot use your key” a mathematical statement rather than a promise. At activation you hand the HSM 3 to 10 RSA public keys and a quorum threshold (minimum 2). The HSM generates the domain - which contains the wrapping keys that protect every key you will ever create - and returns it encrypted so that any M of the N private keys can decrypt it, and fewer than M can decrypt nothing.

Consequences that follow directly from that design:

Local RBAC: the roles you will actually assign

Managed HSM ships a small set of built-in local roles. You assign them at / (HSM-wide) or /keys (or a specific key). The separation of use from manage is the whole point - keep them apart.

Role Can do Typical holder
Managed HSM Administrator Manage role assignments, security domain, full control 2-3 humans, PIM + break-glass only
Managed HSM Crypto Officer Create, import, rotate, delete keys Key-provisioning pipeline
Managed HSM Crypto User Use keys: sign, verify, wrap, unwrap, encrypt, decrypt, release Application managed identity
Managed HSM Crypto Service Encryption User Use a key for service-side encryption (CMK for Storage, SQL, disks) The service’s managed identity
Managed HSM Policy Administrator Manage key-level RBAC policy Governance automation
Managed HSM Crypto Auditor Read key metadata, list, audit (no crypto ops) Compliance / read-only reviewer
Managed HSM Backup Perform backup operations Backup automation identity

Note that release is a Crypto User operation, not an administrative one - the app identity that consumes the released key needs Crypto User, nothing more. An identity that holds both Administrator and Crypto Officer in steady state is a finding waiting to happen; split them.

How a release policy is actually evaluated

The release_policy is not a filter that runs once at creation - it is re-evaluated by the HSM on every release call. The grammar is deliberately small:

Exportable keys that support a release policy include RSA-HSM, EC-HSM, and oct-HSM (symmetric). On a successful release the HSM does not hand back the raw key - it wraps the key to the attested environment’s ephemeral public key (carried in the MAA token), so only that enclave can unwrap it. That wrapping is why a released key intercepted on the wire is inert to anyone but the target TEE.

The claims worth knowing:

Claim Binds release to When to pin it
x-ms-attestation-type = sevsnpvm / tdxvm AMD SEV-SNP or Intel TDX hardware Always
x-ms-compliance-status = azure-compliant-cvm MAA validated the report against Azure’s baseline Always
x-ms-sevsnpvm-hostdata One exact guest-image / container-policy measurement High-value keys, one blessed build
x-ms-sevsnpvm-bootloader-svn A minimum firmware security version number Enforce a patch floor
x-ms-sevsnpvm-is-debuggable = false Non-debuggable guests only Always, for production

Confidential computing: SEV-SNP vs TDX, and the token flow

Two hardware families back Azure confidential VMs, and SKR works with both:

The token flow is the same in shape. The guest runs with a vTPM and secure boot; a guest-attestation client asks the CPU for a hardware-signed report (the SEV-SNP “quote” or TDX quote), which measures firmware, boot state, and guest configuration. The client sends that report to MAA over IMDS collateral (-c imds). MAA validates it against the platform baseline and returns a short-lived, signed JWT whose claims describe exactly what was measured. The HSM never talks to the CPU - it only ever trusts MAA’s signature over MAA’s claims. That indirection is what lets a stateless HSM make a hardware-rooted decision.

Two operational subtleties bite people:

Confidential containers and ACI

You do not need a full VM to hold a key under SKR. Confidential containers on Azure Container Instances (ACI) run on SEV-SNP and produce their own attestation. The clever part: the container group’s confidential computing enforcement (CCE) policy - the allow-list of what may run in the group - is measured, and its hash surfaces as x-ms-sevsnpvm-hostdata. That means you can pin an SKR key to one exact container policy: change the image, the command, or the mounts, and the hostdata changes, and release fails. It is the same operator-exclusion property as a CVM, at container granularity.

On AKS, the equivalent is Confidential Containers (Kata + SEV-SNP), giving pod-level TEEs. Availability moves quickly across regions and versions, so confirm the current GA/preview status for your target region before you design around it. The SKR mechanics are identical - only the thing being measured (a pod’s policy vs a VM’s image) changes.

BYOK vs HYOK vs generate-in-HSM

Where a key is born determines what you can prove about it. Three postures:

Posture Where the key is generated What you can assert Trade-off
Generate in HSM Inside the Managed HSM Key never existed in software; key attestation proves residency Simplest; provenance rooted in Azure hardware
BYOK (import under wrap) On your on-prem HSM, imported wrapped to the KEK Plaintext never transited Azure; on-prem origin You custody the on-prem generation ceremony
“HYOK”-style On your own HSM, never leaves it in usable form Strongest on-prem provenance claim Heaviest to operate; Azure only ever sees ciphertext

BYOK is the workhorse. Note the direction of the wrap: the KEK is generated inside Managed HSM as an RSA-HSM key marked for import; you export its public half, wrap your target key to it on-prem, and upload the transfer blob. The Managed HSM unwraps inside the boundary. At no point does the plaintext key touch Azure software - that is the whole assurance. “HYOK” (hold your own key) is a stricter mindset than a distinct Azure feature: it means the key’s usable form never leaves your custody, and you accept the operational weight that buys.

SKR vs CMK vs double encryption - do not conflate them

These three all involve “your key” but grant fundamentally different properties. Auditors care which one you actually have.

Control What it protects against Who can use the key at runtime
CMK (customer-managed key) Data readable if storage is stolen; instant revocation by disabling the key The Azure service (and its operators, within the service) - the key is released into the service’s encryption context
Double / infrastructure encryption A single-layer cryptographic break (two independent layers) Same as CMK - it is about layers, not operator exclusion
Secure Key Release Anyone outside a verified enclave - including the cloud provider’s operators Only code running inside the one attested TEE

The trap is assuming CMK already gives you operator exclusion. It does not: with CMK, Storage or SQL decrypts your data using your key on Microsoft-operated infrastructure - you can revoke the key, but while it is enabled the service is using it. SKR is the only one of the three where the key is unusable outside hardware you have cryptographically verified. If a requirement literally says “the provider must not be able to use the key,” CMK fails it and SKR passes it. (For the CMK and double-encryption mechanics, see encryption at rest with CMK and double encryption.)

Cost, HA, and the failure modes to plan for

Enterprise scenario

A European payments platform had to satisfy a banking supervisor’s requirement that the data-encryption keys for cardholder data be (a) in a single-tenant FIPS 140-3 Level 3 HSM and (b) provably unusable by anyone other than the production tokenization service - explicitly including the cloud provider’s own operators. Their first design used Key Vault Premium with RBAC, but the audit failed on two points: the HSM was multi-tenant, and “operators cannot use the key” could not be demonstrated, only asserted.

They moved to Managed HSM and inverted the trust model with SKR. The tokenization service runs on DCasv5 SEV-SNP confidential VMs from a hardened, measured image. They generated the master key in the HSM as exportable with a release policy pinned not just to sevsnpvm and azure-compliant-cvm but to the exact image measurement via x-ms-sevsnpvm-hostdata, so only that one build of the tokenization service could ever obtain the key:

{
  "claim": "x-ms-isolation-tee.x-ms-sevsnpvm-hostdata",
  "equals": "9c8e...the-expected-image-measurement...f1"
}

The result satisfied the supervisor cleanly. The single-tenant Level 3 boundary covered requirement (a). For (b), the security domain (3-of-5 quorum, tokens held by the bank’s own officers across three sites) meant Microsoft mathematically could not decrypt the HSM, and the host-data-pinned release policy meant the key could be unwrapped only inside the attested, measured tokenization VMs - not by an operator, not by a rebuilt image, not from any non-confidential host. The one painful lesson: their first hostdata value was wrong because they hashed the image artifact instead of using the measurement MAA actually reports, and every release silently failed with a policy mismatch until they read the rejected token’s claims and corrected the pin.

Verify

Confirm the system behaves as designed, not just as configured.

Checklist

Practice challenges

Work these in order - they escalate from “read the threat model” to “design the failure path.” No live Azure subscription is assumed; the solutions are the commands, policies, and reasoning you would apply.

1. (Beginner) Managed HSM or Key Vault Premium? For each requirement, say which service clears it: (i) “keys must sit in a single-tenant HSM”; (ii) “we need a FIPS 140-3 Level 3 attestation letter”; (iii) “store a dozen app secrets cheaply.”

<details><summary>Show solution</summary>

(i) Managed HSM - Premium is multi-tenant HSM-backed. (ii) Managed HSM - Premium is FIPS 140-2 Level 3; only Managed HSM is 140-3 Level 3. (iii) Neither - use Key Vault Standard/Premium; a per-hour Managed HSM pool for a dozen secrets is money set on fire.

Why: the choice is driven by tenancy, FIPS level, and cost profile - not by which one “has more features.” </details>

2. (Beginner) Provision and confirm activation state. Create a pool with a 90-day soft-delete window and yourself as the initial administrator, then show how you would confirm it is activated (not merely provisioned).

<details><summary>Show solution</summary>

az keyvault create --hsm-name kv-mhsm-lab \
  --resource-group rg-security-core --location eastus2 \
  --retention-days 90 \
  --administrators "$(az ad signed-in-user show --query id -o tsv)"

# Provisioned != activated. Check the security-domain state:
az keyvault show --hsm-name kv-mhsm-lab --query securityDomainProperties

Why: provisioning creates an inert resource; the pool is only usable after the security domain is downloaded, and --retention-days cannot be lowered later - set it deliberately at create time. </details>

3. (Intermediate) Least-privilege local RBAC. Grant an application managed identity the ability to use and release keys but never manage them, and a pipeline identity the ability to import keys but never use them.

<details><summary>Show solution</summary>

# App: use + release only
az keyvault role assignment create --hsm-name kv-mhsm-prod \
  --role "Managed HSM Crypto User" \
  --assignee "<app-managed-identity-object-id>" --scope /keys

# Pipeline: create/import only
az keyvault role assignment create --hsm-name kv-mhsm-prod \
  --role "Managed HSM Crypto Officer" \
  --assignee "<key-import-pipeline-object-id>" --scope /keys

Why: release is a Crypto User operation, so the app needs only Crypto User; import lives with Crypto Officer. Splitting them keeps any single compromised identity from both minting and exfiltrating keys - and remember these grants are invisible to Azure RBAC reviews. </details>

4. (Intermediate) A release policy for Intel TDX. Rewrite the SEV-SNP gate from section 5 to accept an Intel TDX confidential VM instead, and additionally require a non-debuggable guest.

<details><summary>Show solution</summary>

{
  "version": "1.0.0",
  "anyOf": [
    {
      "authority": "https://sharedeus2.eus2.attest.azure.net",
      "allOf": [
        { "claim": "x-ms-isolation-tee.x-ms-attestation-type", "equals": "tdxvm" },
        { "claim": "x-ms-isolation-tee.x-ms-compliance-status", "equals": "azure-compliant-cvm" },
        { "claim": "x-ms-isolation-tee.x-ms-sevsnpvm-is-debuggable", "equals": "false" }
      ]
    }
  ]
}

Why: the only structural change from SEV-SNP is x-ms-attestation-type = tdxvm; the compliance claim and the policy grammar are identical, which is the whole point of MAA normalizing across hardware. Pinning is-debuggable = false blocks a debug-enabled guest from ever obtaining the key. </details>

5. (Advanced) Pin to one exact image - and diagnose the silent failure. You want the key released only to build 9c8e...f1 of your workload. Write the extra claim, then explain how you would debug the case where every release fails with a policy mismatch even though you “used the right hash.”

<details><summary>Show solution</summary>

{ "claim": "x-ms-isolation-tee.x-ms-sevsnpvm-hostdata",
  "equals": "9c8e...the-measurement-MAA-reports...f1" }

Debug path: capture the rejected MAA token the guest actually presented, decode its claims (it is a JWT - Base64URL-decode the payload), and compare its x-ms-sevsnpvm-hostdata against your pinned value. The classic bug is hashing the image artifact yourself instead of using the measurement MAA reports - the two rarely match.

Why: SKR fails closed and silent - a claim mismatch looks identical to a policy that is “just not matching.” The token’s own claims are the ground truth; never trust a hash you computed out-of-band. </details>

6. (Advanced) Design the DR + operator-exclusion proof. Your primary region is gone. List exactly what you must possess to reconstitute the HSM elsewhere, and describe how you would demonstrate to an auditor that Microsoft cannot use the key - not merely assert it.

<details><summary>Show solution</summary>

To reconstitute: (1) the security-domain file, (2) a quorum of the SD private keys (M of N), and (3) a full HSM backup in reachable storage. Provision a fresh pool, upload the SD with the quorum, then restore the backup. Missing the SD or the quorum = permanent, unrecoverable loss - by design.

To demonstrate operator exclusion: show that the SD is encrypted to keys held only by your officers (Microsoft holds only ciphertext, so it cannot decrypt the pool), and show that the production key’s release_policy pins hostdata to one measured build, so the key is unwrappable only inside that attested enclave - not by an operator, not by a rebuilt image, not from any non-confidential host. Then prove it: from a non-attested host, capture the release rejection.

Why: “operator exclusion” is two independent facts - Microsoft cannot decrypt the domain (custody), and the key is unusable outside the enclave (attestation). An auditor wants both shown, not one asserted. </details>

Common beginner mistakes

Glossary

Managed-HSMsecure-key-releaseconfidential-computingattestationFIPS-140-3BYOK
Need this built for real?

Vinod is a Senior Cloud Architect (22+ yrs) — available for Azure / AWS / GCP architecture, landing zones, and migrations.

Work with me

Comments