Tharindu Kalhara

2025-12-28

Using Sealed Secrets in Kubernetes

sealed secretskubernetes

Using Sealed Secrets in Kubernetes

Managing secrets securely is one of the biggest challenges in Kubernetes, especially when following a GitOps workflow.

If you've worked with Kubernetes Secrets before, you probably know that they are only Base64 encoded, not encrypted. This means storing them directly in a Git repository is a serious security risk.

This is where Bitnami Sealed Secrets comes in.

Sealed Secrets allows you to encrypt Kubernetes Secrets so they can be safely committed to Git repositories. Only the Sealed Secrets controller running inside your Kubernetes cluster can decrypt them. :contentReference[oaicite:0]


Why Not Store Kubernetes Secrets Directly?

A normal Kubernetes Secret looks something like this:

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  username: YWRtaW4=
  password: cGFzc3dvcmQ=

Although the values appear encrypted, they are simply Base64 encoded, meaning anyone can easily decode them.

If this file is committed to Git, your credentials are exposed.


What are Sealed Secrets?

Sealed Secrets is an open-source Kubernetes controller developed by Bitnami.

It introduces a new Kubernetes resource called:

SealedSecret

Instead of storing plaintext or Base64 encoded secrets, the secret is encrypted using the cluster's public key.

Only the controller inside the Kubernetes cluster possesses the private key needed to decrypt it.

This makes the encrypted secret completely safe to store in Git repositories. :contentReference[oaicite:1]


How Sealed Secrets Work

Plain Secret
      │
      ▼
kubeseal CLI
      │
Encrypt using Cluster Public Key
      │
      ▼
SealedSecret YAML
      │
Commit to Git
      │
      ▼
FluxCD / ArgoCD
      │
      ▼
Kubernetes Cluster
      │
      ▼
Sealed Secrets Controller
      │
Decrypt using Private Key
      │
      ▼
Normal Kubernetes Secret

The private key never leaves the Kubernetes cluster.


Prerequisites

Before getting started, ensure you have:

  • A running Kubernetes cluster
  • kubectl
  • kubeseal
  • Helm (recommended)
  • Cluster administrator permissions

Step 1 - Install the Sealed Secrets Controller

Add the Bitnami Helm repository.

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

Update Helm repositories.

helm repo update

Install the controller.

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

Verify the installation.

kubectl get pods -n kube-system

You should see the Sealed Secrets controller running successfully. :contentReference[oaicite:2]


Step 2 - Install kubeseal

Download the latest release.

wget https://github.com/bitnami-labs/sealed-secrets/releases/latest/download/kubeseal-linux-amd64.tar.gz

Extract it.

tar -xvzf kubeseal-linux-amd64.tar.gz

Move it into your PATH.

sudo install -m 755 kubeseal /usr/local/bin/kubeseal

Verify the installation.

kubeseal --version

Step 3 - Create a Kubernetes Secret

Create a standard Kubernetes Secret.

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
  namespace: default
type: Opaque
stringData:
  username: admin
  password: mypassword

Save it as:

secret.yaml

Step 4 - Encrypt the Secret

Use kubeseal to convert the Secret into a Sealed Secret.

kubeseal \
    --format yaml \
    < secret.yaml \
    > sealed-secret.yaml

A new encrypted resource will be generated.

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: app-secret
spec:
  encryptedData:
    username: AgB...
    password: AgD...

Notice that the original secret values are no longer visible.


Step 5 - Commit to Git

Now the encrypted file can safely be committed.

git add .

git commit -m "Add sealed secret"

git push

Unlike regular Kubernetes Secrets, this file can safely exist in your Git repository because only your Kubernetes cluster can decrypt it. :contentReference[oaicite:3]


Step 6 - Apply the Sealed Secret

Deploy the encrypted resource.

kubectl apply -f sealed-secret.yaml

The Sealed Secrets controller automatically:

  • Detects the SealedSecret
  • Decrypts it
  • Creates a normal Kubernetes Secret

Verify it.

kubectl get secrets

You should see:

app-secret

Verify the Secret

Inspect the generated Secret.

kubectl describe secret app-secret

Or retrieve it.

kubectl get secret app-secret -o yaml

The controller has recreated a standard Kubernetes Secret that your applications can consume.


Using Sealed Secrets with GitOps

Sealed Secrets integrates perfectly with GitOps tools such as:

  • FluxCD
  • ArgoCD

A typical workflow looks like this.

Developer
      │
      ▼
Create Secret
      │
      ▼
kubeseal
      │
      ▼
Commit SealedSecret
      │
      ▼
Git Repository
      │
      ▼
FluxCD / ArgoCD
      │
      ▼
Kubernetes
      │
      ▼
Sealed Secrets Controller
      │
      ▼
Secret Created

This allows your Git repository to remain the single source of truth while ensuring sensitive credentials are never stored in plaintext.


Benefits of Sealed Secrets

  • Safe to store secrets in Git
  • Perfect for GitOps workflows
  • Uses asymmetric encryption
  • Private key never leaves the cluster
  • Fully Kubernetes native
  • Easy integration with FluxCD and ArgoCD
  • Eliminates manual secret creation

Best Practices

  • Never commit plaintext Kubernetes Secrets to Git.
  • Encrypt secrets using kubeseal before committing.
  • Keep the Sealed Secrets controller running and backed up.
  • Rotate secrets regularly.
  • Use namespace-scoped secrets whenever possible.
  • Follow the principle of least privilege with Kubernetes RBAC. :contentReference[oaicite:4]

Conclusion

Sealed Secrets provides a secure and GitOps-friendly approach to managing sensitive information in Kubernetes.

Instead of exposing credentials through Base64 encoded Secret objects, Sealed Secrets encrypts them using public-key cryptography. The encrypted manifests can safely be version-controlled, while only the controller running inside your Kubernetes cluster can decrypt and recreate the original Secrets.

If you're using FluxCD or ArgoCD, Sealed Secrets is one of the simplest and most effective ways to securely manage application secrets in a GitOps workflow. :contentReference[oaicite:5]


Key Takeaways

  • Kubernetes Secrets are Base64 encoded, not encrypted.
  • Sealed Secrets encrypt Secrets using public-key cryptography.
  • Only the Kubernetes cluster can decrypt Sealed Secrets.
  • Safe to store encrypted secrets in Git repositories.
  • Works seamlessly with FluxCD and ArgoCD.
  • Simplifies secure secret management in GitOps environments.