Skip to main content

Overview

ArgoCD renders Helm templates client-side before applying them to the cluster. Helm’s lookup 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

Secret KeyPurposeGeneration
SECRET_KEY_BASERails session signing and encryptionrandAlphaNum 64
ENCRYPTION_KEYApplication-level data encryptionHex (64 chars via sha256sum)
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEYRails Active Record encryptionrandAlphaNum 64
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEYRails deterministic encryptionrandAlphaNum 64
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALTRails encryption key derivationrandAlphaNum 64
REGISTRY_HTTP_SECRETInternal container registry authrandAlphaNum 32
CREWAI_PLUS_INTERNAL_API_KEYService-to-service authenticationrandAlphaNum 64
If any Active Record encryption key changes, all previously encrypted data becomes unreadable. This includes encrypted database columns that Rails cannot decrypt with new keys. Always pre-set these values before your first deployment.
Generate stable values and set them explicitly in your Helm values file. This bypasses lookup and randAlphaNum entirely.

Generate Secret Values

The easiest approach is to let the chart generate the values for you. Run helm 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:
helm template crewai-platform <chart> --values my-values.yaml \
  | yq 'select(.kind == "Secret" and (.metadata.name | contains("-secrets"))) .data
        | to_entries | .[]
        | .key + ": " + (.value | @base64d)' \
  | grep -E '^(SECRET_KEY_BASE|ENCRYPTION_KEY|ACTIVE_RECORD_ENCRYPTION_|REGISTRY_HTTP_SECRET|CREWAI_PLUS_INTERNAL_API_KEY)'
Replace <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

secrets:
  SECRET_KEY_BASE: "<from output above>"
  ENCRYPTION_KEY: "<from output above>"
  ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY: "<from output above>"
  ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY: "<from output above>"
  ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT: "<from output above>"
  REGISTRY_HTTP_SECRET: "<from output above>"
  CREWAI_PLUS_INTERNAL_API_KEY: "<from output above>"
Store these values in a sealed secret, SOPS-encrypted file, or your CI/CD platform’s secret management — never commit them to version control in plaintext.
If you prefer to generate values independently of the chart:
# Rails secret key base
openssl rand -base64 48 | tr -d '\n'

# Encryption key (hex format)
openssl rand -hex 32

# Active Record encryption keys (run 3 times, one for each key)
openssl rand -base64 48 | tr -d '\n'

# Registry HTTP secret
openssl rand -base64 24 | tr -d '\n'

# Internal API key
openssl rand -base64 48 | tr -d '\n'

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:
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  ignoreDifferences:
    - group: ""
      kind: Secret
      name: crewai-platform-secrets
      jsonPointers:
        - /data
This only works if the Secret already exists from a prior install. On a fresh deployment through ArgoCD, the first sync will still generate random values — and those values will persist. However, any intentional secret changes in your values file will also be ignored. Pre-setting secrets is the more reliable approach.

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:
secrets:
  SSL_PRIVATE_KEY: |
    -----BEGIN PRIVATE KEY-----
    ...
    -----END PRIVATE KEY-----
  SSL_CERTIFICATE: |
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
Or use cert-manager or your cloud provider’s certificate management instead of web.tls.autoGenerate.