Introduction
External Secrets Operator (ESO) is a CNCF incubating project that solves the "how do I get my production secrets into a Pod without checking them into Git" problem. It reads from your existing secret backend — AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager, Azure Key Vault, 1Password, Doppler, Bitwarden, and dozens more — and materializes them as native Kubernetes Secret objects that Pods consume as usual.
What External Secrets Operator Does
- Watches
ExternalSecretCRDs and syncs each key to a native Kubernetes Secret - Supports 30+ providers with a plugin architecture for custom backends
- Rotates Secrets automatically on a configurable
refreshInterval - Templates values into arbitrary shapes (JSON blobs, .env files, TLS bundles)
- Deletes downstream Secrets when the ExternalSecret is removed, preventing drift
Architecture Overview
ESO is a Go controller built with controller-runtime. It installs CRDs for SecretStore, ClusterSecretStore, ExternalSecret, and ClusterExternalSecret, then reconciles each ExternalSecret by calling the configured provider's SDK. Fetched values are cached and diffed against the target Secret; only real changes trigger updates, reducing API calls to your backend.
Self-Hosting & Configuration
- Install via Helm or the provided manifests in the release artifacts
- Each provider has its own auth story — IRSA, Workload Identity, service principals, tokens
ClusterSecretStoreserves multiple namespaces;SecretStoreis namespace-scoped- Use
spec.dataFromto ingest an entire path as-is, orspec.datafor per-key mapping PushSecretCRD (beta) reverses the flow: push K8s Secrets up to a central vault
Key Features
- 30+ first-class providers including major clouds, Vault, Doppler, Akeyless, 1Password, and Pulumi ESC
- Go-template support for transforming values before writing the Secret
- Metrics and webhooks for auditing every rotation
- Works with SOPS, sealed-secrets, and other GitOps-friendly workflows
- Multi-tenancy: namespace selectors on ClusterSecretStore enforce isolation
Comparison with Similar Tools
- Vault Agent Injector — Vault-only; injects at Pod start rather than via Secret objects
- Sealed Secrets — encrypts secrets into Git; no external backend sync
- Secrets Store CSI Driver — similar scope, mounts as files; less flexible templating
- SOPS / age — GitOps-first; human-managed rotation, not continuous sync
- Akeyless / Infisical operators — vendor-specific; ESO works across vendors
FAQ
Q: What happens if the backend is unreachable? A: ESO retries with exponential backoff. Existing Secrets remain intact — Pods keep running.
Q: Can I rotate secrets without restarting Pods?
A: Yes if your app supports hot reload. Otherwise pair with Reloader or checksum/secret annotations.
Q: How do I restrict which namespaces can read a ClusterSecretStore?
A: Use spec.provider.aws.role, conditions namespaceSelector, and RBAC on the ExternalSecret resource.
Q: Is there a GUI? A: ESO itself is headless, but k9s, Lens, and Headlamp can show ExternalSecret status out of the box.