Sealed Secrets¶
GitOps means your cluster's desired state lives in Git, but you cannot
commit plain Kubernetes Secret objects there; they are only
base64-encoded, not encrypted. We recommend
Sealed Secrets for this. It
encrypts a secret so it can be safely committed to a Git repository, and
only your cluster can decrypt it.
How it works¶
A controller in your cluster holds a private key. You encrypt secrets
against the matching public key using the kubeseal CLI, producing a
SealedSecret resource. ArgoCD applies the SealedSecret like any other
manifest, and the controller decrypts it in-cluster into a regular
Secret that your pods consume. The plaintext never leaves your machine
in a form anyone but your cluster can read.
Workflow¶
Write a normal Secret manifest (do not commit this file), then seal it:
# Create a Secret manifest locally (not committed)
kubectl create secret generic db-credentials \
--namespace my-app \
--from-literal=password='s3cr3t' \
--dry-run=client -o yaml > secret.yaml
# Seal it against the cluster's public key
kubeseal --format yaml < secret.yaml > sealed-secret.yaml
Commit sealed-secret.yaml to your repository and let ArgoCD deploy it.
The resulting Secret appears in the my-app namespace for your pods to
mount or reference as environment variables.
kubeseal fetches the public key from the controller in your cluster
using your kubeconfig. If you run it offline, fetch the certificate once
with kubeseal --fetch-cert and pass it with --cert.
A SealedSecret is encrypted for a specific namespace and name by
default, so move or rename it only by re-sealing.