Bitnami Sealed Secrets is a Kubernetes operator that allows you to encrypt your Kubernetes secrets and store them safely in a version control system, such as Git. Sealed Secrets uses a combination of public and private key cryptography to ensure that your secrets can only be decrypted by the Sealed Secrets controller running in your Kubernetes cluster.
This guide will provide an overview of Bitnami Sealed Secrets, how it works, and walk through three detailed examples to help you get started.
Overview of Bitnami Sealed Secrets
Sealed Secrets is a tool designed to solve the problem of managing secrets securely in Kubernetes. Unlike Kubernetes Secrets, which are base64 encoded but not encrypted, Sealed Secrets encrypt the data using a public key. The encrypted secrets can be safely stored in a Git repository. Only the Sealed Secrets controller, which holds the private key, can decrypt these secrets and apply them to your Kubernetes cluster.
Key Concepts
- SealedSecret CRD: A custom resource definition (CRD) that represents an encrypted secret. This resource is safe to commit to version control.
- Sealed Secrets Controller: A Kubernetes controller that runs in your cluster and is responsible for decrypting SealedSecrets and creating the corresponding Kubernetes Secrets.
- Public/Private Key Pair: The Sealed Secrets controller generates a public/private key pair. The public key is used to encrypt secrets, while the private key, held by the controller, is used to decrypt them.
Installation
To use Sealed Secrets, you need to install the Sealed Secrets controller in your Kubernetes cluster and set up the kubeseal
CLI tool.
Step 1: Install Sealed Secrets Controller
Install the Sealed Secrets controller in your Kubernetes cluster using Helm:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install sealed-secrets-controller bitnami/sealed-secrets
Alternatively, you can install it using kubectl
:
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.20.2/controller.yaml
Step 2: Install kubeseal CLI
The kubeseal
CLI tool is used to encrypt your Kubernetes secrets using the public key from the Sealed Secrets controller.
- macOS:
brew install kubeseal
- Linux:
wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.20.2/kubeseal-linux-amd64 -O kubeseal
chmod +x kubeseal
sudo mv kubeseal /usr/local/bin/
- Windows:
Download thekubeseal.exe
binary from the releases page.
How Sealed Secrets Work
- Create a Kubernetes Secret: Define your secret using a Kubernetes Secret manifest.
- Encrypt the Secret with
kubeseal
: Use thekubeseal
CLI to encrypt the secret using the Sealed Secrets public key. - Apply the SealedSecret: The encrypted secret is stored as a
SealedSecret
resource in your cluster. - Decryption and Creation of Kubernetes Secret: The Sealed Secrets controller decrypts the SealedSecret and creates the corresponding Kubernetes Secret.
Example 1: Basic Sealed Secret
Step 1: Create a Kubernetes Secret
Start by creating a Kubernetes Secret manifest. For example, let’s create a secret that contains a database password.
apiVersion: v1
kind: Secret
metadata:
name: my-db-secret
namespace: default
type: Opaque
data:
password: cGFzc3dvcmQ= # base64 encoded 'password'
Step 2: Encrypt the Secret Using kubeseal
Use the kubeseal
command to encrypt the secret:
kubectl create secret generic my-db-secret --dry-run=client --from-literal=password=password -o yaml > my-db-secret.yaml
kubeseal --format yaml < my-db-secret.yaml > my-db-sealedsecret.yaml
This command will create a SealedSecret
manifest file (my-db-sealedsecret.yaml
), which is safe to store in a Git repository.
Step 3: Apply the SealedSecret
Apply the SealedSecret
manifest to your Kubernetes cluster:
kubectl apply -f my-db-sealedsecret.yaml
The Sealed Secrets controller will decrypt the sealed secret and create a Kubernetes Secret in the cluster.
Example 2: Environment-Specific Sealed Secrets
Step 1: Create Environment-Specific Secrets
Create separate Kubernetes Secrets for different environments (e.g., development
, staging
, production
).
For the staging
environment:
apiVersion: v1
kind: Secret
metadata:
name: my-db-secret
namespace: staging
type: Opaque
data:
password: c3RhZ2luZy1wYXNzd29yZA== # base64 encoded 'staging-password'
For the production
environment:
apiVersion: v1
kind: Secret
metadata:
name: my-db-secret
namespace: production
type: Opaque
data:
password: cHJvZHVjdGlvbi1wYXNzd29yZA== # base64 encoded 'production-password'
Step 2: Encrypt Each Secret
Encrypt each secret using kubeseal
:
For staging
:
kubeseal --format yaml < my-db-secret-staging.yaml > my-db-sealedsecret-staging.yaml
For production
:
kubeseal --format yaml < my-db-secret-production.yaml > my-db-sealedsecret-production.yaml
Step 3: Apply the SealedSecrets
Apply the SealedSecrets to the respective namespaces:
kubectl apply -f my-db-sealedsecret-staging.yaml
kubectl apply -f my-db-sealedsecret-production.yaml
The Sealed Secrets controller will create the Kubernetes Secrets in the appropriate environments.
Example 3: Using SOPS and Sealed Secrets Together
SOPS (Secret Operations) is a tool used to encrypt files (including Kubernetes secrets) before committing them to a repository. You can use SOPS in conjunction with Sealed Secrets to add another layer of encryption.
Step 1: Create a Secret and Encrypt with SOPS
First, create a Kubernetes Secret and encrypt it with SOPS:
apiVersion: v1
kind: Secret
metadata:
name: my-sops-secret
namespace: default
type: Opaque
data:
password: cGFzc3dvcmQ= # base64 encoded 'password'
Encrypt this file using SOPS:
sops --encrypt --kms arn:aws:kms:your-region:your-account-id:key/your-kms-key-id my-sops-secret.yaml > my-sops-secret.enc.yaml
Step 2: Decrypt and Seal with kubeseal
Before applying the secret to Kubernetes, decrypt it with SOPS and then seal it with kubeseal
:
sops --decrypt my-sops-secret.enc.yaml | kubeseal --format yaml > my-sops-sealedsecret.yaml
Step 3: Apply the SealedSecret
Apply the SealedSecret to your Kubernetes cluster:
kubectl apply -f my-sops-sealedsecret.yaml
This approach adds an extra layer of security by encrypting the secret file with SOPS before sealing it with Sealed Secrets.
Best Practices for Using Sealed Secrets
- Key Rotation: Regularly rotate the Sealed Secrets controller’s keys to minimize the risk of key compromise. This can be done by re-installing the Sealed Secrets controller, which generates a new key pair.
- Environment-Specific Secrets: Use different secrets for different environments to avoid leaking sensitive data from one environment to another. Encrypt these secrets separately for each environment.
- Audit and Monitoring: Implement logging and monitoring to track the creation, modification, and access to secrets. This helps in detecting unauthorized access or misuse.
- Backups: Regularly back up your SealedSecrets and the Sealed Secrets controller’s private key. This ensures that you can recover your secrets in case of a disaster.
- Automated Workflows: Integrate Sealed Secrets into your CI/CD pipelines to automate the encryption, decryption, and deployment of secrets as part of your workflow.
- Secure the Sealed Secrets Controller: Ensure that the Sealed Secrets controller is running in a secure environment with limited access, as it holds the private key necessary for decrypting secrets.
Conclusion
Bitnami Sealed Secrets is an essential tool for securely managing secrets in Kubernetes, especially in GitOps workflows where secrets are stored in version control systems. By following the detailed examples and best practices provided in this guide, you can securely manage secrets across different environments, integrate Sealed Secrets with other tools like SOPS, and ensure that your Kubernetes applications are both secure and scalable.