Skip to main content
  1. Index/

ESO (External Secrets Operator)

External Secrets Operator (ESO) is a CNCF incubating project that bridges the gap between Kubernetes-native secrets and enterprise secret management backends. Its premise is that native Kubernetes Secrets — base64-encoded values stored in etcd — are not adequate as a primary secret store: they offer no encryption at rest by default, no access audit trail, no versioning or rotation lifecycle, and no single source of truth across multiple clusters. Rather than replacing Kubernetes Secrets as a consumption mechanism (applications still mount them as environment variables or files in the familiar way), ESO replaces etcd as their source of authority, pulling the real values from a backend that does provide those properties and keeping the Kubernetes Secret as a synchronised, ephemeral projection.

ESO introduces three Custom Resource Definitions that together express the full synchronisation contract. A SecretStore (namespace-scoped) or ClusterSecretStore (cluster-wide) defines how to authenticate with and connect to a specific backend: the provider type, endpoint, and credentials ESO should use. An ExternalSecret declares which keys to fetch from which store, how to map them into a Kubernetes Secret, and a refreshInterval — the polling cadence at which ESO re-fetches the value from the backend and updates the Secret if it has changed. When ESO reconciles an ExternalSecret, it authenticates to the backend using the referenced SecretStore, fetches the specified secret values, and creates or patches a native Secret object in the same namespace. A PushSecret resource (the inverse direction) allows Kubernetes Secrets to be pushed into a backend, enabling bidirectional synchronisation. The provider abstraction is wide: ESO ships support for over 20 backends out of the box — Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, Doppler, Infisical, and many others — with a provider plugin model for the rest. Switching backends requires updating the SecretStore, not application code or ExternalSecret definitions.

ESO is the most commonly used approach for Kubernetes secrets management in GitOps workflows because it cleanly separates the two concerns that Sealed Secrets conflates: the reference (the ExternalSecret manifest, which is safe to commit to Git and contains no secret material) and the value (held in the backend, never in the repository). Its trade-off compared to the Secrets Store CSI Driver is architectural: ESO materialises secrets into native Kubernetes Secret objects, which means they exist in etcd and are accessible via the Kubernetes API to anyone with the appropriate RBAC; the CSI driver avoids etcd entirely by mounting secrets directly into pod filesystems. For most workloads ESO’s etcd presence is acceptable — particularly when etcd encryption at rest is configured — and its simpler consumption model (standard env vars and volume mounts, no pod spec changes beyond annotation) makes it the lower-friction choice. For workloads that require secrets to never touch the Kubernetes control plane, the CSI driver is the appropriate alternative.

Related

Sealed Secrets

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.

Confidential Containers (CoCo)

Confidential Containers (CoCo) is a CNCF sandbox project that lifts hardware confidential computing — TDX, SEV-SNP, Intel SGX, IBM Secure Execution — up to the Kubernetes pod level, providing a unified software layer that abstracts away the underlying TEE technology. Its defining trust model is unusually strict: the Kubernetes control plane, the kubelet, the container runtime, and the cloud operator are all treated as explicitly untrusted. Only the hardware itself and the workload owner’s own supply chain are in scope for trust.

KMS v2 (Kubernetes KMS Provider v2)

KMS v2 (Kubernetes KMS Provider version 2) is the stable (GA since Kubernetes 1.29, KMS v1 deprecated in 1.28 and disabled by default in 1.29) mechanism for encrypting the contents of the Kubernetes etcd datastore at rest using an external key management service. Without encryption, Kubernetes Secrets stored in etcd are base64-encoded — trivially decodable by anyone with read access to the etcd data files or a snapshot. With KMS v2 enabled, resources written to etcd — Secrets, ConfigMaps, and any other API objects selected by the EncryptionConfiguration — are encrypted before being persisted, using a unique per-object key derived locally. The envelope encryption scheme means those per-object keys are never stored in plaintext: only their encrypted form lives in etcd, and only the external KMS holds the wrapping key. The encryption configuration is declared in a file referenced by the API server’s --encryption-provider-config flag, with kms: apiVersion: v2 selecting the KMS v2 code path, and endpoint: unix:///path/to/plugin.sock pointing at the plugin’s Unix domain socket.