Skip to content

Commit 82e995f

Browse files
committed
docs: add KMS encryption documentation for self-managed Azure
- Add Key Vault Crypto User role assignment instructions for KMS identity in self-managed Azure cluster creation guide - Add KMS role assignment warning callout in workload identity setup guide - Update aggregated docs and API reference with KMS workload identity fields Signed-off-by: Bryan Cox <brcox@redhat.com> Commit-Message-Assisted-by: Claude (via Claude Code)
1 parent 1778fe9 commit 82e995f

4 files changed

Lines changed: 284 additions & 1 deletion

File tree

docs/content/how-to/azure/azure-workload-identity-setup.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,23 @@ This creates 7 managed identities with federated credentials for:
6262
- NodePool Management
6363
- Network Operator
6464

65+
To also create a KMS identity for Azure Key Vault etcd encryption at rest, add the `--enable-kms` flag:
66+
67+
```bash
68+
hypershift create iam azure \
69+
--name $CLUSTER_NAME \
70+
--infra-id $INFRA_ID \
71+
--azure-creds $AZURE_CREDS \
72+
--resource-group-name $PERSISTENT_RG_NAME \
73+
--oidc-issuer-url $OIDC_ISSUER_URL \
74+
--output-file workload-identities.json \
75+
--enable-kms
76+
```
77+
78+
!!! warning "KMS Key Vault Role Assignment"
79+
80+
If you use `--enable-kms`, you must **manually** assign the `Key Vault Crypto User` role to the KMS identity on your Key Vault. The `--auto-assign-roles` flag does not cover this because the Key Vault scope is user-provided. See [Enabling KMS Encryption](create-self-managed-azure-cluster.md#enabling-kms-encryption-etcd-encryption-at-rest) for the role assignment commands.
81+
6582
For complete documentation on the IAM commands, see [Create Azure IAM Resources Separately](create-iam-separately.md).
6683

6784
## Configure OIDC Issuer

docs/content/how-to/azure/create-self-managed-azure-cluster.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,133 @@ ${HYPERSHIFT_BINARY_PATH}/hypershift create nodepool azure \
267267
- `--diagnostics-storage-account-type Managed`: Use Azure managed storage for diagnostics
268268
- `--control-plane-operator-image`: Custom HyperShift operator image (optional)
269269

270+
## Enabling KMS Encryption (etcd Encryption at Rest)
271+
272+
Self-managed Azure HostedClusters support encrypting etcd data at rest using [Azure Key Vault](https://learn.microsoft.com/en-us/azure/key-vault/general/overview) with the KMSv2 protocol. This requires:
273+
274+
1. An Azure Key Vault with a cryptographic key
275+
2. A workload identity with `Key Vault Crypto User` role on the Key Vault
276+
277+
### Prerequisites
278+
279+
Ensure the `kms` workload identity is included in your `workload-identities.json` file. When using `hypershift create iam azure`, pass the `--enable-kms` flag to create the KMS identity:
280+
281+
```bash
282+
hypershift create iam azure \
283+
--name "$CLUSTER_NAME" \
284+
--infra-id "$INFRA_ID" \
285+
--azure-creds "$AZURE_CREDS" \
286+
--resource-group-name "$PERSISTENT_RG_NAME" \
287+
--oidc-issuer-url "$OIDC_ISSUER_URL" \
288+
--output-file ./workload-identities.json \
289+
--enable-kms
290+
```
291+
292+
### Create a Key Vault and Key
293+
294+
!!! note "RBAC Key Vault Permissions"
295+
296+
The Key Vault is created with `--enable-rbac-authorization`, which means the creator does **not** automatically get data plane access. You must have the `Key Vault Crypto Officer` role (or equivalent) on the Key Vault to create and manage keys. If the key creation step fails with a `Forbidden` error, assign yourself the role:
297+
298+
```bash
299+
MY_OBJECT_ID=$(az ad signed-in-user show --query id -o tsv)
300+
KV_ID=$(az keyvault show --name "${KV_NAME}" --query id -o tsv)
301+
az role assignment create \
302+
--assignee-object-id "${MY_OBJECT_ID}" \
303+
--assignee-principal-type User \
304+
--role "Key Vault Crypto Officer" \
305+
--scope "${KV_ID}"
306+
```
307+
308+
```bash
309+
# Create Key Vault
310+
KV_NAME="${PREFIX}-kv"
311+
az keyvault create \
312+
--name "${KV_NAME}" \
313+
--resource-group "${MANAGED_RG_NAME}" \
314+
--location "${LOCATION}" \
315+
--enable-rbac-authorization
316+
317+
# Create encryption key
318+
KEY_NAME="${PREFIX}-etcd-key"
319+
az keyvault key create \
320+
--vault-name "${KV_NAME}" \
321+
--name "${KEY_NAME}" \
322+
--kty RSA \
323+
--size 2048
324+
325+
# Get the key ID (used as --encryption-key-id)
326+
ENCRYPTION_KEY_ID=$(az keyvault key show \
327+
--vault-name "${KV_NAME}" \
328+
--name "${KEY_NAME}" \
329+
--query key.kid -o tsv)
330+
```
331+
332+
### Assign Key Vault Crypto User Role to the KMS Identity
333+
334+
!!! warning "Manual Step Required"
335+
336+
The `--auto-assign-roles` / `--assign-service-principal-roles` flag does **not** assign the Key Vault role because the Key Vault scope is user-provided and not known to the CLI at role-assignment time. You must perform this role assignment manually.
337+
338+
Grant the KMS workload identity the `Key Vault Crypto User` role on your Key Vault so it can encrypt and decrypt etcd data:
339+
340+
```bash
341+
# Get the principal ID of the KMS managed identity
342+
# The identity name follows the pattern: {clusterName}-kms-{infraID}
343+
# List identities in the resource group to find the exact name:
344+
# az identity list --resource-group "${PERSISTENT_RG_NAME}" --query "[?contains(name, 'kms')]" -o table
345+
KMS_MI_NAME=$(az identity list \
346+
--resource-group "${PERSISTENT_RG_NAME}" \
347+
--query "[?contains(name, '${CLUSTER_NAME}-kms')].name" -o tsv)
348+
KMS_PRINCIPAL_ID=$(az identity show \
349+
--name "${KMS_MI_NAME}" \
350+
--resource-group "${PERSISTENT_RG_NAME}" \
351+
--query principalId -o tsv)
352+
353+
# Get the Key Vault resource ID
354+
KV_ID=$(az keyvault show --name "${KV_NAME}" --query id -o tsv)
355+
356+
# Assign Key Vault Crypto User role to the KMS identity
357+
az role assignment create \
358+
--assignee-object-id "${KMS_PRINCIPAL_ID}" \
359+
--assignee-principal-type ServicePrincipal \
360+
--role "Key Vault Crypto User" \
361+
--scope "${KV_ID}"
362+
```
363+
364+
### Create the Cluster with KMS
365+
366+
Add the `--encryption-key-id` flag to your cluster creation command:
367+
368+
```bash
369+
${HYPERSHIFT_BINARY_PATH}/hypershift create cluster azure \
370+
--name "$CLUSTER_NAME" \
371+
--namespace "$CLUSTER_NAMESPACE" \
372+
--azure-creds $AZURE_CREDS \
373+
--location ${LOCATION} \
374+
--node-pool-replicas 2 \
375+
--base-domain $PARENT_DNS_ZONE \
376+
--pull-secret $PULL_SECRET \
377+
--generate-ssh \
378+
--release-image ${RELEASE_IMAGE} \
379+
--external-dns-domain ${DNS_ZONE_NAME} \
380+
--resource-group-name "${MANAGED_RG_NAME}" \
381+
--vnet-id "${GetVnetID}" \
382+
--subnet-id "${GetSubnetID}" \
383+
--network-security-group-id "${GetNsgID}" \
384+
--sa-token-issuer-private-key-path "${SA_TOKEN_ISSUER_PRIVATE_KEY_PATH}" \
385+
--oidc-issuer-url "${OIDC_ISSUER_URL}" \
386+
--dns-zone-rg-name ${PERSISTENT_RG_NAME} \
387+
--assign-service-principal-roles \
388+
--workload-identities-file ./workload-identities.json \
389+
--encryption-key-id "${ENCRYPTION_KEY_ID}" \
390+
--diagnostics-storage-account-type Managed
391+
```
392+
393+
!!! note "KMS Authentication"
394+
395+
For self-managed Azure, the KMS provider authenticates using the `kms` workload identity specified in your `workload-identities.json`. This is different from managed Azure (ARO HCP), which uses managed identities with CSI secret store volumes. The `--kms-credentials-secret-name` flag is not needed for self-managed clusters.
396+
270397
## Verification
271398

272399
Check the cluster status and access:

docs/content/reference/aggregated-docs.md

Lines changed: 124 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/content/reference/api.md

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)