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.
