Sealed Secrets#
The SealedSecrets controller solves the problem of storing Kubernetes secret data securely by encrypting the configurations. It can only be decrypted by sealed secret controller running in cluster.
Architecture#
SealedSecrets is composed of two Kubernetes components:
Controller: A cluster-side component for data decryption.Kubeseal: A client-side utility for data encryption. It uses asymmetric cryptography methods for data encryption and kubeconfig to communicate with the cluster.
Pre-Requisites#
You need to have kubeseal installed on your local machine. You can get the latest release from Sealed Secret Releases.
Usage#
Create K8s sealed secret#
Lets create a sample k8s secret that will be used for MySQL:
-
Create the secret as a normal Kubernetes secret resource:
apiVersion: v1 kind: Secret metadata: name: mysql-secrets namespace: gabbar-dev data: # base64 encoded "root" USERNAME: cm9vdA== # base64 encoded "@mysqlpassword" USER_PASSWORD: QG15c3FscGFzc3dvcmQ= # base64 encoded "test-database" DATABASE: dGVzdC1kYXRhYmFzZQ== -
Save it in a file named
secret-mysql.yaml. This file should not be pushed to source control as it is easily de-codable. -
Install kubeseal and your kubeconfig should be pointing to your SAAP cluster
-
Sealed secrets controller is running in
stakater-sealed-secretsnamespace and sealed secrets service name issealed-secrets, so you need to run:kubeseal --controller-name=sealed-secrets --controller-namespace=stakater-sealed-secrets --format yaml < SECRET_FILEwhere:
SECRET_FILE: the name of the YAML file containing the k8s secretSEALED_SECRET: the name of the YAML file that will contain the sealed secret
-
Add and commit this sealed secret to source control
-
Remove the original secret
For Dynamic Test Environment#
To use secrets in dynamic test environments (for PR environment), you need to seal secret with cluster-wide scope so that it can be decrypted by any namespace. Since PR namespaces are dynamic and tied to the lifecycle of PR, cluster-wide scope make sure that it can be decrypted by dynamic namespaces.
To create a sealed secret in Dynamic Test Environments:
-
Generate a
SealedSecretresource:kubeseal --controller-name=sealed-secrets --controller-namespace=stakater-sealed-secrets --format yaml --scope cluster-wide < secret-mysql.yamlThis will generate sealedsecret resource output:
apiVersion: bitnami.com/v1alpha1 kind: SealedSecret metadata: annotations: sealedsecrets.bitnami.com/cluster-wide: "true" creationTimestamp: null name: mysql-secrets spec: encryptedData: DATABASE: AgBLmwvAw... USER_PASSWORD: AgCkxffaV... USERNAME: AgAkGib0a... template: metadata: annotations: sealedsecrets.bitnami.com/cluster-wide: "true" creationTimestamp: null name: mysql-secrets -
Add a
sealedSecretblock in the Helm values present indeploy/values.yamlin your application repository and copy/paste the key values from the resource:sealedSecret: enabled: true annotations: sealedsecrets.bitnami.com/cluster-wide: "true" files: - name: mysql-secrets encryptedData: DATABASE: AgBLmwvAw... USER_PASSWORD: AgCkxffaV... USERNAME: AgAkGib0a...
For Dev Environment#
To generate sealedsecrets for dev environment:
-
Run the following command:
kubeseal --controller-name=sealed-secrets --controller-namespace=stakater-sealed-secrets --format yaml < secret-mysql.yamlThis will generate sealedsecret resource output:
apiVersion: bitnami.com/v1alpha1 kind: SealedSecret metadata: creationTimestamp: null name: mysql-secrets namespace: gabbar-dev spec: encryptedData: DATABASE: AgBLmwvAw... USER_PASSWORD: AgCkxffaV... USERNAME: AgAkGib0a... template: metadata: creationTimestamp: null name: mysql-secrets namespace: gabbar-dev -
Add a
sealedSecretblock in the Helm values present in<tenant>/<application>/<env>/values.yamlin the GitOps-config repository and copy/paste key values from the generated output:sealedSecret: enabled: true annotations: "" files: - name: mysql-secrets encryptedData: DATABASE: AgBLmwvAw... USER_PASSWORD: AgCkxffaV... USERNAME: AgAkGib0a...
Consuming Secret in Application using Environment Variables#
When consuming the sealed secret in the application using environment variables, you need to add the env: field in the values file, for example if you want to use environment variables from above MySQL secret, in values file, replace:
env: []
with:
env:
- name: MYSQL_USERNAME
valueFrom:
secretKeyRef:
name: mysql-secrets
key: USERNAME
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secrets
key: USER_PASSWORD