Kubernetes Curriculum
On this page
- Secrets Encryption At Rest
- 1. Architectural Concept & Deep Dive
- 2. Encryption Providers Comparison
- 3. Envelope Encryption via KMS v2 Plugin
- KMS v2 Configuration Manifest (encryption-config-kms.yaml)
- 4. Step-by-Step Implementation Lab
- Step 1: Create Static Encryption Key Configuration (Local Provider)
- Step 2: Enable Provider in kube-apiserver.yaml
- Step 3: Re-encrypt Pre-existing Secrets
- 5. Verification & Key Rotation Strategy
- 1. Verify Encryption in etcd Directly
- 2. Zero-Downtime Key Rotation
- 6. Key Takeaways
Secrets Encryption At Rest
1. Architectural Concept & Deep Dive
A fundamental reality of native Kubernetes Secrets:
Kubernetes Secrets are NOT encrypted by default. They are merely Base64-encoded strings.
Base64 is an encoding format, not an encryption mechanism. Anyone with read access to the etcd database, access to backup snapshots, or permission to execute kubectl get secret -o yaml can decode credentials instantly (echo "cGFzc3dvcmQ=" | base64 -d).
To protect credentials against physical disk theft, unprivileged etcd access, and cloud snapshot exfiltration, the Kubernetes control plane provides Encryption at Rest via the EncryptionConfiguration API.
2. Encryption Providers Comparison
Kubernetes supports multiple cryptographic providers in its evaluation chain:
3. Envelope Encryption via KMS v2 Plugin
In the KMS v2 Envelope Encryption model:
- Key Encryption Key (KEK): Stored and managed securely inside an external Hardware Security Module (HSM) such as AWS KMS.
- Data Encryption Key (DEK): A dynamic, ephemeral AES-GCM key generated locally by the API server.
- The API server encrypts the Secret with the DEK, asks AWS KMS to encrypt the DEK with the KEK, and stores the encrypted DEK alongside the encrypted secret payload in etcd.
KMS v2 Configuration Manifest (encryption-config-kms.yaml)
4. Step-by-Step Implementation Lab
Step 1: Create Static Encryption Key Configuration (Local Provider)
If an external KMS is unavailable, deploy a hardened aescbc provider:
Step 2: Enable Provider in kube-apiserver.yaml
Add the --encryption-provider-config argument and host volume mounts to /etc/kubernetes/manifests/kube-apiserver.yaml:
Step 3: Re-encrypt Pre-existing Secrets
Newly created secrets will be encrypted automatically. To encrypt all historical secrets already in etcd:
5. Verification & Key Rotation Strategy
1. Verify Encryption in etcd Directly
- The output should start with the header
k8s:enc:aescbc:v1:key1:. - Plaintext strings must not appear anywhere in the output!
2. Zero-Downtime Key Rotation
To rotate encryption keys without outage:
- Generate a new key (
key2) and prepend it as the first entry in thekeyslist. - Keep the old key (
key1) as the second entry so existing secrets can still be decrypted. - Restart the API server.
- Run
kubectl get secrets --all-namespaces -o json | kubectl replace -f -to re-encrypt all secrets withkey2. - Remove
key1from the configuration file and restart the API server.
6. Key Takeaways
- Kubernetes Secrets are not encrypted by default; they are merely Base64-encoded.
EncryptionConfigurationenables transparent, cryptographic encryption at rest before data reaches etcd.- KMS v2 envelope encryption is the industry best practice, eliminating static keys on master disks.
- After enabling encryption, you must trigger an in-place replace (
kubectl replace) to encrypt pre-existing secrets.