Skip to main content

Azure Key Vault Key Wrapping

Use Azure Key Vault to protect the Trust Domain Server's signing key material at rest. Signing keys are encrypted before being written to the Kubernetes CRD, with a Key Vault-held key acting as the Key Encrypting Key (KEK). The KEK never leaves Azure infrastructure.

info

This page covers key wrapping — encrypting stored signing keys at rest. If you want signing keys to live entirely inside Azure Key Vault so they never enter server memory, see Azure Key Vault Key Manager instead.

How it works

The Trust Domain Server uses envelope encryption. When it needs to persist a signing key, the server generates a fresh AES-256-GCM data-encryption key (DEK) and uses it to encrypt the signing key locally. It then asks Azure Key Vault to wrap the DEK with the KEK. The CRD stores the encrypted signing key alongside the wrapped DEK. To decrypt, the server asks Azure Key Vault to unwrap the DEK, then decrypts the signing key locally with it.

The Key Vault key acts as the KEK and never leaves Azure infrastructure. Azure Key Vault only ever sees DEKs, and the signing-key plaintext never leaves the Trust Domain Server.

Prerequisites

  • Managed HSM required. The purpose of key wrapping is to ensure that only you control the KEK. Defakto infrastructure never has access to it; encryption and decryption of your signing key material happen entirely within your Azure tenant. On Azure, the only service that enforces this guarantee for symmetric keys is a Managed HSM.
  • Workload Identity. The Trust Domain Server must have an Azure Workload Identity (or Managed Identity) with permissions on the Managed HSM.

How to Deploy

Step 1 — Provision a Managed HSM

If you do not already have a Managed HSM, create one:

az group create -l eastus -n my-resource-group

oid=$(az ad signed-in-user show --query id -o tsv)
az keyvault create \
--hsm-name my-managed-hsm \
--location eastus \
--resource-group my-resource-group \
--administrators $oid \
--retention-days 90

A newly provisioned Managed HSM must be activated before it can perform cryptographic operations. Activation requires downloading the security domain with a quorum of RSA key pairs:

openssl req -newkey rsa:2048 -nodes -keyout cert_0.key -x509 -days 365 -out cert_0.cer -subj "/CN=HSM Domain 0"
openssl req -newkey rsa:2048 -nodes -keyout cert_1.key -x509 -days 365 -out cert_1.cer -subj "/CN=HSM Domain 1"
openssl req -newkey rsa:2048 -nodes -keyout cert_2.key -x509 -days 365 -out cert_2.cer -subj "/CN=HSM Domain 2"

az keyvault security-domain download \
--hsm-name my-managed-hsm \
--sd-wrapping-keys ./cert_0.cer ./cert_1.cer ./cert_2.cer \
--sd-quorum 2 \
--security-domain-file security-domain.json
warning

Store the security domain file and RSA private keys in a secure location. They are required to recover the HSM in a disaster scenario. The security domain download can only be performed once during initial activation.

Step 2 — Create an AES-256 symmetric key

Create an AES-256 key in the Managed HSM for key wrapping. The key must be a symmetric oct type with encrypt and decrypt operations enabled:

az keyvault key create \
--hsm-name my-managed-hsm \
--name defakto-wrapping-key \
--ops encrypt decrypt \
--kty oct \
--size 256

Step 3 — Set up permissions

Assign the Managed HSM Crypto User role to the Trust Domain Server's identity on the Managed HSM. This role permits encrypt and decrypt operations:

az keyvault role assignment create \
--assignee-object-id <service-principal-object-id> \
--assignee-principal-type ServicePrincipal \
--hsm-name my-managed-hsm \
--role "Managed HSM Crypto User" \
--scope "/"

For AKS deployments, use Workload Identity so that credentials rotate automatically rather than using a static client secret.

Step 4 — Update Helm values

Set the Key Vault URL and key name in your spirl-system Helm values. The URL must point to the Managed HSM (.managedhsm.azure.net), not a standard vault:

azure:
keyVault:
url: "https://my-managed-hsm.managedhsm.azure.net/"
keyName: "defakto-wrapping-key"

Optionally pin a specific key version:

azure:
keyVault:
url: "https://my-managed-hsm.managedhsm.azure.net/"
keyName: "defakto-wrapping-key"
keyVersion: "a1b2c3d4e5f6"

If keyVersion is omitted, the latest version of the key is used.

Apply the Helm release:

helm upgrade spirl-system spirl/spirl-system \
-f values.yaml \
--namespace <namespace>

Step 5 — Verify

On successful startup, the Trust Domain Server logs the following:

Key wrapping via Azure Key Vault keyVaultURL=https://my-managed-hsm.managedhsm.azure.net/ keyName=defakto-wrapping-key

The server also performs a test encryption during initialization to confirm it can access the key and that the key supports AES-256-GCM. If this test fails, startup is aborted with an error describing the issue.

Helm Values Reference

ValueRequiredDefaultDescription
azure.keyVault.urlYes""URL of the Azure Managed HSM (e.g., https://<hsm-name>.managedhsm.azure.net/). Must use the https scheme.
azure.keyVault.keyNameYes""Name of the AES-256 symmetric key in the Managed HSM.
azure.keyVault.keyVersionNoLatest versionSpecific key version to use. If omitted, the most recent version is used.

When to configure

Key wrapping must be configured before the Trust Domain Server stores any signing key material. Configure it as part of your initial Helm installation.

Switching key wrapping providers on an existing deployment is not supported. Data the Trust Domain Server has already persisted is encrypted with the current KEK, and the server cannot decrypt it with a different provider's key. If you need to change providers, contact Defakto support for guidance on your specific deployment.

Security Considerations

  • Managed HSM required. Only Managed HSM vaults are supported for key wrapping.
  • AES-256-GCM. All encryption uses the A256GCM algorithm. The key must support this algorithm or initialization fails.
  • Key Vault availability. The Trust Domain Server calls Key Vault at startup and during key rotation. In steady state, SVID issuance does not require Key Vault calls; the decrypted signing key is held in server memory.
  • Workload Identity. Use Azure Workload Identity rather than static client secrets so that credentials rotate automatically.
  • Key version pinning. Pinning a key version prevents automatic use of a newer version if the key is rotated in Key Vault. If you pin a version, update the Helm value when you rotate the key in Key Vault.