Argo CD with External Secrets Operator

Argo CD with External Secrets Operator keeps secret values out of Git and out of Argo CD's cache by having Argo CD deploy only ExternalSecret references. This page covers layout, refresh intervals, health checks and the failure points to plan for.

On this page

How Argo CD with External Secrets Operator keeps secret values out of Git

Argo CD deploys whatever is in Git, so secret values cannot live in Git or in Argo CD's cache. The pattern this topic builds on is External Secrets Operator (ESO) running on the destination cluster. ESO reads secret values from AWS Secrets Manager, Azure Key Vault, Google Secret Manager or Vault and writes ordinary Kubernetes Secrets inside the cluster. Argo CD syncs only the ExternalSecret resources, which contain references (a store, a remote key and a target name) and no values. The values themselves never pass through the Argo CD repo-server or its Redis cache, which is the central difference from plugin-based injection.

Before publishing, the writer must confirm the ESO release you will standardize on, the API version of the ExternalSecret, SecretStore and ClusterSecretStore resources, the CRD names and the provider list against the ESO documentation. No ESO-specific source was supplied for this page, so none of those details should be taken from memory. Confirm also how your ESO version handles Argo CD's health checks for these custom resources, because Argo CD needs to understand their status before it can report the application as Healthy. Plan the layout early: decide which team owns each SecretStore and whether stores are cluster-wide or namespace-scoped, since that choice determines who can read which remote secrets.

The practical checks are: confirm that no Git path or Helm values file holds a literal secret value, confirm that the Argo CD service account cannot read the Kubernetes Secrets that ESO creates unless a role explicitly allows it, and confirm that the ESO controller's own identity to the provider is scoped to the secrets each cluster needs. Each provider has its own authentication and quota model, and the cost and throttling behavior of the store you choose will shape how often ESO refreshes. Review those limits per provider before you set refresh intervals, and ask your team and any partner to write the refresh and rotation plan into the scope.

What you need in place before connecting Argo CD to a secret store

Argo CD only deploys ExternalSecret references in this design, so the work starts with the platform underneath it: a supported Argo CD version, a destination cluster with External Secrets Operator, a store account the cluster can use, and a network path to that store. Each item below is a decision to confirm before the first sync.

Supported Argo CD version

Only the three most recent minor versions receive patch releases, so pick a minor line that is still patched and plan to move to the next one within that window. Confirm the exact patch level against the release page before you pin it. Check that your Argo CD version matches the ExternalSecret manifests and the Argo CD health checks you plan to rely on, since the sync and health behavior you test must be the behavior you run in production.

Repositories defined as Secrets

Argo CD 3.0 removed repository configuration from the argocd-cm ConfigMap, so every Git repository that holds ExternalSecret manifests must be registered as a Kubernetes Secret. If you are upgrading from 2.14, move those definitions before you cut over, or the Application sources will not resolve. Keep the repository Secrets themselves out of the Git repositories they describe.

Who can see generated Secrets

The 2.14 to 3.0 changes limit update and delete RBAC to the application itself and require an explicit logs, get permission for log access. Test with a non-admin account that the people who may view Application resources can still see the Kubernetes Secrets that ESO produces, and that people who should not see them cannot. Review project roles before adding ExternalSecret resources, because a role that can read Secrets in the destination namespace can read synced values.

External Secrets Operator on the destination cluster

ESO must run on each destination cluster that will read from the store, with its CRDs installed before the first ExternalSecret sync. Argo CD should manage ESO's ExternalSecret and SecretStore resources as a separate application that syncs ahead of the workloads that consume the Secrets. Confirm the ESO version and its supported Kubernetes versions with the project before you choose a chart version.

Store account and auth method

The cluster needs a workload identity or auth method for the store, such as an IAM role for a service account on AWS, a managed identity on Azure, a service account identity on Google Cloud, or a Vault auth method. Ask the store owner which identity the cluster will use, which secret paths it may read, and whether read access is scoped per environment. Confirm these answers in writing before you create the SecretStore, because the scope of that identity sets the blast radius of any compromised cluster.

Network path to the store endpoint

Test that every destination cluster can reach the store's API endpoint over the route your network policy allows, including DNS resolution and any private endpoint or proxy in between. Segmented clusters often need an explicit egress rule for ESO's pods. Run this test from inside the cluster, not from a workstation, because a successful test from an administrator laptop says nothing about the ESO controller's path.

Choosing the source store for AWS, Azure, Google Cloud or Vault

AWS Secrets Manager charges by the secret and by the number of API calls, so cost grows with both the number of secrets your clusters read and how often they read them. Per the AWS pricing page, each secret costs $0.40 per month and every 10,000 API calls costs $0.05, with no upfront costs or long-term contracts. Reads made by External Secrets Operator on every refresh interval count toward the API charge, so refresh frequency is a direct cost lever.

  • Per-secret charge: Each stored secret is billed monthly, so consolidating values into fewer secrets reduces this line but may affect how access is scoped.
  • Per-call charge: Every 10,000 API calls is billed separately, so short refresh intervals across many clusters multiply the cost.
  • Batch size: BatchGetSecretValue retrieves up to 20 secrets per call, which can reduce request volume when many secrets are read together.
  • Batch limit: Batch calls are limited to 100 requests per second per Region, and cross-account requests can be throttled for the calling account.
  • Audit trail: CloudTrail logs a GetSecretValue entry for each secret returned by a batch call, so audit volume follows the number of secrets read, not the number of calls.

Confirm the refresh interval, the number of clusters and the expected secret count before you estimate spend, and check the current quotas on the AWS quotas page.

Configuration sequence for ExternalSecret delivery through Argo CD

This sequence moves secret values out of Git and into the destination cluster, where External Secrets Operator reads them from your secret store. Argo CD deploys only the ExternalSecret references, and each step ends with a check you can run before moving on.

  1. Install External Secrets Operator through Argo CD

    The platform team adds External Secrets Operator to the destination cluster as its own Argo CD Application, sourced from the chart or manifests you approve and pinned to a specific version. Keep this application separate from the workloads that consume secrets so the operator can be upgraded on its own schedule. The step is done when the operator's Deployment is running in its namespace and the Application shows Healthy and Synced in the Argo CD UI or through the CLI. If the Application stays Progressing, check the operator's CRDs first, because the ExternalSecret and SecretStore resources depend on them.

  2. Create the cluster-side store authentication

    Configure how the cluster proves its identity to your secret store, using the workload identity, IAM role, managed identity or Vault auth method your platform already supports. Confirm the exact authentication mechanism and its permissions with the store owner and with the External Secrets Operator documentation for your provider. Create the credentials reference as a Kubernetes object managed outside the Git path that Argo CD syncs, or through an identity mechanism that stores no long-lived secret. Check it by confirming the identity can read one non-production test secret, since a failed read here is the most common reason later steps fail.

  3. Define a SecretStore or ClusterSecretStore

    Create a SecretStore for a single namespace or a ClusterSecretStore when several namespaces share one backend, pointing at the provider, region or vault URL, and the authentication from the previous step. Illustrative example: a ClusterSecretStore named platform-secrets that points at one AWS Region and uses a service account bound to a read-only policy. Commit this manifest to Git through an Argo CD Application scoped to the platform project. Check the store's status condition for Ready, which confirms the operator could connect and authenticate.

  4. Write ExternalSecret references to store paths

    Define each ExternalSecret so it names the store, the remote path or key in your backend, and the target Kubernetes Secret it should create. Use only paths and property names in the manifest, never the secret value itself. Illustrative example: an ExternalSecret named payments-db that maps the password property at a path such as prod/payments/db into a Secret called payments-db-credentials. Set refresh behavior deliberately, because refresh interval controls how quickly rotated values reach the cluster and how many API calls your provider receives. Validate the manifest with a dry run before committing it.

  5. Commit ExternalSecret manifests and let Argo CD sync them

    Add the ExternalSecret manifests to the Git path that the consuming application's Argo CD Application watches, and let auto-sync or a reviewed manual sync apply them. Because Git holds only references, reviewers can approve changes to paths and refresh behavior without seeing values. Confirm the Application reaches Synced and Healthy, and that Argo CD reports the ExternalSecret resource as healthy. If the Application shows OutOfSync repeatedly after the operator writes the Secret, check whether Argo CD is tracking fields the operator manages, and confirm the resource tracking method used by your Argo CD version.

  6. Confirm the generated Secret exists

    Check the ExternalSecret status condition for Ready, then confirm the target Kubernetes Secret exists in the expected namespace with the expected keys. Do not print secret values in terminal output or logs. Check key names, creation timestamp and the labels or owner references the operator sets. A missing Secret with a Ready condition usually points to a target name or template mismatch in the manifest, so compare the spec with what was created.

  7. Verify a workload consumes the synced value

    Deploy or restart a test workload that mounts the Secret as an environment variable or file, and confirm the pod reaches Running and passes its readiness check. Prove the value arrived by having the application perform a harmless authenticated call, not by printing the secret. Then rotate the test value in the backend and confirm the refresh interval updates the Secret, noting that many workloads only read mounted files or environment variables after a restart. Record the store, ExternalSecret and Application versions so the configuration can be reproduced during audits or recovery.

Mapping Argo CD applications, ExternalSecrets and store paths

This table maps each object in the chain, from the Argo CD Application down to the Kubernetes Secret workloads read, to its owner, purpose and change control. Read it as a responsibility map: the platform team owns the store and its access, while application teams own only the ExternalSecret references that Argo CD deploys. The main takeaway is that a store path change can alter live values, so it should sit with the platform team and pass through the same Git review as other manifests.

ObjectOwner and purposeWho may change the store pathRefresh interval and tracking
Argo CD ApplicationApplication team; points Argo CD at the Git path that holds the ExternalSecret manifestsApplication team edits the Git path; project policy limits which repositories and destinations applySync policy set per application; not a secret refresh setting
Argo CD projectPlatform team; defines allowed source repositories, destination clusters and namespaces for the applicationPlatform team only, through reviewed changes to the AppProjectNot applicable; scopes what the Application may deploy
ESO SecretStore (namespace scoped)Platform or team owner; holds the provider connection and authentication method for one namespacePlatform team; restrict through Git review and admission controlsNot applicable; connection settings are read when ESO reconciles
ExternalSecretApplication team; maps remote secret names and keys to a target Kubernetes SecretApplication team for keys and target names; store path changes need platform approvalrefreshInterval field on the resource; confirm the value against your ESO version and change window
External secret name and versionSecret owner in the provider; ESO reads the current version unless a version is pinnedProvider administrators and rotation automation; not Argo CDVersions change in the provider; pinning or rotation timing should be confirmed with your ESO version
Target Kubernetes SecretCreated and updated by ESO; consumed by workloads in the same namespaceESO controller only; manual edits are overwritten on the next syncCarries tracking metadata that determines whether Argo CD treats it as managed or as an orphan
RBAC role that reads the SecretCluster administrator; grants get or list on Secrets to workload service accounts and humansCluster administrators through reviewed RBAC manifestsNot applicable; Argo CD 3.0 requires explicit logs and get permissions for logs access, not Secret reads

How refresh intervals and health checks change cost and reliability

Every refresh an External Secrets Operator (ESO) controller performs is a read against your secret store, so the recurring read volume is set by three things: how many ExternalSecret objects exist, how many clusters read from the same store, and how often each one refreshes through its refreshInterval. Shortening the interval from a few minutes to a few seconds multiplies calls without adding any value for secrets that change once a quarter. For AWS Secrets Manager, the supplied list prices are $0.40 per secret per month and $0.05 per 10,000 API calls. Illustratively, 200 secrets refreshed every minute across three clusters would make roughly 864 million calls a month, while the same secrets refreshed hourly would make about 14 million. Real totals depend on your configuration, including the batching you use, so model your own refresh schedule before you choose intervals.

Argo CD should treat an ExternalSecret as healthy only when its status reports the Ready condition, because that is the signal that the target Kubernetes Secret was created or updated from the store. Without that check, an Application can show Synced and Healthy while the secret it depends on is missing, expired or failing to authenticate. Argo CD does not know the semantics of ESO custom resources by default, so the health logic is usually added as a resource health customization in the argocd-cm ConfigMap. Confirm the exact customization format, the resource group and the Lua health script against the current Argo CD documentation for your version before you adopt it, and test it against a deliberately broken store reference in a non-production cluster.

Rotation happens in the store, not in Git or in Argo CD. For AWS Secrets Manager, managed rotation or a Lambda rotation function changes the secret value and the dependent service, and ESO picks up the new value on its next refresh. The reliability question is therefore the gap between rotation and refresh: a long refreshInterval delays pods that depend on the new value, while a workload that reads the Kubernetes Secret only at startup will keep the old value until it restarts. Decide per workload whether a restart is part of rotation, and confirm with your application owners how they reload credentials. Also check the store's own limits, such as the AWS quota of 10,000 GetSecretValue requests per second per Region, before you set fleet-wide refresh rates.

Security controls for ExternalSecret deployments

With External Secrets Operator, Argo CD deploys only ExternalSecret references, but the store credential, the admin account, the projects that can ship those references and the repo-server still decide who can reach real secret values. The cards below cover the controls that connect those pieces, and what to check in each one.

Keep the store credential out of Git

The ESO SecretStore or ClusterSecretStore needs a credential or workload identity to read your external store. Create that credential on the cluster, never as a manifest in the Git repository Argo CD watches. Scope it to the narrowest read permission per path or prefix, so a compromised namespace reads only its own secrets. Check that the store's read policy names specific secret paths for each environment, and that no wildcard grants read access to every secret in the account or vault.

Disable the built-in admin user

The built-in admin account is intended for first-time setup. After SSO or local users are working, set admin.enabled to false in the argocd-cm ConfigMap so no shared password can sync an ExternalSecret or read a generated Secret. Confirm that at least one named administrator can still log in through SSO before you disable it, and keep a documented break-glass path that does not depend on the identity provider being available.

Restrict projects and target namespaces

An Argo CD AppProject controls which repositories, clusters and namespaces an application may deploy to. Limit which projects may create ExternalSecret resources and which namespaces those resources may target, so a team cannot point a manifest at another team's namespace and receive secrets there. Review the project's allowed resource kinds as well, because a project that can create ExternalSecrets in any namespace can also pull values from any store it can reference.

Limit repo-server exposure to untrusted repositories

The repo-server runs Helm and Kustomize against repository content. A chart or overlay from an untrusted source can read files outside its directory or reach resources the project should not touch. Allow only approved repositories in each project, and use Kustomize or Helm settings that block out-of-tree file access. Confirm that ExternalSecret templates in shared charts come from repositories your security team reviews.

Confirm TLS and credential redaction

Argo CD uses TLS for traffic between its components, and it redacts cluster, Git and OAuth2 credentials from API responses and logs. Verify this on your own installation: check that the API and component endpoints present valid certificates, and search API output and controller logs for the store credential after a test sync. Treat any match as a defect to report, and do not assume redaction covers credentials that ESO or a plugin introduces.

Restrict who reads generated Secrets

ESO writes the synced values into ordinary Kubernetes Secrets. Anyone who can read those Secrets through RBAC can read the secret values, so limit get, list and watch on Secrets to the workloads and operators that need them. Argo CD's logs permission is separate: since the 2.14 to 3.0 change, reading application logs needs an explicit logs get permission. Grant it only to people who need pod logs, because application logs can expose values an application writes to stdout.

Common failures when syncing secrets with External Secrets Operator

This table pairs each common failure in an External Secrets Operator setup for Argo CD with its likely cause, the first diagnostic step and the fix. Read it by symptom: the early rows check the store connection and refresh behavior, and the later rows check Argo CD health, tracking and RBAC. The main takeaway is that most failures sit in store identity, refresh rates or Argo CD settings, not in the Git manifests.

FailureLikely causeDiagnostic stepFix
ExternalSecret stays not readyThe controller's identity on the store lacks read permission for the secret or its pathDescribe the ExternalSecret and its SecretStore, read the status conditions, then test a read with the same identityGrant read access on the specific secret path to the controller's role or workload identity, then confirm the condition reports ready
Argo CD shows Progressing or Degraded for a Secret that looks healthyArgo CD health is evaluated on the ExternalSecret resource, which lags or reports an error even though the target Secret existsCompare the ExternalSecret status with the Secret in the target namespace, and check any ExternalSecret health customization in argocd-cmCorrect the ExternalSecret status issue, or add a custom health check under resource.customizations that reads the sync condition, after confirming the rule against your Argo CD version
Throttling from batch or cross-account callsMany ExternalSecrets refreshing at the same time, or batch and cross-account reads that exceed AWS per-Region limitsCheck controller logs for throttling messages and review GetSecretValue volume per account in CloudTrailLengthen and stagger refresh intervals, group reads per store, and confirm with AWS which limits can be raised for your account
Deleted store secret still in a recovery windowThe source secret was deleted in AWS or soft-deleted in Key Vault, so reads fail while the object remains recoverableCheck the deletion state in the store: scheduled deletion in AWS Secrets Manager or a soft-deleted object in Key VaultRestore the secret before the window ends, or point the ExternalSecret at a new secret name and confirm the change in Git
Vault license or backend limit blocks a planned featureA design feature such as replication, namespaces, HSM support or seal wrapping needs a Vault Enterprise license, or the chosen storage backend has limited supportCompare each planned feature against the Vault Enterprise feature list and the storage backend documentation before the build startsConfirm licensing with the vendor, choose a supported backend such as integrated storage, or validate OpenBao separately because its migration guide was tested only against Vault 1.14.1 Community Edition
Generated Secrets removed by Argo CDThe target Secret carries Argo CD tracking labels or annotations copied from the ExternalSecret template, so Argo CD treats it as managedInspect the Secret's labels and annotations, and confirm the tracking method set for the Argo CD instance, which defaults to annotation-based trackingRemove copied tracking metadata from the template, keep generated Secrets out of Git, and set the ESO creation and deletion policies on purpose
Argo CD 3.0 RBAC hides Secret or logs views from existing usersUpdate and delete rules now apply only to the Application itself, logs access needs an explicit logs get permission, and Dex RBAC uses the federated_claims.user_id claimRun argocd account can-i for logs and get on the Application, then review policy.csv and the SSO claim mappingAdd explicit logs get and update or delete rules for the Application, remap SSO claims, and test these rules in a non-production instance before upgrading

Questions buyers ask before connecting Argo CD to a secret store

What does it cost to run Argo CD with External Secrets Operator against a cloud secret store?

Argo CD and External Secrets Operator are open-source software, so the recurring cost is the secret store itself and the calls made to it. For AWS Secrets Manager, the pricing page lists $0.40 per secret per month and $0.05 per 10,000 API calls, with no upfront costs or long-term contracts. For Azure Key Vault, the Azure Retail Prices API lists secret operations in East US at $0.03 per 10,000 operations on Standard and Premium tiers. Refresh interval is the main lever: a short interval across many secrets and clusters multiplies API calls. Ask for a quote that lists the store, secret count, clusters, refresh interval and any HSM or managed key costs, which are billed separately. DeployOpen's fees follow from the written scope.

How long does a typical External Secrets Operator setup take?

Duration depends on the work, not on a fixed template, so no timeline applies until the scope is written. The main drivers are the number of secret stores and providers, the number of clusters that need access, how many namespaces and secret paths follow your naming model, and how many approval steps your change process requires. Cloud IAM reviews and store owner sign-off often take longer than the configuration itself. A single store and one cluster with a clear ownership model is the simplest case. Ask for a schedule that breaks the work into store access, cluster installation, ExternalSecret templates, refresh tests and handover.

What does the client team need to provide for this integration?

The work needs access from several owners before engineering starts. Store owners must agree on secret paths, naming and which secrets each environment may read. Cloud or identity administrators must create the IAM roles or workload identities that the operator uses, with read permissions limited to the secrets in scope. Platform engineers need access to the Git repository that holds the Argo CD applications and to the destination clusters, where the operator and its authentication configuration are installed. Security reviewers should confirm how refresh failures and rotations are monitored. Confirm each of these owners before the scope is signed.

Can our team set up Argo CD with External Secrets Operator without outside help?

Yes, a capable platform team can build this internally, and the project documentation covers installation and resource definitions. The harder parts are usually the cross-team decisions and the operational checks: least-privilege IAM for each cluster, a clear model for secret paths, and tests that confirm a rotated value reaches the workload. Teams that have not run an operator with cloud credentials before often spend the most time on authentication and error handling. An outside partner is useful when you want the design, the tests and the runbooks written to a fixed scope, with your team trained to operate them.

How do I choose between External Secrets Operator, Vault Secrets Operator and the Secrets Store CSI Driver?

The choice follows where your secrets live and how workloads consume them. External Secrets Operator syncs values from AWS Secrets Manager, Azure Key Vault, Google Secret Manager or Vault into Kubernetes Secrets, which suits workloads that read environment variables or standard Secret volumes. Vault Secrets Operator is the better fit when Vault or OpenBao is already the system of record. The CSI driver mounts secrets directly into pods and avoids creating a synced Secret object, which can matter for strict exposure rules but adds a mount dependency. Check which provider your store owners already run, whether your workloads need synced objects, and how each option fits your audit evidence.

What does a fixed-scope External Secrets Operator engagement include?

A fixed-scope engagement covers the agreed deliverables, written before work starts. For this integration that typically means the store and identity design, the Argo CD application layout that deploys only ExternalSecret references, the operator installation on the chosen clusters, refresh and health checks, and handover documentation. Scope lists the stores, providers, clusters and environments included, and exclusions such as secret migration or store administration. Ongoing support, upgrades and continuous testing are available as retainers. Quotes follow from the written scope, so the scope document is the place to confirm what is in and out.

How DeployOpen works on this

DeployOpen plans, implements, documents and supports self-hosted open-source platforms inside your own infrastructure. For Argo CD with External Secrets Operator, we scope the secret stores, cluster authentication and refresh design in writing, then build and test the ExternalSecret layout in the clusters you control.

How we scope

  • Written scope lists the secret stores, clusters, namespaces and Argo CD projects covered by the engagement.
  • We record which provider you use, how clusters authenticate to it, and who owns each secret path.
  • Engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts.
  • Cost drivers such as request volume, secret counts and HSM or managed-key choices are reviewed before quoting.

How we build

  • We set up External Secrets Operator on the destination clusters and define ClusterSecretStore resources for each provider.
  • Argo CD applications deploy only ExternalSecret references, with the layout, refresh intervals and health checks agreed in scope.
  • We test refresh behavior, failed-sync handling and secret rotation in a non-production cluster before promotion.
  • Access to Argo CD, the operator and the provider is reviewed against least privilege and the project boundaries you set.

How we hand over

  • Handover documentation covers the secret layout, store configuration, authentication model and refresh settings.
  • Runbooks describe how to rotate a secret, add an environment, and diagnose a store that stops syncing.
  • Your team receives the configuration as code in your own Git repositories, with the operator's version pinned.
  • We walk your engineers through verification steps so they can confirm health after each change.

How we support

  • Ongoing support, operator and Argo CD upgrades, and continuous testing are available as retainers.
  • Upgrade work checks External Secrets Operator and Argo CD release notes before each version change.
  • Retainer scope is agreed in writing, including which clusters, stores and environments it covers.
  • Confirm your provider's current quotas, pricing and support terms directly with the vendor before finalizing the scope.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.