Skip to content

Reference

Scope

Look-up facts for External Secrets Operator (ESO): release and support matrix, API versions, CRD field values, provider stability, generators, controller flags, Helm values, metrics, ports, template functions, security advisories, and a hardening checklist. For why things work this way, see Explanation. For task recipes, see How-to Guides.

Release and Support Matrix

ESO supports only the current minor version; the previous minor is end-of-life the day a new minor ships. Since v2.0 a new minor has shipped roughly every three weeks, although the release docs describe releases as "as-needed". The Helm chart and the operator have separate release lifecycles, but chart version and appVersion currently move together (chart 2.11.0 / app v2.11.0).

ESO version Tested Kubernetes Release date End of life Notable change
2.11 1.36 2026-09-18 Release of 2.12 Barbican application credentials, Infisical duplicate-key option, global imageRegistry in chart
2.10 1.36 2026-08-28 2026-09-18 Conjur PushSecret, OpenBao Kubernetes auth, GitHub Dependabot secrets
2.9 1.36 2026-08-07 2026-08-28 1Password environments
2.8 1.35-1.36 2026-07-18 2026-08-07 CreateOrMerge creation policy, AWS Certificate Manager provider, GitLab deploy-token generator
2.7 1.35 2026-06-26 2026-07-18 Dedicated OpenBao provider, BeyondTrust Workload Credentials, syncWindows
2.3 1.34-1.35 2026-04-10 2026-04-24 First release line after the CVE-2026-34984 fix
2.0 1.34-1.35 2026-02-06 2026-03-06 Removed unmaintained Alibaba and Device42 providers
1.2 1.34 2025-12-19 2026-01-23 Fix for CVE-2026-22822 (getSecretKey removed)
1.0 1.34 2025-11-07 2025-11-21 GA release, Go multi-module split (/apis, /runtime, /providers/v1/*, /generators/v1/*)
0.20 1.34 2025-09-22 2025-11-07 First release after the 2025 release pause
0.17 1.33 2025-05-14 2025-07-17 Stopped serving v1beta1
0.16 1.32 2025-04-14 2025-05-14 Promoted v1 APIs, removed v1alpha1 and conversion webhooks, removed v1 template engine

Intermediate minors (2.1, 2.2, 2.4-2.6, 1.1, 1.3, 0.18, 0.19) are listed on the upstream Stability and Support page. Upstream recommends upgrading one minor version at a time and reading each release note.

API Versions

Kind API group/version Scope Status
ExternalSecret external-secrets.io/v1 Namespace Stable (GA)
ClusterExternalSecret external-secrets.io/v1 Cluster Stable (GA)
SecretStore external-secrets.io/v1 Namespace Stable (GA)
ClusterSecretStore external-secrets.io/v1 Cluster Stable (GA)
PushSecret external-secrets.io/v1alpha1 Namespace Alpha API
ClusterPushSecret external-secrets.io/v1alpha1 Cluster Alpha API
Generators (Password, ECRAuthorizationToken, ...) generators.external-secrets.io/v1alpha1 Namespace Alpha API
ClusterGenerator generators.external-secrets.io/v1alpha1 Cluster Alpha API
GeneratorState generators.external-secrets.io/v1alpha1 Namespace Alpha API (tracks generated values for cleanup)

v1beta1 is gone

external-secrets.io/v1beta1 stopped being served in v0.17.0 (2025-05-14). Manifests must use external-secrets.io/v1 (only the version string changes). v1alpha1 versions of ExternalSecret/SecretStore were removed in v0.16.0. The Helm value crds.unsafeServeV1Beta1 (default false) re-enables v1beta1 serving for backward compatibility; the chart comment says it would be removed on 2026-05-01, but it is still present in chart 2.11.0.

ExternalSecret Fields

Field Default Purpose
spec.secretStoreRef kind: SecretStore Default store (SecretStore or ClusterSecretStore)
spec.refreshPolicy Periodic Periodic, OnChange, or CreatedOnce
spec.refreshInterval 1h0m0s Re-sync period; 0s fetches and creates once
spec.syncWindows none Cron-based allow/deny windows (UTC) for periodic refresh (since 2.7)
spec.target.name metadata.name Target Secret name (immutable)
spec.target.creationPolicy Owner Ownership of the target Secret (see below)
spec.target.deletionPolicy Retain What happens when provider data disappears (see below)
spec.target.immutable false Create the Secret as immutable
spec.target.template none Secret type, metadata, and Go-template data/templateFrom
spec.data[] none Per-key mapping secretKey <- remoteRef (key, property, version, decodingStrategy)
spec.data[].sourceRef none Per-entry storeRef or generatorRef override
spec.dataFrom[] none Bulk: extract, find (by name.regexp or tags), or sourceRef.generatorRef; supports rewrite

Manual refresh: kubectl annotate es <name> force-sync=$(date +%s) --overwrite.

Creation, Deletion and Refresh Policies

Policy Value Behavior
creationPolicy Owner (default) Creates the Secret and sets ownerReferences; deleting the ExternalSecret deletes the Secret
creationPolicy Orphan Creates/updates the Secret without ownerReferences; it survives ExternalSecret deletion
creationPolicy Merge Does not create; merges keys into an existing Secret (expects it to exist)
creationPolicy CreateOrMerge Creates the Secret if missing, otherwise merges (since 2.8)
creationPolicy None Does not create or update a Secret
deletionPolicy Retain (default) Keeps the Secret when all provider keys are deleted
deletionPolicy Delete Deletes the Secret when all provider keys are deleted
deletionPolicy Merge Removes vanished keys but keeps the Secret
refreshPolicy Periodic (default) Syncs every refreshInterval and on spec change
refreshPolicy OnChange Syncs only when ExternalSecret metadata or spec changes
refreshPolicy CreatedOnce Syncs once per ExternalSecret; combine with target.immutable: true for write-once credentials

Status Conditions

Condition type Reason Meaning
Ready SecretSynced Last sync succeeded
Ready SecretSyncedError Fetch, template or write failed
Ready SecretMissing Target Secret is missing
Ready SecretOwnedByOther Target Secret is owned by another ExternalSecret
Ready SecretImmutable Target Secret is immutable and cannot be updated
Deleted SecretDeleted Target Secret was deleted per deletionPolicy

PushSecret Fields

Field Default Values
spec.secretStoreRefs[] kind: SecretStore One or more stores to write to (by name or labelSelector)
spec.selector none Exactly one of secret.name or generatorRef
spec.refreshInterval 1h0m0s Re-push period
spec.updatePolicy Replace Replace or IfNotExists
spec.deletionPolicy None None (keep in provider) or Delete (remove from provider when PushSecret is deleted)
spec.data[].match none secretKey -> remoteRef.remoteKey / property
spec.data[].conversionStrategy None None or ReverseUnicode
spec.template none Same template engine as ExternalSecret

ClusterSecretStore Conditions

A ClusterSecretStore without spec.conditions can be referenced from every namespace. Each condition entry can match on:

Field Type Example
namespaces list of names ["team-a", "team-b"]
namespaceSelector label selector matchLabels: {app: frontend}
namespaceRegexes list of regular expressions ["^team-.*$"]

Annotation external-secrets.io/ignore-maintenance-checks: "true" on a store silences controller warning events for providers without an explicit maintainer (the admission warning cannot be disabled).

Provider Stability

Upstream lists roughly 40 providers. Only these carry stable or beta status; everything else is alpha and community-maintained.

Provider Stability Maintainer PushSecret
AWS Secrets Manager stable external-secrets Yes
AWS Parameter Store stable external-secrets Yes
Azure Key Vault stable external-secrets Yes
GCP Secret Manager stable external-secrets Yes
HashiCorp Vault stable external-secrets Yes
Akeyless stable external-secrets Yes
CyberArk Secrets Manager (Conjur) stable CyberArk contributors Since 2.10 (feature table not yet updated)
IBM Cloud Secrets Manager stable @IdanAdar No
Oracle Vault stable @anders-swanson Yes
Previder stable @previder No
Kubernetes (remote cluster) beta external-secrets Yes
SecretServer (Delinea Secret Server) beta @gmurugezan Yes

Alpha providers (2026-09): AWS Certificate Manager, Barbican, BeyondTrust, BeyondTrust Workload Credentials, Bitwarden Secrets Manager, Chef, Cloud.ru, Delinea, Devolutions Server, Doppler, Fortanix, Generic Webhook, GitHub Actions/Dependabot secrets, GitLab Variables, Infisical, Keeper Security, Nebius MysteryBox, Ngrok, Onboardbase, OpenBao, OVHcloud, Passbolt, Password Depot, Pulumi ESC, Scaleway, Senhasegura DSM, Volcengine, Yandex Certificate Manager, Yandex Lockbox, 1Password (Connect), 1Password SDK.

Removed: Alibaba Cloud and Device42 (v2.0.0, unmaintained).

Generators

All generators live in generators.external-secrets.io/v1alpha1 and are referenced from dataFrom[].sourceRef.generatorRef (or PushSecret.spec.selector.generatorRef). Every invocation produces new values.

Generator kind Produces
ACRAccessToken Azure Container Registry token
ECRAuthorizationToken AWS ECR registry credentials
STSSessionToken AWS STS session credentials
GCRAccessToken Google Container/Artifact Registry token
QuayAccessToken Short-lived Quay token via a federated robot account
CloudsmithAccessToken Cloudsmith registry token
GithubAccessToken GitHub App installation token
GitlabDeployToken GitLab deploy token (since 2.8)
Grafana Grafana service-account token
VaultDynamicSecret Any Vault dynamic secret (database, AWS, PKI, ...)
BeyondtrustWorkloadCredentialsDynamicSecret BeyondTrust dynamic credential
Password Random password (length, digits, symbols)
SSHKey SSH key pair
UUID Random UUID
MFA TOTP code from a seed secret
Webhook Result of an arbitrary HTTP call
Fake Static values for testing
ClusterGenerator Cluster-scoped wrapper around any generator spec

Controller Flags

Flag Default Notes
--concurrent 1 Concurrent reconciles (Helm: concurrent)
--controller-class default Match spec.controller on stores (Helm: controllerClass)
--namespace all Watch one namespace only (Helm: scopedNamespace)
--enable-leader-election false Required when replicaCount > 1 (Helm: leaderElect)
--enable-flood-gate true Skip ExternalSecrets whose store is unhealthy
--enable-managed-secrets-caching true Cache only ESO-managed Secrets
--enable-secrets-caching false Cache all cluster Secrets (memory cost)
--enable-vault-token-cache false Reuse Vault tokens across requests
--store-requeue-interval 5m0s Store health re-check period
--client-qps / --client-burst 50 / 100 Kubernetes API client limits
--enable-*-reconciler true Per-CRD switches: cluster-external-secret, cluster-store, secret-store, push-secret, cluster-push-secret
--loglevel info debug logs Secret deletions and key diffs (never values)

Helm Values

Value Default Purpose
installCRDs true Chart installs and upgrades CRDs
crds.conversion.enabled false Conversion webhook (unused since v1alpha1 removal)
crds.unsafeServeV1Beta1 false Temporarily serve deprecated v1beta1
crds.create* true Per-CRD install switches (must match process*)
replicaCount 1 Core controller replicas
leaderElect false Leader election for the controller
concurrent 1 Concurrent reconciles
processClusterExternalSecret, processClusterStore, processSecretStore, processPushSecret, processClusterPushSecret, processClusterGenerator true Reconciler switches
scopedNamespace / scopedRBAC "" / false Namespace-scoped install (disables cluster kinds)
genericTargets.enabled false Allow writing ConfigMaps/custom resources instead of Secrets
webhook.create true Admission/conversion webhook Deployment
certController.create true Cert controller Deployment
serviceMonitor.enabled false Prometheus Operator ServiceMonitor
grafanaDashboard.enabled false Bundled Grafana dashboard
bitwarden-sdk-server.enabled false Sidecar service required by the Bitwarden provider

Chart repository: https://charts.external-secrets.io (chart external-secrets/external-secrets). CRDs exceed the 256 KB client-side apply limit, so manual CRD installs need kubectl apply --server-side.

Ports and Network Flows

Component Inbound Outbound
Core controller 8080 metrics (from monitoring), 8082 liveness kube-apiserver, secret provider endpoints
Webhook 10250 from kube-apiserver, 8080 metrics, 8081 health kube-apiserver
Cert controller 8080 metrics, 8081 health kube-apiserver

Metrics

Metric Type Meaning
externalsecret_sync_calls_total Counter ExternalSecret sync calls
externalsecret_sync_calls_error Counter ExternalSecret sync errors
externalsecret_status_condition Gauge Condition per ExternalSecret
externalsecret_reconcile_duration Gauge Reconcile duration
externalsecret_provider_api_calls_count Counter Provider API calls (provider, call, status labels)
clusterexternalsecret_status_condition Gauge Condition per ClusterExternalSecret
secretstore_status_condition / clustersecretstore_status_condition Gauge Store health
secretstore_reconcile_duration / clustersecretstore_reconcile_duration Gauge Store reconcile duration

Plus the standard controller-runtime metrics (workqueue depth, reconcile latency and errors, webhook latency).

Template Functions

Template engine v2 (the only engine since v0.16) exposes Go templates, 200+ Sprig functions (minus env and expandenv), and these ESO helpers:

Function Purpose
pkcs12key, pkcs12keyPass, pkcs12cert, pkcs12certPass Extract keys/certs from PKCS#12 as PEM
pemToPkcs12, pemToPkcs12Pass, fullPemToPkcs12, fullPemToPkcs12Pass, pemTruststoreToPKCS12, pemTruststoreToPKCS12Pass Build PKCS#12 archives
filterPEM, filterCertChain, certSANs Select PEM blocks, leaf/intermediate/root certs, SANs
jwkPublicKeyPem, jwkPrivateKeyPem Convert JWK to PEM
rsaDecrypt Decrypt RSA ciphertext (None or RSA-OAEP, SHA1/SHA256)
toYaml, fromYaml, hexdec Encoding helpers

Renamed from the removed v1 engine: base64encode -> b64enc, base64decode -> b64dec, fromJSON -> fromJson, toJSON -> toJson. Removed: toBytes, pemPrivateKey, pemCertificate, getSecretKey (security fix in 1.2.0). Since the CVE-2026-34984 fix, getHostByName is also unavailable in user templates.

Security Advisories

ID Published Affected Fixed Summary
CVE-2024-45041 (GHSA-qwgc-rr35-h4x9) 2024-09-09 < 0.10.2 0.10.2 Cert-controller ClusterRole could read all Secrets and patch webhook configs (CVSS 3.1: 8.3)
CVE-2025-55196 (GHSA-fcxq-v2r3-cc8h) 2025-08-13 0.15.0 - 0.19.1 0.19.2 PushSecret controller listed Secrets/stores without a namespace selector (CVSS 7.1)
CVE-2026-22822 (GHSA-77v3-r3jw-j2v2) 2026-01-20 0.20.2 - < 1.2.0 1.2.0 getSecretKey template function read Secrets cross-namespace (GHSA: 9.3 critical, NVD: 8.8 high)
CVE-2026-34984 (GHSA-r2pg-r6h7-crf3) 2026-04-11 2.0.0 - 2.2.0 and earlier fix merged 2026-03-31; first 2.x minor after is 2.3.0 getHostByName in templates allowed DNS-based exfiltration (CVSS 7.1)

Report vulnerabilities to [email protected], not GitHub issues.

Hardening Checklist

  • Run the current minor (only it receives fixes) and upgrade one minor at a time.
  • Verify images with Cosign keyless signatures (ghcr.io/external-secrets/external-secrets); SBOM and provenance ship with each release.
  • Use workload identity (IRSA, EKS Pod Identity, GKE/Azure Workload Identity, Vault Kubernetes auth) instead of static keys.
  • Restrict SecretStore, PushSecret and ClusterPushSecret creation to platform teams via RBAC.
  • Add conditions to every ClusterSecretStore.
  • Disable unused kinds (process*: false, crds.create*: false) or install namespace-scoped (scopedRBAC, scopedNamespace).
  • Set rbac.serviceAccountTokenCreate: false and grant token creation per ServiceAccount.
  • Apply NetworkPolicies per the port table; use private provider endpoints.
  • Restrict webhook TLS ciphers (webhook.extraArgs.tls-ciphers); webhook minimum is TLS 1.2 by default.
  • Enable Kubernetes Secret encryption at rest (ESO writes plain Kubernetes Secrets).
  • Enforce policy with Kyverno or OPA Gatekeeper (allowed providers, no cross-namespace refs, template restrictions).
  • Alert on externalsecret_sync_calls_error and Ready=False conditions.

Benchmarks

Unsourced performance data

Upstream publishes no controlled benchmarks. The figures below were estimated from vendor documentation, community reports, and engineering judgment; hardware, versions and methodology were not recorded. Treat them as rough guidance and run your own load test. See Explanation for what actually drives load.

Provider Secret fetch time (estimate) Default refresh Notes
AWS Secrets Manager 50-200 ms 1h Account-level API quotas apply
HashiCorp Vault 10-50 ms 1h Network-dependent
Azure Key Vault 50-200 ms 1h Regional latency
GCP Secret Manager 30-100 ms 1h Fast in-region
ExternalSecrets Controller CPU (estimate) Controller memory (estimate)
50 50-100m 128Mi
200 100-300m 256Mi
1,000 500m-1 512Mi-1Gi
Dimension Limit (estimate) Notes
ExternalSecrets per cluster 10,000+ Controller memory and provider quotas are the bottleneck
Stores per cluster 50+ Each store is health-checked every --store-requeue-interval
Refresh rate Provider API limits AWS Secrets Manager GetSecretValue quota is documented at 10,000 requests/s per account and Region; Vault has no default limit but operators can set rate-limit quotas

Sources