External Secrets Operator (ESO)¶
Kubernetes operator that syncs secrets from external providers (Vault, AWS SM, GCP SM) into native K8s Secrets.
Overview¶
ESO is the standard Kubernetes bridge for external secrets. It watches ExternalSecret CRDs, fetches values from external providers (Vault, AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, etc.), and creates/updates native Kubernetes Secrets. It also supports PushSecret to push K8s secrets back to external providers.
Key Facts¶
| Attribute | Detail |
|---|---|
| Website | external-secrets.io |
| Stars | ~5k+ ⭐ |
| Latest Version | v2.2.0 (March 20, 2026) |
| Language | Go |
| License | Apache 2.0 |
| Governance | Community |
Evaluation¶
| Pros | Cons |
|---|---|
| Multi-provider — Vault, AWS, GCP, Azure, etc. | Sync lag (not real-time, poll-based) |
| PushSecret for bidirectional sync | Secrets stored in K8s etcd (base64) |
| Generators for dynamic secret creation | v1beta1 API deprecated |
| Templating for complex secret construction | Only supports latest minor version |
| ClusterSecretStore for cross-namespace | |
| Apache 2.0, active community |
Architecture¶
flowchart TB
subgraph K8s["Kubernetes Cluster"]
ES["ExternalSecret\n(CRD)"]
SS["SecretStore\n(provider config)"]
ESO_C["ESO Controller"]
Secret["K8s Secret\n(native)"]
end
subgraph External["External Providers"]
Vault_E["HashiCorp Vault"]
AWS_SM["AWS Secrets Manager"]
GCP_SM["GCP Secret Manager"]
AZ_KV["Azure Key Vault"]
end
ES --> ESO_C
SS --> ESO_C
ESO_C -->|"fetch"| External
ESO_C -->|"create/update"| Secret
Secret --> Pod_E["Pods\n(mount or envFrom)"]
style ESO_C fill:#1565c0,color:#fff
Core Resources¶
| Resource | Scope | Purpose |
|---|---|---|
| SecretStore | Namespace | Provider connection config |
| ClusterSecretStore | Cluster-wide | Shared provider config |
| ExternalSecret | Namespace | Defines which secrets to sync |
| ClusterExternalSecret | Cluster-wide | Cross-namespace secret sync |
| PushSecret | Namespace | Push K8s secrets → external provider |
Notes¶
Sources¶
Questions¶
Answered¶
-
Q: Can ESO push secrets to providers? -- Yes. The PushSecret CRD reverses the normal flow, pushing data from Kubernetes Secrets out to external providers such as AWS Secrets Manager, HashiCorp Vault, or GCP Secret Manager. It supports configurable deletion and update policies.
-
Q: How does ESO differ from Sealed Secrets? -- Sealed Secrets encrypts secrets client-side and decrypts them in-cluster using a controller-managed key pair. ESO does not encrypt secrets itself; it synchronizes secrets from external management systems (Vault, AWS SM, etc.) into native Kubernetes Secrets. ESO delegates trust to the external provider rather than managing its own encryption.
-
Q: What happens if the external provider is unavailable? -- ESO continues serving the last successfully synced Kubernetes Secret. The
status.conditionsfield reflects the sync error. Once the provider recovers, the next reconciliation loop updates the Secret. TheretrySettingsfield on SecretStore controls retry behavior (maxRetries,retryInterval). -
Q: Can ESO manage secrets across multiple clusters? -- Yes. Use the Kubernetes provider in a SecretStore to sync secrets between clusters. Each cluster runs its own ESO controller, and SecretStores can reference remote Kubernetes API servers. ClusterExternalSecret distributes ExternalSecrets across namespaces within a single cluster.
-
Q: How does the template engine work? -- ESO uses Go templates defined in
spec.target.templateto transform secret data before writing it to the Kubernetes Secret. Templates support built-in functions (base64encode,fromJson,toString,regexMatch) and full Go template control structures. The template context includes all fetched secret values. -
Q: What is the difference between SecretStore and ClusterSecretStore? -- SecretStore is namespaced and can only be referenced by ExternalSecrets in the same namespace. ClusterSecretStore is cluster-scoped and can be referenced by ExternalSecrets in any namespace. ClusterSecretStore supports
conditionsto restrict which namespaces can reference it.
Open¶
-
Q: How does ESO handle secret rotation notifications to workloads? -- ESO updates the Kubernetes Secret when the external value changes, but workloads that mounted the secret as a file will not see the updated value until the pod is restarted. Consider using the Reloader operator or application-level secret watching to trigger rolling updates when secrets change.
-
Q: What is the performance impact of running many ExternalSecrets? -- Each ExternalSecret triggers a reconciliation loop at its
refreshInterval. With thousands of ExternalSecrets, the controller may generate significant API traffic against the external provider. TunerefreshIntervalto balance freshness against API rate limits.