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-secrets
namespace 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_FILE
where:
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
SealedSecret
resource:kubeseal --controller-name=sealed-secrets --controller-namespace=stakater-sealed-secrets --format yaml --scope cluster-wide < secret-mysql.yaml
This 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
sealedSecret
block in the Helm values present indeploy/values.yaml
in 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.yaml
This 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
sealedSecret
block in the Helm values present in<tenant>/<application>/<env>/values.yaml
in 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