Managing Kubernetes Secrets with Sealed Secrets

Yatharth SharmaYatharth Sharma
4 min read

Overview

Kubernetes provides a built-in mechanism for managing sensitive information like passwords, tokens, and keys using Secrets.

However, storing these secrets in plain text, even in version-controlled environments is a major security concern.

This is where Sealed Secrets by Bitnami comes into play. In this blog, we’ll walk through the fundamentals of Sealed Secrets, how it works, and how you can set it up in your Kubernetes environment.

Why Sealed Secrets?

Kubernetes allows you to create secrets in two primary ways:

1. Imperative Way

Using kubectl:

kubectl create secret generic temp-db-secret --from-literal=PASS=example

2. Declarative Way

Creating YAML:

apiVersion: v1
data:
    DB_PASSWORD: jnsfDCJScj43SpM=
kind: Secret
metadata:
    name: database
    namespace: default

By writing a YAML file and applying it with kubectl apply. However, storing these YAML files in Git (especially public repositories) is a huge risk as secrets are base64 encoded and not encrypted.

❗ Base64 ≠ Security

This is where Sealed Secrets helps.

Sealed Secrets allow you to encrypt your Kubernetes secrets using a controller's public key so you can safely store them in version control (even public repos!). Only the cluster with the private key can decrypt and use the secrets.

Sealed Secrets Components

To use Sealed Secrets, there are three main components involved:

  • Sealed Secrets Controller (Operator)
    Deployed on your Kubernetes cluster, it manages decryption and secret creation.

  • kubeseal CLI
    A local tool used to encrypt secrets using the controller's public key.

  • Custom Resource Definition (CRD)
    Represents the SealedSecret object in Kubernetes.

How Sealed Secrets Work

  1. Deploy the Sealed Secrets controller in your cluster.

  2. It generates a public/private key pair.

  3. You encrypt your secret using the public key via kubeseal.

  4. The encrypted file (SealedSecret) is safe to commit to version control.

  5. The controller decrypts the SealedSecret inside the cluster and creates the actual Kubernetes Secret.

Installation Guide

1. Install the Sealed Secrets Controller (via Helm)

## Add helm repo
helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
## Install helm chart
helm install sealed-secrets-controller sealed-secrets/sealed-secrets --namespace kube-system
## Check pod status
kubectl get po -n kube-system

✅ Best practice: Deploy it in the kube-system namespace with deployment name as sealed-secret-controller


2. Install kubeseal CLI

macOS (via Homebrew):

brew install kubeseal

## Check installation
kubeseal --version

Linux (Manual Installation):

## Set KUBESEAL_VERSION, 0.30.0 is latest as of now.
KUBESEAL_VERSION='0.30.0'

## For AMD:
curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz"
tar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz kubeseal
sudo install -m 755 kubeseal /usr/local/bin/kubeseal

## For ARM
curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-arm64.tar.gz"
tar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-arm64.tar.gz kubeseal
sudo install -m 755 kubeseal /usr/local/bin/kubeseal

## Check installation
kubeseal --version

Verify connectivity with K8s cluster sealed-secret connector by fetching the public cert.

## Fetch the controller's public cert:
kubeseal --fetch-cert --controller-name sealed-secrets --controller-namespace kube-system

🛠️ Creating and Encrypting a Secret

Step 1: Create a Kubernetes Secret YAML

kubectl create secret generic temp-db-secret -n default \
  --dry-run=client --from-literal=PASS=example -o yaml > secret.yaml

Step 2: Encrypt it using kubeseal

kubeseal --controller-name=sealed-secrets \
  --controller-namespace=kube-system \
  --format yaml < secret.yaml > mysealedsecret.yaml

Or, do it all in one step:

kubectl create secret generic temp-db-secret -n default \
  --dry-run=client --from-literal=PASS=example -o yaml | \
  kubeseal --controller-name=sealed-secrets \
  --controller-namespace=kube-system --format yaml > mysealedsecret.yaml

Now mysealedsecret.yaml can safely be committed to Git.


🚀 Applying the Sealed Secret

Apply it to your cluster:

kubectl apply -f mysealedsecret.yaml

Check if the secret was created:

kubectl get secret -n default

You can also verify the SealedSecret resource:

kubectl get sealedsecret

✅ You can now even apply the same SealedSecret to another cluster (as long as it has the same private key).


🧠 Wrapping Up

Sealed Secrets is an essential tool for GitOps-based Kubernetes workflows. It bridges the gap between secure secret management and storing everything as code.

Whether you're managing multiple clusters, following GitOps practices, or just looking to enhance your Kubernetes security posture - Sealed Secrets is a simple yet powerful solution.


🔗 Resources:

0
Subscribe to my newsletter

Read articles from Yatharth Sharma directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Yatharth Sharma
Yatharth Sharma

I am a DevOps Engineer currently working as a Sr. Platform Engineer at Leegality. My core skills include Containerization and its Orchestration, Implementing Infrastructure as Code for cloud platforms and enabling the process of CI CD. I also have experience with going cloud-native for microservices and setting up observability over Production for better insights.