Sealed Secrets is a Kubernetes controller and companion CLI tool (kubeseal) created by Bitnami that solves a specific GitOps problem: how to store Kubernetes Secret manifests in a Git repository without exposing their contents. A standard Kubernetes Secret is base64-encoded, not encrypted — anyone who can read the manifest file or the Git history can decode the values instantly. Sealed Secrets resolves this by encrypting the secret values using asymmetric cryptography before they ever leave the developer’s machine, producing a SealedSecret custom resource that contains only ciphertext and is safe to commit to any repository, public or private. The corresponding plaintext Secret is materialised exclusively inside the cluster by the controller, which holds the only private key capable of decryption.
The mechanics follow a strict one-way trust model. On installation, the Sealed Secrets controller generates an RSA key pair and stores the private key as a Kubernetes Secret inside the cluster. Developers retrieve the public key via kubeseal --fetch-cert and use it to encrypt a standard Secret manifest locally: kubeseal encrypts each value individually using the public key, embeds the cluster and namespace identity as associated data in the ciphertext (so a SealedSecret created for one namespace cannot be decrypted and applied to another, and a SealedSecret from one cluster cannot be decrypted by a different cluster’s controller), and outputs a SealedSecret YAML manifest. That manifest is committed to Git and applied to the cluster through the normal GitOps pipeline (Argo CD, Flux). When the controller detects a new or updated SealedSecret, it decrypts the values using its private key and creates or updates a standard Kubernetes Secret object in the specified namespace. From that point, pods consume the Secret in the normal way with no awareness of the Sealed Secrets layer. Key rotation is handled by the controller generating a new key pair periodically (defaulting to every 30 days); old keys are retained for decrypting existing SealedSecrets and new sealings use the latest key.
Sealed Secrets occupies a different architectural niche from ESO and the Secrets Store CSI Driver: it has no dependency on an external secret backend at runtime, making it operationally simpler — there is no Vault, no AWS Secrets Manager, no external service to be available for a pod to start. The entire system is self-contained within the cluster. The trade-off is that secret values live in the Git repository (encrypted) and in etcd (as a native Secret), rather than in a purpose-built secret store with rotation, leasing, and audit capabilities; Sealed Secrets provides no rotation lifecycle, no dynamic credentials, and no centralised audit trail beyond the Kubernetes API server’s own audit log. It is the right choice for teams adopting GitOps who want a simple, infrastructure-light path to committing secrets safely, and the wrong choice for teams who need credential rotation, short-lived secrets, or cross-cluster secret management — scenarios better served by ESO backed by Vault or a cloud secret manager.
