Overview
ArgoCD renders Helm templates client-side before applying them to the cluster. Helm’slookup function — which the chart uses to persist auto-generated secrets across upgrades — always returns an empty result in client-side rendering. This means every ArgoCD sync generates new random values for auto-generated secrets, breaking Rails database encryption and session continuity.
Affected Secrets
OIDC_PRIVATE_KEY is the only secret requiring block scalar YAML syntax because it is a multi-line RSA PEM string. All other secrets are single-line alphanumeric values. See the Configure in Values example — the
| character on the OIDC_PRIVATE_KEY line is required.OIDC_KEY_ID and OIDC_PRIVATE_KEY must be rotated together. Changing one without the other breaks Workload Identity trust relationships (AWS IAM OIDC, GCP Workload Identity, Azure Federated Credentials) that pin to the key ID.Recommended: Pre-Set All Secrets
Generate stable values and set them explicitly in your Helm values file. This bypasseslookup and randAlphaNum entirely.
Generate Secret Values
The easiest approach is to let the chart generate the values for you. Runhelm template with your values file — since it renders client-side (just like ArgoCD), the chart’s auto-generation logic produces random secrets that you can extract and pin:
<chart> with the path to the chart (e.g., ./helm or an OCI reference). This requires yq — install with brew install yq, snap install yq, or see the yq docs.
This prints the auto-generated values in plain text. Copy them into your values file:
Configure in Values
Alternative: generate with openssl
Alternative: generate with openssl
If you prefer to generate values independently of the chart. The
| tr -dc 'A-Za-z0-9' | head -c N filter mirrors the chart’s randAlphaNum
output exactly — pure alphanumeric, no +/= from base64 padding that would
otherwise drift from the values a non-ESO chart install produces.Using ESO with ArgoCD
For deployments that want the external store (AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, Vault) as the canonical source of truth, see the dedicated External Secrets Operator guide. It covers fresh installs, migration paths from inline secrets or partial ESO setups, the backend key reference, and the pre-upgrade wait Job. When using ESO with ArgoCD specifically, the pre-upgrade hook sequencing the chart relies on works the same way under ArgoCD’s sync — ArgoCD respects Helm hook annotations and applies resources in the correct phase order.Alternative: ArgoCD ignoreDifferences
You can configure ArgoCD to ignore changes to the Secret resource so that auto-generated values from the initial install are preserved:
Self-Signed TLS Certificates
The chart can auto-generate self-signed TLS certificates (web.tls.autoGenerate: true). These also use lookup for persistence and will regenerate on every ArgoCD sync.
If you use application-level TLS with ArgoCD, provide your own certificates:
web.tls.autoGenerate.
Cloud Provider Workload Identity: crewai-crews Namespace
GCP, Azure, and AWS (IRSA) all require thedefault ServiceAccount in the crewai-crews namespace to be annotated for Workload Identity (GKE), Azure Workload Identity (AKS), or IRSA (EKS). The chart creates this namespace via a Helm Job, so the namespace does not exist until after the first sync completes.
Two-Application pattern (recommended):
Create a separate ArgoCD Application that runs after the main CrewAI Application and applies only the SA annotation:
manifests/crewai-crews-sa/sa.yaml:
GCP (GKE Workload Identity):
For AWS IRSA, the IAM role trust policy must also include
system:serviceaccount:crewai-crews:default in addition to the annotation. See Post-Install: IRSA Trust Policy for Crew Build Pods.Dependency Ordering with Sync Waves
For deployments that require infrastructure dependencies (NGINX Ingress Controller, External Secrets Operator) to be ready before CrewAI starts, use multiple ArgoCD Applications with sync waves:pre-install, post-install) already sequence the DB migration job before the main web/worker deployments — no additional sync wave configuration within the chart is needed for internal ordering.
OIDC_PRIVATE_KEY in the secrets table requires block scalar YAML syntax because it is a multi-line RSA PEM string, unlike all other secrets in the table which are single-line alphanumeric strings. See the Configure in Values example above for the correct
| block scalar syntax.