Sealed Secrets

Encrypt your Secret using the custom resource definition SealedSecret manifest kind, which is safe to store - even to a public repository or a deployment pipeline.

The SealedSecret can be decrypted only by the h8lio cluster and nobody else (not even the original author) is able to obtain the original Secret from the SealedSecret.

This feature is in early access (alpha). Let us know your feedback



  • A cluster (Kubernetes namespace) in which you want to create a sealed secrets (my-cluster in this documentation)
  • kubectl configured on the above cluster


We need to install the kubeseal client to be able to generate the SealedSecret.

Refers to the documentation for the installation options

On Linux AMD 64bit architecture (check for the latest release):

wget -qO-$KSV/kubeseal-$KSV-linux-amd64.tar.gz | tar xzvf -
chmod 755 kubeseal
mv kubeseal /usr/local/bin
kubeseal --help


In this following example, we are going to create a portable SealedSecret to be used as a MySQL password.

  1. Creates a password.txt file including our secrets as key-value pairs:
echo "MYSQL_PASSWORD=test_password" > password.txt


  1. Generates the Secret named my-secret in my-cluster from our password.txt and sealed it with the kubeseal client to a my-secret.yaml file:
kubectl create secret generic my-secret -n my-cluster --from-file=password.txt --dry-run=client -o yaml \
 | kubeseal -o yaml --cert > my-secret.yaml

Pay attention to the kubeseal argument --cert which points to the public certificate used to seal the secret (see the documentation).

To generate a certificate Secret replace the --from-file argument value password.txt by a .crt file.


kind: SealedSecret
  creationTimestamp: null
  name: my-secret
  namespace: my-cluster
    password.txt: AgCw0lzghJuO94okBA/zWSH+aBl4mVrdpIk+cm8Q8yXkqFvUIBgQLr5rQBs7neZZyDH8yR/mp71H62xXSELGtv7WQXNk7J6lt1sqp7+zFFgpbXVnDFFCgXGreMuMUt34RJaP1bsZ0u6xXsHZywqcrWVfWdW8Ik/kCJh00bkRRYD1fSvmw537WQ0Af2XVlIJlRE+zjgbk99MiRXTDu0N9CRb3ZAXEAnpT8y7nH7ECv3o78wuo46QATuB1YvAk5EDfgdq62BvEgDgWbcVGHX67gXZJ2W3rcRqydwspo9R+H0w2wCrbzWsD8d5I2NNnZ8YyHh94tP1DeAtaDVj9KjA4F8qb8egq3w97WSpXStM8QH7+J/t/FB2rGxAOqygugmvZHnOVkVlrAQBCpkQy1AMXwQ665ixCs4iFtFZgwf4JJyCaAVUBO8Q3EyxVTkfb2NOqvVXfkJeMSWGXuhcAebtJ3r+P94U2XzVaOCmZuYDOfuen5hQOmXRJQJnLD0TqYYL/o6KJHFbKCtjJr1zIsp8y/f/MnIz5oVuNxHt77ALzP+Z+2rHrvBQGcqSgxlPlyKpARm0j197M8fuYzL+D1OZdJCBizglBgzbtk7oXQvNaoYWPm1KmpIuZklBWK12Bs9LuWoFq6h2wcZ/0f1I4AJna04dEcE0v5nYKv4P0gtKfEbyZKNe1g9o/UEW18uzCOjx/3Kh68ORBVzpXiGDNEZASC5pE/xYlpd8+lsKdygUkmfM=
    data: null
      creationTimestamp: null
      name: my-secret
      namespace: my-cluster

Note: it is not possible to deploy the generated SealedSecret manifest my-secret.yaml to another cluster than the one specified at its creation time

  1. Apply the SealedSecret manifest to your cluster:
kubectl apply -f my-secret.yaml
  1. Check the SealedSecret has been correctly deployed:
kubectl -n my-cluster get
NAME                  AGE
my-secret             1m
kubectl -n my-cluster describe my-secret

Checks the events and status from the above command output result.

  1. Check if the unsealed Secret has successfully been created:
kubectl -n my-cluster get secrets


NAME                  AGE
my-secret             1m
  1. Use the my-secret Secret within pods (or template) as same as a directly generated secrets…