Autonomize · Genesis Downloads

Genesis Downloads · Secrets management

Secrets management

Genesis reads every credential from a single Kubernetes Secret named ai-studio-secrets — 44 keys in total: 34 required plus 10 optional, feature-gated ones. This page is the complete inventory, the four ways to populate it, and the rotation cadence per key class.

Scope — this is one of two Secrets ai-studio-secrets is the platform credential bundle that every application pod reads. A second, much smaller Secret — customer-genesis-secrets — carries the PostgreSQL admin password and the OIDC client-secret reference used by the ops chart, not by application pods. It is covered in the install guide alongside the ExternalSecret templates for all three clouds.

Backend choices

The umbrella chart supports four supply paths for ai-studio-secrets. Pick one.

BackendWhen to chooseSetup
ESO + Azure Key Vault Azure customers — the default global.secrets.externalSecrets.enabled: true, global.secrets.azure.vaultUrl, Workload Identity wired
ESO + AWS Secrets Manager AWS customers global.secrets.externalSecrets.enabled: true, global.secrets.aws.region, IRSA wired
ESO + GCP Secret Manager GCP customers global.secrets.externalSecrets.enabled: true, GKE Workload Identity wired
Manual K8s Secret Air-gapped clusters, dev clusters, no ESO global.secrets.externalSecrets.enabled: false — you pre-create ai-studio-secrets yourself
What ESO mode renders With externalSecrets.enabled=true the umbrella renders one ExternalSecret and one SecretStore per release, mapping each key from your backend into ai-studio-secrets. No client secrets are stored in the cluster — the SecretStore authenticates with workload identity.

Key inventory — 44 keys: 34 required, 10 optional

The mapping is defined in the umbrella chart's values.yaml under secrets.data. Convention: vault keys are kebab-case, Kubernetes Secret keys are snake_case. The platform reads only the Kubernetes side.

This is the chart's full mapping These counts are the umbrella chart's shipped secrets.data. A deployment may legitimately override it with a smaller subset — pinning the mapping to the keys a particular vault actually holds, so the all-or-nothing sync cannot stall on a key nobody provisioned. If you do that, every reference you drop must stay optional: true on the consuming service.
CategoryKeysRequired when
Database & cache3Password auth / Redis AUTH enabled
Application encryption & sessions6Always
Keycloak / OIDC6Always
Keycloak SMTP8Keycloak sends user email — all 8 together
Azure services, Marketplace & AD federation8Per feature — the 2 Marketplace keys are optional
Gateway, service auth & data stores6Always, except the optional QDRANT_API_KEY
Observability & web tools5Optional — per feature
Optional — LLM providers2Optional — per enabled provider
Total4434 required, 10 optional

Database & cache — 3 keys

Vault keyK8s keyRequired whenDescription
DB-USERDB_USERglobal.database.authMethod: passwordPostgres app user — omit for managed identity
DB-PASSWORDDB_PASSWORDglobal.database.authMethod: passwordPassword for DB_USER — omit for managed identity. Must be alphanumeric.
REDIS-PASSWORDREDIS_PASSWORDglobal.redis.auth: trueRedis AUTH password

Application encryption & sessions — 6 keys

All six are required in every deployment.

Vault keyK8s keyDescription
SECRET-KEYSECRET_KEYFastAPI session-signing key (32 random bytes. Generate with openssl rand -base64 32)
AUTH-SECRETAUTH_SECRETAuth.js / NextAuth session secret on genesis-fe. Generate with openssl rand -hex 33 | head -c 64
CREDENTIAL-ENCRYPTION-KEYCREDENTIAL_ENCRYPTION_KEYAES-256 key wrapping connector credentials at rest. Generate with openssl rand -base64 32.
CREDENTIALS-ENCRYPTION-KEYCREDENTIALS_ENCRYPTION_KEYPlural alias of the above (legacy compatibility). Keep both; the same value is fine
SECURITY-ENCRYPTION-KEYSECURITY_ENCRYPTION_KEYAES-256 key wrapping organization-scoped secrets in Postgres. Generate with openssl rand -hex 33 | head -c 64
SECURITY-ENCRYPTION-SALTSECURITY_ENCRYPTION_SALTSalt used by SECURITY_ENCRYPTION_KEY. Generate with openssl rand -hex 33 | head -c 32
Escrow these before install The three encryption keys wrap data at rest in PostgreSQL. Lose them and every stored connector credential and organization-scoped secret becomes unrecoverable — there is no recovery path. Put them in a sealed envelope or hardware token before you go to production, and see Rotation before you ever change them.

Keycloak / OIDC — 6 keys

Vault keyK8s keyRequiredDescription
AUTH-KEYCLOAK-SECRETAUTH_KEYCLOAK_SECRETAlwaysAuth.js client secret for genesis-fe ↔ Keycloak. Generate with openssl rand -hex 33 | head -c 64
KEYCLOAK-CLIENT-SECRETKEYCLOAK_CLIENT_SECRETAlwaysOIDC client secret for backend services. Generate with openssl rand -hex 33 | head -c 64
KEYCLOAK-FRONTEND-CLIENT-SECRETKEYCLOAK_FRONTEND_CLIENT_SECRETAlwaysBrowser-facing OIDC client secret. Generate with openssl rand -hex 33 | head -c 64
KC-BOOTSTRAP-ADMIN-USERNAMEKC_BOOTSTRAP_ADMIN_USERNAMEFirst install onlyInitial Keycloak admin username (must be set to "admin").
KC-BOOTSTRAP-ADMIN-PASSWORDKC_BOOTSTRAP_ADMIN_PASSWORDFirst install onlyInitial Keycloak admin password (must be alphanumeric.).
KC-SPI-EVENTS-LISTENER-GENESIS-AUTHZ-EVENT-LISTENER-INTERNAL-API-KEYKC_SPI_EVENTS_LISTENER_GENESIS_AUTHZ_EVENT_LISTENER_INTERNAL_API_KEYAlwaysShared secret on the Keycloak → genesis-authz event-sync webhook. Generate with openssl rand -hex 33 | head -c 64

Keycloak SMTP — 8 keys

Required when Keycloak sends user email (verification, password reset). Set all eight together — Keycloak fails if any one is missing.

Vault keyK8s keyDescription
KC-SMTP-HOSTKC_SMTP_HOSTSMTP server hostname
KC-SMTP-PORTKC_SMTP_PORTUsually 587 (STARTTLS) or 465 (SSL)
KC-SMTP-USERKC_SMTP_USERSMTP username
KC-SMTP-PASSWORDKC_SMTP_PASSWORDSMTP password
KC-SMTP-FROMKC_SMTP_FROMFrom address — must be authorized by your SMTP relay
KC-SMTP-FROM-DISPLAY-NAMEKC_SMTP_FROM_DISPLAY_NAMEDisplay name shown to recipients
KC-SMTP-SSLKC_SMTP_SSL"true" for implicit SSL (port 465), else "false"
KC-SMTP-STARTTLSKC_SMTP_STARTTLS"true" for STARTTLS (port 587), else "false"

Azure services, Marketplace & AD federation — 8 keys

Azure-managed services — 3 keys

Vault keyK8s keyRequired when
AZURE-OPENAI-API-KEYAZURE_OPENAI_API_KEYAzure OpenAI is the LLM backend
AZURE-DOCUMENT-INTELLIGENCE-KEYAZURE_DOCUMENT_INTELLIGENCE_KEYDocument Intelligence component used
AZURE-SEARCH-API-KEYAZURE_SEARCH_API_KEYSearch component used

(Optional) Azure Marketplace — 2 keys

Consumed by genesis-tenant-mgmt for Azure Marketplace SaaS Fulfillment v2.

Vault keyK8s keyRequired whenDescription
AZURE-MARKETPLACE-CLIENT-SECRETAZURE_MARKETPLACE_CLIENT_SECRETSaaS billing via Azure MarketplacePublisher AAD app secret from Partner Center technical configuration
AZURE-MARKETPLACE-WEBHOOK-SECRETAZURE_MARKETPLACE_WEBHOOK_SECRETFuture useOperator-generated random value, reserved for webhook validation

Azure AD federation — 3 keys

These configure end-user SSO via Azure AD as a Keycloak identity provider.

Vault keyK8s keyDescription
AZURE-AD-CLIENT-IDAZURE_AD_CLIENT_IDApp registration client ID
AZURE-AD-CLIENT-SECRETAZURE_AD_CLIENT_SECRETApp registration client secret
AZURE-AD-TENANT-IDAZURE_AD_TENANT_IDTenant ID (GUID)
Not the same as Workload Identity Cluster Workload Identity is configured separately via global.serviceAccount.azure.*. The AZURE_CLIENT_ID / AZURE_TENANT_ID env vars it uses are deliberately not in this inventory — the Workload Identity webhook injects them into pods labelled azure.workload.identity/use=true. The split avoids a collision with the AD-federation values above.

Gateway, service auth & data stores — 6 keys

Vault keyK8s keyRequired whenDescription
APISIX-ADMIN-KEYAPISIX_ADMIN_KEYAlwaysBearer token for the APISIX Admin API. Generate with openssl rand -hex 33 | head -c 64
INTERNAL-API-KEYSINTERNAL_API_KEYSAlwaysPlatform-internal service-to-service API keys. Format is a JSON array — and it needs to include the value for GENESIS-API-KEY in the array.
GENESIS-API-KEYGENESIS_API_KEYAlwaysDefault platform API key, also used by genesis-authz internal calls. Generate with openssl rand -hex 33 | head -c 64
JWT-SECRETJWT_SECRETAlwaysSymmetric secret for internal JWT signing fallback (HS256). Production prefers JWKS via Keycloak. Generate with openssl rand -hex 33 | head -c 64
ADMIN-PASSWORDADMIN_PASSWORDAlwaysInitial platform admin password.
QDRANT-API-KEYQDRANT_API_KEYOptional: only needed when Qdrant cluster auth enabled.Qdrant API key
INTERNAL_API_KEYS must be a JSON array Write it as ["<hex>"], not as a comma-separated string. It is parsed as a JSON list, and a bare string fails settings validation — genesis-be and genesis-authz will not start.

(Optional) Observability & web tools — 5 keys

Vault keyK8s keyRequired when
KAFKA-SASL-USERNAMEKAFKA_SASL_USERNAMEModelHub trace ingestion enabled
KAFKA-SASL-PASSWORDKAFKA_SASL_PASSWORDModelHub trace ingestion enabled
OTEL-EVENTHUB-CONNECTION-STRINGOTEL_EVENTHUB_CONNECTION_STRINGOTEL Azure Event Hub exporter
OTEL-EVENTHUB-NAMESPACEOTEL_EVENTHUB_NAMESPACEOTEL Azure Event Hub exporter
TAVILY-API-KEYTAVILY_API_KEYTavily web-search tool enabled in agents

(Optional) LLM providers — 2 keys

The umbrella chart ships two optional mappings for LLM providers.

Vault keyK8s keyProvider
OPENAI-API-KEYOPENAI_API_KEYDirect OpenAI (non-Azure)
ANTHROPIC-API-KEYANTHROPIC_API_KEYAnthropic — Claude models

Manual creation — no ESO

Set global.secrets.externalSecrets.enabled: false and pre-create the Secret yourself.

kubectl create secret generic ai-studio-secrets \
  -n genesis \
  --from-literal=DB_USER='postgres' \
  --from-literal=DB_PASSWORD='<rotated>' \
  --from-literal=REDIS_PASSWORD='<rotated>' \
  --from-literal=SECRET_KEY='<32-rand-bytes>' \
  --from-literal=AUTH_SECRET='<32-rand-bytes>' \
  --from-literal=CREDENTIAL_ENCRYPTION_KEY='<32-rand-bytes>' \
  --from-literal=CREDENTIALS_ENCRYPTION_KEY='<32-rand-bytes>' \
  --from-literal=SECURITY_ENCRYPTION_KEY='<32-rand-bytes>' \
  --from-literal=SECURITY_ENCRYPTION_SALT='<16-rand-bytes>' \
  --from-literal=AUTH_KEYCLOAK_SECRET='<from-keycloak-client>' \
  ...   # repeat for all 34 required keys, plus any optional ones you enable

Generate random values with either of:

openssl rand -base64 32
python -c "import secrets; print(secrets.token_urlsafe(32))"
Shipping it via GitOps Never commit ai-studio-secrets to git. If you need it in a GitOps repo, use SealedSecrets so only your cluster can decrypt it.

ESO + Azure Key Vault

The most common configuration.

# values-customer-acme.yaml
global:
  secrets:
    provider: "kubernetes"
    k8sSecretName: "ai-studio-secrets"
    refreshInterval: "1h"
    externalSecrets:
      enabled: true
    azure:
      vaultUrl: "https://kv-acme-prod.vault.azure.net/"
    secretStore:
      name: "genesis-secret-store"
      kind: "ClusterSecretStore"      
  managedIdentity:
    enabled: true
    provider: "azure"
    azure:
      clientId: "<workload-identity-client-id>"
      tenantId: "<aad-tenant-id>"
secrets:
  data:   
    - { secretKey: DB_USER, remoteKey: DB-USER }
    - { secretKey: DB_PASSWORD, remoteKey: DB-PASSWORD }
    - { secretKey: TEMPORAL_STORE_PASSWORD, remoteKey: DB-PASSWORD }
    - { secretKey: TEMPORAL_VISIBILITY_STORE_PASSWORD, remoteKey: DB-PASSWORD }
    ...   # repeat for all 44 mapped keys
  

Before you install, confirm:

  1. Workload Identity federation between Azure AD and AKS is configured.
  2. The genesis-platform-sa ServiceAccount carries the azure.workload.identity/use=true annotation.
  3. The Azure AD app behind that ServiceAccount has get and list on the vault's secrets.
  4. ESO is installed in the cluster.
  5. Every key you leave in secrets.data exists in the vault with a value populated — the 34 required ones at minimum. The sync is all-or-nothing, so trim the mapping for any of the 10 optional keys you do not provision.

ESO + AWS Secrets Manager

global:
  secrets:
    externalSecrets:
      enabled: true
    aws:
      region: "us-east-1"
  managedIdentity:
    enabled: true
    provider: "aws"
  serviceAccount:
    aws:
      enabled: true
      roleArn: "arn:aws:iam::123456789012:role/genesis-platform-sa"

Before you install: IRSA is configured, and the role has secretsmanager:GetSecretValue and secretsmanager:DescribeSecret on the relevant secrets.

ESO + GCP Secret Manager

global:
  secrets:
    externalSecrets:
      enabled: true
  managedIdentity:
    enabled: true
    provider: "gcp"

Before you install: GKE Workload Identity binds the Kubernetes ServiceAccount to a Google service account holding roles/secretmanager.secretAccessor.


Rotation

Key classCadenceDisruption
DB_PASSWORD, REDIS_PASSWORD 90 days None — hot-reloads on the next pool refresh (≤ 60s)
SECRET_KEY, AUTH_SECRET, JWT_SECRET 180 days Active sessions invalidate. Rotate in a maintenance window
CREDENTIAL_ENCRYPTION_KEY and the other two encryption keys Only via the key-rotation procedure All stored credentials become unreadable if rotated without it
KEYCLOAK_*_SECRET 365 days, per Keycloak client None — pods pull fresh on the next request
KC_BOOTSTRAP_ADMIN_* Delete entirely after first install None
Azure / OpenAI / Anthropic API keys Per provider policy, typically 90–365 days None
INTERNAL_API_KEYS, GENESIS_API_KEY 180 days Service-to-service callers must update simultaneously
KAFKA_*, OTEL_* Per provider policy None — pods reconnect
Encryption-key rotation destroys data CREDENTIAL_ENCRYPTION_KEY, CREDENTIALS_ENCRYPTION_KEY and SECURITY_ENCRYPTION_KEY wrap data at rest in PostgreSQL. Rotating any of them without the documented two-step rotation procedure renders every stored connector credential and organization-scoped secret permanently unrecoverable. Open a support ticket for the procedure before you attempt it.

Once ESO syncs a new value into the Secret, pods must roll to pick it up. ESO honours eso.external-secrets.io/refresh-time: "1h", so most rotations land within the hour unattended. Force it when you need immediate pickup:

kubectl rollout restart deploy -n genesis

Pre-production audit checklist

CheckWhy it matters
All 34 required keys exist in the chosen backendA missing key surfaces as CreateContainerConfigError, not a clear error
Of the 10 optional keys, only those for features you enabled exist — and no othersUnused entries generate key not found noise on every ESO refresh
KC_BOOTSTRAP_ADMIN_* is scheduled for deletion after bootstrapA live bootstrap admin credential is a standing privilege-escalation path
The three encryption keys have a documented escrow pathLosing them means losing the data — there is no recovery
Per-key rotation cadence is on a real calendar90 / 180 / 365 days as listed above
ai-studio-secrets is not committed to git anywhereUse SealedSecrets if it must travel through a GitOps repo
ESO refreshInterval is setThe 1h default is fine
genesis-platform-sa has minimum-scope read on the backendNo write, no delete — the platform never mutates your vault

Keys are occasionally added or removed between releases. The authoritative per-release inventory ships with the release manifest; check it when upgrading rather than assuming this page's count.


See also

Prerequisites

What you provision before an install starts — Postgres, Redis, cert-manager, DNS, TLS, ESO, registry.

Install guide

End-to-end runbook, including where the ExternalSecret CRs get applied in the sequence.

Platform values

The non-secret half of configuration: which chart values every environment must change, and which to leave at their defaults.

Deployment models

ArgoCD / GitOps is the recommended path. Secrets are referenced, never committed.