Sealed Secrets provide a secure way to encrypt the Kubernetes secrets. This resource can be stored in public repository and used in devops automation maintaining confidentiality of the secured information. We implement the sealed secret controller in the Kubernetes cluster to manage SealedSecret. SealedSecret can be decrypted to secret object in the target namespace and used as per Kubernetes behaviour.
Sealed Secrets is an open source project maintained by bitnami-labs.
Setup Sealed Secrets
To configure Sealed Secrets for use, we need to setup in following way :
CLI for client VM
The kubeseal client is available on homebrew: $ brew install kubeseal
The kubeseal utility uses asymmetric crypto to encrypt secrets that only the controller can decrypt. These encrypted secrets are encoded in a SealedSecret resource, which you can see as a recipe for creating a secret. It is expected to install Sealed Secret Controller with name as "sealed-secrets-controller" in Kube-system namespace by default. If we install the controller with different name then provide the name with --controller-name
and for different namespace, need to provide the --controller-namespace
in the kubeseal command.
An example for SealedSecret usage :
kubeseal uses the cert as configured with the controller during the encryption process. If we are using kubeseal where cluster is unreachable, then we can pull the cert with kubeseal --fetch-cert
command and then pass the certificate with --cert
option to create the sealedSecret resource.
The above created “mysecret-sealed.yaml” can be safely shared across networks and in public/private archives and repo. Since it’s encrypted and require the private key ( placed only with controller) thus can’t be decoded externally. When we create the SealedSecret resource in the cluster, the controller recognises the resource and create the normal unencrypted secret in the namespace using the private/public key pairs maintained as kubernetes secrets at controller.
Controller for cluster
The Sealed Secrets helm chart is now official supported and hosted in this GitHub repo.
The controller generates its own self-signed certificates when is deployed for the first time and manages the renewal lifecycle of the certificates.
There is a minor bug in controller service for the helm version 1.17.1 To workaround, we need to remove the “name: http” for the Kubernetes service created to expose the controller.
We can provide own certificates, which can be created in the kube-system namespace (or same namespace wherever controller is deployed) with secret type as “kubernetes.io/tls
” labeled with sealedsecrets.bitnami.com/sealed-secrets-key=active
.
The sealed-secrets-controller can be further configured with various options to add or change features to the controller.
Sealed key renewal
Auto configuration
Sealed key renewal is configured to 30d by default. This value can be changed with the controller option "--key-renew-period
".
Manual process
There might be a need to rotate the private/public key pair attached to controller earlier then it’s expiry period. This might be need for any suspicion for compromised key or any other use case. Theprivate/public key pair can be generated early by passing current timestamp to the controller into a flag --key-cutoff-time
or with an environment variable called SEALED_SECRETS_KEY_CUTOFF_TIME
. Expected date format is RFC1123, which can be generated with the date -R
command.
With the above helm upgrade, the new secret would be created with a set ofprivate/public key pairs and get attached to the controller. It would be applicable for any new SealedSecret operation within the cluster.
If a sealing key has been leaked out of the cluster, we must consider all our SealedSecret resources encrypted with that key and stored in public repository as compromised. No amount of sealing key rotation in the cluster or even re-encryption of existing SealedSecrets files can change that. The best practice would be to periodically rotate all the actual secrets and create new SealedSecret resource with those new secrets. Also renew the sealed secret key if suspect of any compromise.
Backup and recovery
To prepare for any cluster operation tasks, we can create a backup of the secret attached to the controller which holds the cert and the key. The key is used for decrypt operation for sealed secrets into secrets.
kubectl get secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key -o yaml > backup-sealedSecret.key
In order to attach this secret to the controller, we can create the secret in the namespace and delete the controller pod to let the pod get recreated and cache the provisioned secret with the backup keys.
Also, there might be a need ( usually it’s not recommended) to recover the secret from the sealed secret privately in secured environment for review or any other legitimate use case. For that, we can use the backed up keys from the controller to use during the recovery process.
Usage of SealedSecret
In the below example, we would deploy MYSQL DB application in the Kubernetes Cluster. The DB needs to be configured with the root password, passed by the environment variable – MYSQL_ROOT_PASSWORD to the deployment resource. We would create a sealedSecret resource for the root password, which would generate the secret resource in the defined namespace. Once MYSQLDB would be deployed, it would refer to the secret resource and fetch the root password to configure the DB application.
Create Namespace for the app deployment
Create secret for root password and push to kubeseal tool to create sealedSecret
Verify the sealedSecret, to see that the name and namespace match to the secret which follows the default “strict” scope. We can refer here, for further details on other scopes – namespace-wide and cluster-wide.
Create SealedSecret resource in cluster and verify that the sealed secret and secret both gets created in the database-ns.
Create the MYSQL DB in the database-ns namespace.
Verify that the mysql db is configured and able to launch with the defined root password.
Wrapping Up
With the above implementation, we can conclude that SealedSecret adds an encryption to secure data for archival purpose, and can be used to deploy secrets in cluster. For the applications in cluster, it still uses the secret object generated by the underlying sealed secrets.
Thus, with this innovative approach, we get more secure way to store and use secrets for public repository and devops automation purpose.