Encryption at rest with Kustomizer and Age
Kustomizer has builtin support for encrypting and decrypting Kubernetes configuration (packaged as OCI artifacts) using Actually Good Encryption (age) asymmetric keys. Age is a modern and secure encryption tool with small explicit keys that is a viable alternative to PGP.
This guide shows you how to securely distribute sensitive Kubernetes configuration to trusted consumers. When publishing OCI artifacts to a container registry, you can opt to encrypt the artifacts content using your consumers public keys.
Before you begin
- Install the Kustomizer CLI by the following instructions in the Installation guide.
- Install the age key generator CLI e.g.
brew install age
.
Key management
Assuming you want to publish sensitive Kubernetes configuration that can be accessed only by a set of trusted users, first you'll need to acquire their public keys.
Generate key pairs
Generate a X25519 key pair using age keygen CLI:
age-keygen -o id_age
Extract the public key to a separate file:
age-keygen -y id_age > id_age.pub
Create the recipients file
Collect the public keys from your users and save them in a file (one key per line):
touch recipients.txt
cat user1/id_age.pub >> recipients.txt
cat user2/id_age.pub >> recipients.txt
For testing purposes, add your own public key to the recipients file:
cat id_age.pub >> recipients.txt
Publish encrypted artifacts
To encrypt Kubernetes configuration with your users' public keys, you can point Kustomizer at the recipients file when pushing artifacts to a container registry:
kustomizer push artifact oci://ghcr.io/my-org/my-app:1.0.0 \
-k ./examples/demo-app \
--age-recipients ./recipients.txt
Now if you try to inspect the artifact, Kustomizer will fail to access the artifact content:
$ kustomizer inspect artifact oci://ghcr.io/my-org/my-app:1.0.0
✗ pulling ghcr.io/my-org/my-app:1.0.0 failed: encrypted artifact, you need to supply a private key for decryption
Consume encrypted artifacts
To make use of encrypted artifacts, you'll need to point Kustomizer to a local file with one or more private keys (age identities).
To inspect an artifact encrypted with your public key:
$ kustomizer inspect artifact oci://ghcr.io/my-org/my-app:1.0.0 \
--age-identities ./id_age
Artifact: oci://ghcr.io/my-org/my-app@sha256:1801d42d5459e81119dad543a7f1080ed2aadc92dcbb7c9dabf282692d6bf29d
BuiltBy: kustomizer/v2.0.0
CreatedAt: 2021-12-29T08:35:40Z
EncryptedWith: age-encryption.org/v1
Checksum: 5b8c45af6951e977581122b7848b490f25b43ffd44ed7a82fd574eff6aac06be
Resources:
- Namespace/kustomizer-demo-app
- ConfigMap/kustomizer-demo-app/redis-config-bd2fcfgt6k
- Service/kustomizer-demo-app/backend
- Service/kustomizer-demo-app/cache
- Service/kustomizer-demo-app/frontend
- Deployment/kustomizer-demo-app/backend
- ghcr.io/stefanprodan/podinfo:6.0.0
- Deployment/kustomizer-demo-app/cache
- public.ecr.aws/docker/library/redis:6.2.0
- Deployment/kustomizer-demo-app/frontend
- ghcr.io/stefanprodan/podinfo:6.0.0
- HorizontalPodAutoscaler/kustomizer-demo-app/backend
- HorizontalPodAutoscaler/kustomizer-demo-app/frontend
All Kustomizer commands that pull artifacts from container registries expose the
--age-identities
flag, e.g.:
kustomizer apply inventory sensitive-app --wait --prune \
--artifact oci://ghcr.io/my-org/app-frontend:1.0.0 \
--artifact oci://ghcr.io/my-org/app-backend:1.0.0 \
--age-identities ./id_age