Kubernetes Encryption Config
This page covers the EncryptionConfiguration shape that the Kubernetes API server consumes, the API server flag wiring, and the initial migration of existing resources to KMS-encrypted storage. It assumes Install
is complete and bao-kms-provider doctor reports green on every control-plane node.
Prerequisites
- The provider is running on every control-plane node and exposes its Unix socket at the path documented in the provider configuration file.
bao-kms-provider doctorsucceeds with the active configuration.- The Kubernetes API server has read access to its
EncryptionConfigurationfile, and the runtime user can connect to the provider socket through theopenbao-kms-socketgroup (see Deployment: Linux Identity Model ).
Write The EncryptionConfiguration
The minimal EncryptionConfiguration for a fresh enablement keeps the identity provider as a fallback so existing plaintext data remains readable during migration:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- kms:
apiVersion: v2
name: openbao-kms-workload-a
endpoint: unix:///run/openbao-kms/kms.sock
timeout: 3s
- identity: {}
A maintained sample lives at deploy/kubernetes/encryption-config.yaml in the repository.
Required values:
| Field | Constraint |
|---|---|
providers[].kms.apiVersion | Always v2. KMS v1 is not implemented. |
name | Identity-bearing. Must match transit.keyIdScope.providerName in the provider configuration. Do not change after encryption begins. |
endpoint | Must use the unix:// scheme and match server.socketPath in the provider configuration. |
timeout | Start with 3s. Tightening this value should follow benchmark and failure-mode testing; see Reference: EncryptionConfiguration
. |
resources | Start narrow (secrets). Common second step is to add configmaps. |
CRDs can be encrypted with the same provider. Plan resource selection deliberately; size, read/write volume, and recovery impact all change as the encrypted set grows.
Configure The Kubernetes API Server
Place the file on every control-plane node, then point kube-apiserver at it:
--encryption-provider-config=/etc/kubernetes/encryption-config.yaml
To enable in-place reload of the file when its contents change without restarting the API server, also set:
--encryption-provider-config-automatic-reload=true
Reload is convenient, though the API server still depends on the provider being healthy at the moment a configuration change takes effect. A reload that introduces a misspelled provider name or an unreachable socket will surface as KMS Status failures and ultimately as encrypt or decrypt errors. Treat reload as a faster restart. The API server applies the new configuration immediately and surfaces errors at the next encrypt or decrypt call rather than during validation.
Restart Or Reload The API Server
If --encryption-provider-config-automatic-reload=true is set, the API server picks up changes to the configuration file in place. Otherwise, restart kube-apiserver once on each control-plane node.
After the API server has the new configuration:
Confirm the API server log records that the KMS provider is healthy.
Confirm
kubectl get nodessucceeds.Confirm a probe Secret can be created and read back:
kubectl create secret generic openbao-kms-bootstrap-probe \ --from-literal=value='probe' kubectl get secret openbao-kms-bootstrap-probe \ -o jsonpath='{.data.value}' | base64 -d
End-to-end encryption verification (etcd inspection, key_id stability, AAD shape) belongs to the next page; see First Encrypt .
Migrate Existing Resources
Kubernetes encryption applies on write. Existing objects are not rewritten when the configuration changes. The first time the provider is enabled on an existing cluster, every targeted resource must be rewritten so its etcd payload is replaced with KMS-encrypted ciphertext.
For Secrets:
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
Run an equivalent rewrite for every resource type in the resources list. The exact command differs per resource; the pattern is kubectl get <resource> --all-namespaces -o json | kubectl replace -f -.
After rewriting:
- Restart
kube-apiserveron one control-plane node and confirm reads still succeed. - Repeat across the remaining control-plane nodes.
- Verify a sample of objects in etcd to confirm payloads no longer contain plaintext. The First Encrypt page describes the etcd inspection technique.
Remove The Identity Fallback
Once every targeted resource has been rewritten and verified, remove the identity provider from the configuration:
providers:
- kms:
apiVersion: v2
name: openbao-kms-workload-a
endpoint: unix:///run/openbao-kms/kms.sock
timeout: 3s
Reload or restart the API server. After this point, any object targeted by the configuration that has not been rewritten will fail to decrypt.
Do not remove the fallback before the migration verification on the previous step has completed. Removing it too early breaks reads of plaintext objects that were not migrated.
Read Next
- First Encrypt for the end-to-end smoke test.
- Operations: Rotation once encryption is live and the cluster is in steady state.