kubeseal Sealed Secrets CLI

Version 0.41 · source

Start here

kubeseal --fetch-cert > pub.pem
Get the public cert
kubeseal -f secret.yaml -w sealed.yaml
Seal a Secret
kubectl apply -f sealed.yaml
Deploy it
kubeseal --cert pub.pem < s.yaml
Seal offline
kubeseal --scope cluster-wide
Loosen the binding
kubeseal --validate < sealed.yaml
Will it decrypt?
kubeseal --re-encrypt < sealed.yaml
Use the newest key
kubeseal --merge-into sealed.yaml
Add a key

Concepts

  1. Secret plain, local only
  2. SealedSecret encrypted, in Git
  3. Controller holds private key
  4. Secret in the cluster

Seal

kubeseal -f <secret> -w <sealed>
Seal a Secret file
Without -f it reads stdin, without -w it writes stdout.
kubeseal < <secret> > <sealed>
Seal via stdin and stdout
kubectl create secret generic <name> --dry-run=client --from-literal=<k>=<v> -o json | kubeseal > <sealed>
Create and seal in one pipe
kubeseal -o yaml < <secret>
Output YAML instead of JSON
kubeseal --namespace <ns> < <secret>
Seal for a namespace
Used when the Secret has no namespace of its own.
kubectl apply -f <sealed>
Deploy the SealedSecret
kubectl get sealedsecret
List SealedSecrets
kubectl get secret <name>
Check the controller made the Secret

Certificate

kubeseal --fetch-cert > <pub.pem>
Download the controller's public cert
kubeseal --cert <pub.pem> < <secret>
Seal offline with a saved cert
kubeseal --cert <https-url> < <secret>
Seal with a cert from a URL
export SEALED_SECRETS_CERT=<pub.pem>
Set the default cert

Controller

kubeseal --controller-name <name>
Name of the controller service
The Helm chart names it sealed-secrets, kubeseal expects sealed-secrets-controller.
kubeseal --controller-namespace <ns>
Namespace of the controller
Default is kube-system.
kubeseal --version
Show kubeseal version

Scopes

kubeseal --scope strict
Bind name and namespace (default)
kubeseal --scope namespace-wide
Allow renaming inside the namespace
kubeseal --scope cluster-wide
Allow any name and namespace
Scope annotations
Annotation on the Secret Effect
sealedsecrets.bitnami.com/namespace-wide: "true" Namespace-wide scope
sealedsecrets.bitnami.com/cluster-wide: "true" Cluster-wide scope, wins over the other

Maintain

kubeseal --validate < <sealed>
Check the controller can decrypt it
kubeseal --re-encrypt < <sealed> > <new>
Re-encrypt with the newest key
Does not update the object in the cluster: apply the result.
kubeseal --merge-into <sealed> < <secret>
Add values to an existing SealedSecret
kubeseal --recovery-unseal --recovery-private-key <k1>,<k2> < <sealed>
Decrypt offline with backed-up keys
kubectl get secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key -o yaml > <main.key>
Back up the sealing keys
Store the file safely: it can decrypt everything.
kubectl apply -f <main.key>
Restore keys, then restart the controller pod

Raw mode

echo -n <value> | kubeseal --raw --name <n> --namespace <ns>
Encrypt one value (strict)
Experimental. Paste the output into encryptedData yourself.
echo -n <value> | kubeseal --raw --namespace <ns> --scope namespace-wide
Encrypt one value, namespace-wide
echo -n <value> | kubeseal --raw --scope cluster-wide
Encrypt one value, cluster-wide

Secret annotations

Controller behaviour
Annotation (sealedsecrets.bitnami.com/) Effect
managed: "true" Take over an existing Secret
patch: "true" Add keys, keep others (0.23+)
skip-set-owner-references: "true" Secret outlives its SealedSecret

Recipes

Seal a new secret
kubectl create secret generic db --dry-run=client \  --from-literal=password=<pw> -n app -o json \  | kubeseal > db-sealed.jsonkubectl apply -f db-sealed.json
Seal in CI without cluster access
# once, with cluster accesskubeseal --fetch-cert > pub.pem# later, anywherekubeseal --cert pub.pem -f secret.yaml -w sealed.yaml
Add a value to a sealed secret
echo -n <new> | kubectl create secret generic db \  --dry-run=client --from-file=token=/dev/stdin -o json \  | kubeseal --merge-into db-sealed.json
Rotate to the latest key
kubeseal --re-encrypt < db-sealed.json > tmp.json \  && mv tmp.json db-sealed.jsonkubectl apply -f db-sealed.json