The backend-credentials secret and the
ClusterSecretStore (Mode 1) apply to APC 2.0 and later. The ESO controller ServiceAccount, the Mode 2 cluster RBAC, the Mode 3 per-namespace RBAC, and the leader-election RBAC require APC 2.1 or later.provider block; for the Vault provider block and Vault-side setup, see Configure Hashicorp Vault for data plane failover. The manifests use two placeholders: <release-name> is the Helm release name you install the Astronomer chart with (for example astronomer), and <pool-namespace> is one of your pre-created namespace pool namespaces.
These manifests assume the platform is installed in the
astronomer namespace. If you installed it into a different namespace, replace astronomer in the manifests and the chart values accordingly.Install the ESO CRDs yourself
By default the APC chart installs the External Secrets Operator CRDs (external-secrets.crd.create: true). If you set external-secrets.crd.create: false — for example, when a separate infrastructure team owns CRD installation — install the CRDs yourself before you install or upgrade the platform.
The CRDs are published by the external-secrets project as a single CRD bundle. Apply the bundle whose tag matches the ESO version the APC chart ships, currently v2.7.0:
Backend credentials secret (Modes 1 and 2)
Create the backend credentials in the platform (astronomer) namespace. Skip this if you authenticate with workload identity instead of a credential pair.
ESO controller ServiceAccount (Modes 2 and 3)
In Modes 2 and 3, you create the ESO controller ServiceAccount yourself and disable the chart’s ServiceAccount creation, so the ServiceAccount and its RBAC exist before ESO starts. In Configure External Secrets Operator security, you setexternal-secrets.serviceAccount.create: false and external-secrets.serviceAccount.name to this ServiceAccount. Create it in the astronomer namespace:
eks.amazonaws.com/role-arn for AWS, iam.gke.io/gcp-service-account for GCP).
Secret store manifests (Modes 1 and 2)
Option A — cluster-scoped ClusterSecretStore (Modes 1 and 2)
auth block. AWS IRSA is shown. GCP and Vault use their provider’s equivalent auth:
<release-name>-external-secrets) is created during ESO setup — by the chart in Mode 1, or by you in Modes 2 and 3 (see ESO controller ServiceAccount). For workload identity, annotate it for your provider (eks.amazonaws.com/role-arn for AWS, iam.gke.io/gcp-service-account for GCP) — in Mode 1 through the chart’s external-secrets.serviceAccount.annotations value, or in Modes 2 and 3 directly on the ServiceAccount you create.
Option B — namespaced SecretStore synced by the platform (Mode 2 only)
Both the credentials secret and theSecretStore carry the astronomer.io/commander-sync annotation, which tells the platform to sync them into every Deployment namespace.
Static credentials onlyThis synced-
SecretStore option supports static credentials only. The platform copies the credentials Secret and the SecretStore into each Deployment namespace, so it can’t carry per-namespace workload-identity references. To use workload identity (AWS IRSA, GKE Workload Identity, or Vault Kubernetes auth) in Mode 2, use the cluster-scoped ClusterSecretStore (Option A) instead.Force-delete secrets in AWS Secrets Manager
AWS Secrets Manager soft-deletes secrets by default, keeping them recoverable for a 30-day window during which the secret name stays reserved. If the platform then tries to create a secret with the same name, the create conflicts with the still-recoverable secret. This can happen when you use custom release names and reuse a release name for a new Deployment after deleting the previous one. To make ESO hard-delete secrets instead, setforceDeleteWithoutRecovery on the AWS provider in your SecretStore or ClusterSecretStore:
ClusterSecretStore or SecretStore in Modes 1 and 2, or the per-namespace SecretStore in Mode 3. The ESO GCP Secret Manager and Azure Key Vault providers don’t expose an equivalent option: GCP Secret Manager deletes secrets immediately, so the conflict doesn’t arise, and Azure Key Vault’s soft-delete can’t be overridden from the store — on Azure you purge a deleted secret through Azure itself.
Mode 2: hardened ESO cluster RBAC
In Mode 2, you disable the ESO sub-chart’s default RBAC (external-secrets.rbac.create: false), then apply the ClusterRole and ClusterRoleBinding below. They grant ESO the same reconcile rules as the Mode 3 per-namespace Role, but cluster-scoped, and pin ServiceAccount token creation with resourceNames to ESO’s own ServiceAccount in the astronomer namespace. That pinned token-create serves the same purpose as in Mode 3: ESO assumes the shared identity by minting its own ServiceAccount’s token (the serviceAccountRef path) — required for Vault, and used by AWS or GCP workload identity through serviceAccountRef. It goes unused if you authenticate with static credentials.
In Mode 2 you apply this
ClusterRole and ClusterRoleBinding yourself. The chart doesn’t ship them, since external-secrets.rbac.create: false. The rules mirror the external-secrets Role, expressed as a cluster-scoped role with token creation pinned to the ESO ServiceAccount.clustersecretstores rules let ESO read the cluster-scoped store; include them when Mode 2 uses a ClusterSecretStore. If you use only the synced SecretStore (Option B), you can omit them.
config-syncer RBAC (Option B synced SecretStore)
The platform’s config-syncer component performs the Option B sync: it copies thecommander-sync-annotated credentials Secret and SecretStore from the astronomer namespace into each Deployment namespace, so it needs write access to secrets and secretstores in every target namespace. Mode 3 doesn’t use this component — there, each namespace has its own pre-provisioned SecretStore and nothing is synced.
The chart creates this RBAC automatically in a standard install. Provision the Role and RoleBinding below yourself only if you run with cluster-scoped roles disabled, so config-syncer isn’t otherwise granted namespace access. Create them in each Deployment namespace, binding the <release-name>-config-syncer ServiceAccount in astronomer.
Mode 3: per-namespace RBAC
In Mode 3 (customer-managed isolated identity), each Deployment gets its own backend identity, and you pre-provision per-namespace RBAC for every platform component that operates in the pool namespaces. This document covers the ESO and Commander RBAC. The remaining platform components — kube-state-metrics, the Houston DB bootstrapper hook, Prometheus, and NGINX — are covered in Component RBAC for restricted mode. Create these objects in theastronomer namespace and in each pool namespace, in addition to the standard namespace pools setup, and replicate them with matching namespace names on every cluster a Deployment can fail over to.
Each RoleBinding names the component’s ServiceAccount in the astronomer namespace as a cross-namespace subject. The chart installs those ServiceAccounts release-prefixed: <release-name>-external-secrets and <release-name>-commander.
Rather than hand-writing every object, you can generate the full set with the provided script. See Generate the platform RBAC. The manifests below are the reference for what that script produces.
Per-namespace ServiceAccount and SecretStore (isolated identity)
For isolated backend identity, pre-provision a ServiceAccount and a namespacedSecretStore that authenticates as it through workload identity in each pool namespace. In namespace pools you provision this chain when the namespaces are created, before any Deployment exists, so name the ServiceAccount after the pre-created pool namespace (shown here as <pool-namespace>-eso) rather than a Deployment ID, which isn’t yet known. Each pool namespace hosts one Deployment at a time, so a per-namespace identity is effectively per-Deployment. Annotate the ServiceAccount for your provider. Omit the annotation for Vault Kubernetes auth.
SecretStore the same in every pool namespace — the value of global.dataPlaneFailover.externalSecretManagerName (shown here as astronomer-secret-store). The name must be identical across namespaces. The provider block and identity can differ per namespace.
ESO Role and RoleBinding
Grants the ESO controller ServiceAccount the reconcile verbs it needs inside the namespace. Create it in theastronomer namespace and in each pool namespace.
Token-creation Role and RoleBinding
Required in Mode 3, for any backend: the per-namespaceSecretStore authenticates as the per-namespace ServiceAccount (auth.jwt.serviceAccountRef), so ESO must mint that ServiceAccount’s token to assume its identity — whether the backend is AWS (IRSA), GCP (Workload Identity), or Vault (Kubernetes auth). More broadly, ESO needs ServiceAccount-token creation whenever a store authenticates through a serviceAccountRef: always for Vault, and for AWS or GCP only when you authenticate with a ServiceAccount token (workload identity) rather than static credentials or the ESO controller’s own IRSA or GKE Workload Identity.
The RoleBinding subject is the ESO controller ServiceAccount (<release-name>-external-secrets in astronomer), because the controller is the process that calls the Kubernetes TokenRequest API. The rule’s resourceNames pins which ServiceAccount the controller may mint a token for — the per-namespace SA <pool-namespace>-eso — so it can assume that one identity and nothing else. Create the Role and RoleBinding alongside the ESO Role in each pool namespace.
Commander Role and RoleBinding
Create in theastronomer namespace and in each pool namespace, binding the <release-name>-commander ServiceAccount.
Generate the platform RBAC (Mode 3)
Mode 3 needs RBAC for every platform component that runs in the pool namespaces, not just ESO. Rather than hand-writing each object, generate the complete set with the provided script. It emits a single bundle that covers both the ESO-specific RBAC in this document and the namespace pools platform-component RBAC in Component RBAC for restricted mode:- ESO — the reconcile
RoleandRoleBindingand theresourceNames-pinned token-creationRoleandRoleBinding. - Commander — the per-namespace
RoleandRoleBinding. - kube-state-metrics — the per-namespace
RoleandRoleBinding. - Houston DB bootstrapper hook — a
RoleandRoleBindingcreated in theastronomernamespace only. - Prometheus — a cluster-scoped
ClusterRoleandClusterRoleBindingfor scrape access. - NGINX — a cluster-scoped
ClusterRoleandClusterRoleBinding, plus its namespaced configRoleandRoleBinding.
--release-name— the Helm release name of the platform. The script uses it to prefix every generated ServiceAccount,Role, andClusterRole(for example<release-name>-commanderand<release-name>-external-secrets).--release-namespace— the platform namespace (astronomer), where the component ServiceAccounts live. Every generatedRoleBindingnames them here as a cross-namespace subject.--namespaces— a comma-separated list of the namespaces to emit per-namespace RBAC for. Include the platform namespace and every pool namespace.
--installer-user instead:
SecretStore carry provider-specific identity, so the script doesn’t generate them — create those as shown in Per-namespace ServiceAccount and SecretStore (isolated identity).
Leader-election RBAC (optional ESO high availability)
To run the ESO controller with more than one replica for resiliency, enable leader election so only one replica reconciles secrets at a time. See Run ESO with multiple replicas. In Modes 2 and 3, where you manage ESO’s RBAC, create the leader-election Role and RoleBinding in theastronomer namespace, binding the ESO ServiceAccount: