Skip to content

Bitnami Sealed Secrets for GitOps

Sealed Secrets by Bitnami encrypts Kubernetes Secrets into SealedSecret custom resources using asymmetric public-key cryptography. Because only the controller running inside the target cluster possesses the private decryption key, SealedSecret manifests are safe to commit directly to public or private Git repositories (GitOps).


How It Works

sequenceDiagram
    participant Dev as Developer / CI Pipeline
    participant CLI as kubeseal CLI
    participant Git as Git Repository
    participant Ctrl as Sealed Secrets Controller
    participant K8s as Native Kubernetes Secret

    Dev->>CLI: Pass plain Secret YAML
    CLI->>Ctrl: Fetch Public Key (or use local cert)
    CLI->>Dev: Generate encrypted SealedSecret YAML
    Dev->>Git: Commit SealedSecret to Git
    Git->>Ctrl: Applied to Cluster via GitOps (ArgoCD/Flux)
    Ctrl->>K8s: Decrypts with Private Key and creates native Secret

Step 1. Install Sealed Secrets Controller via Helm

helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
helm repo update

helm install sealed-secrets sealed-secrets/sealed-secrets \
  --namespace kube-system \
  --version 2.16.1

Step 2. Install kubeseal CLI

brew install kubeseal
export VERSION="0.27.1"
curl -sSL https://github.com/bitnami-labs/sealed-secrets/releases/download/v${VERSION}/kubeseal-${VERSION}-linux-amd64.tar.gz \
  | tar -xz kubeseal
sudo install kubeseal /usr/local/bin/

Step 3. Seal a Secret

Create a plain Kubernetes secret locally (do not commit this file):

mysecret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
  namespace: default
type: Opaque
stringData:
  username: admin
  password: supersecretpassword123

Encrypt with kubeseal:

kubeseal --format yaml < mysecret.yaml > mysealedsecret.yaml

The resulting mysealedsecret.yaml is safe to commit to version control:

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: mysecret
  namespace: default
spec:
  encryptedData:
    username: AgBy8hg...
    password: AgCx9pQ...

Apply the sealed secret to the cluster:

kubectl apply -f mysealedsecret.yaml

# Verify controller decrypted and created the native secret
kubectl get secret mysecret -n default


Key Backup & Scope Options

Back Up Your Private Key

The controller rotates its key pair automatically every 30 days while retaining older keys. Store a backup of the private key secret securely in case of disaster recovery.

# Export the private key secret
kubectl get secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key \
  -o yaml > sealed-secrets-keys-backup.yaml

Scope Options

  • strict (Default): Bound to both secret name and namespace.
  • namespace-wide: Can be renamed within the same namespace.
  • cluster-wide: Can be used under any name in any namespace.