Managing Kubernetes Secrets Securely with Sealed Secrets
Are you storing your Kubernetes secrets in Git? If so, you're probably exposing sensitive data without realizing it. Sealed Secrets offer a secure, GitOps-friendly way to encrypt your secrets so they’re safe even in public repositories.
In this guide, you'll learn:
- What Kubernetes secrets are and why they're insecure by default
- What Sealed Secrets are and how they work
- When to use them — and what to watch out for
- How to install and use them with real examples
- Alternatives like SOPS and Vault
Let’s dive in and make your GitOps workflow both secure and maintainable.
What is a Kubernetes Secret?
A Kubernetes Secret is an object used to store sensitive data like passwords, OAuth tokens, and SSH keys. These secrets are base64-encoded and stored within the cluster. While convenient, they lack strong encryption, making them unsuitable for storing in Git repositories directly.
Base64 encoding is not encryption. Storing Kubernetes secrets in Git without protection exposes them to risk.
What is a Sealed Secret?
Sealed Secrets, developed by Bitnami, provide a way to store encrypted Kubernetes secrets safely in Git repositories. A SealedSecret is an encrypted version of a regular Secret, which can only be decrypted by the controller running in the target cluster.
How it works
-
You create a Kubernetes Secret manifest as you normally would.
-
You use the
kubeseal
CLI to encrypt this secret. The encryption is done using the public key of the Sealed Secrets controller running in your cluster. -
The public key is automatically generated by the controller upon installation.
- You can retrieve it with:
kubeseal --fetch-cert
or by accessing the controller's secret viakubectl
. -
You do not need to generate keys manually; the controller handles key pair generation internally.
-
The encrypted secret (called a SealedSecret) is safe to store in Git, even in a public repository, because it cannot be decrypted without the matching private key.
-
When you apply this SealedSecret to the cluster, the Sealed Secrets controller uses its private key (stored only inside the cluster) to decrypt it and generate a standard Kubernetes Secret.
Because the private key never leaves the controller inside the cluster, only that specific cluster can decrypt and use the sealed secret, ensuring your sensitive data remains protected.
Why Use Sealed Secrets?
- GitOps-Friendly: Safe to commit to Git and track changes over time.
- Cluster-Specific Decryption: Only the intended cluster can decrypt secrets.
- Simple Workflow: Easy integration with CI/CD tools.
- Open Source and Maintained: Backed by the community and Bitnami.
Things to Watch Out For
- If you lose the private key (e.g., during cluster recreation), you won’t be able to decrypt existing sealed secrets.
- Sealed secrets are one-way encrypted—you cannot retrieve the original secret from the sealed one.
- Rotation or migration requires planning (e.g., backing up keys).
Installing Sealed Secrets
1. Install the Sealed Secrets Controller
Use Helm (recommended):
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
Or using a manifest:
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.25.0/controller.yaml
Replace the version URL with the latest release if needed.
2. Install the CLI
brew install kubeseal # macOS
# or download from https://github.com/bitnami-labs/sealed-secrets/releases
Using Sealed Secrets in Practice
Step-by-step
1. Create a Kubernetes Secret manifest
apiVersion: v1
kind: Secret
metadata:
name: mysecret
namespace: default
type: Opaque
data:
password: bXlzZWNyZXRwYXNzd29yZA== # base64 encoded
2. Seal the secret
Tip: You can seal directly from kubectl
output too:
kubectl create secret generic mysecret \
--from-literal=password=mypassword \
--dry-run=client -o json | \
kubeseal --format=yaml > mysealedsecret.yaml
3. Commit to Git
The mysealedsecret.yaml
is now safe to commit and store in your Git repository.
4. Apply it to your cluster
This will automatically generate a Kubernetes Secret in the target namespace.
Notes and Alternatives
Rotating Keys
To back up and rotate your sealing key:
Keep this in a secure location like a password manager or encrypted storage.
Alternatives
- SOPS (by Mozilla) + Kustomize
- Vault + External Secrets Operator
- Helm Secrets Plugin
SOPS is a good choice if you prefer file-level encryption and flexibility over integration with Kubernetes controllers.
Summary
Sealed Secrets provide a GitOps-compatible and secure way to manage sensitive data in Kubernetes. They are ideal for teams that:
- Want to store secrets in Git
- Need a straightforward and cluster-scoped solution
- Prefer not to manage a separate secrets backend like Vault
By understanding its limitations and setup requirements, you can confidently integrate Sealed Secrets into your CI/CD pipeline.