Bitnami Sealed Secrets


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 the kubeseal.exe binary from the releases page.

How Sealed Secrets Work

  1. Create a Kubernetes Secret: Define your secret using a Kubernetes Secret manifest.
  2. Encrypt the Secret with kubeseal: Use the kubeseal CLI to encrypt the secret using the Sealed Secrets public key.
  3. Apply the SealedSecret: The encrypted secret is stored as a SealedSecret resource in your cluster.
  4. 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

  1. 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.
  2. 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.
  3. Audit and Monitoring: Implement logging and monitoring to track the creation, modification, and access to secrets. This helps in detecting unauthorized access or misuse.
  4. 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.
  5. Automated Workflows: Integrate Sealed Secrets into your CI/CD pipelines to automate the encryption, decryption, and deployment of secrets as part of your workflow.
  6. 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.