Enable Redis Authentication & TLS
Starting with platform release 3.26.4, DynamoAI supports authenticated and TLS-encrypted connections to Redis across all components. This guide covers enabling Redis authentication and TLS on an existing deployment, for both in-cluster Redis and managed providers (AWS ElastiCache, Azure Cache for Redis / Azure Managed Redis).
The default security mode is none, so existing unauthenticated deployments keep working after the image upgrade with no configuration changes. Enabling auth/TLS is opt-in via the values described below.
Prerequisites
- Platform images at version 3.26.4 or later on every component (API, metrics-server, evaluation and guard workers). The variables below are ignored by older images.
- A Redis password (or managed-cache access key) stored in your secret manager, delivered to the cluster as a
passwordkey on the platform's Redis secret (the secret referenced byglobal.secrets.redis). - A maintenance window: enabling auth restarts Redis and the components that connect to it. In-flight evaluation jobs may need resubmission.
Configuration contract
Every Redis-consuming component accepts the same environment variables:
| Variable | Values | Notes |
|---|---|---|
REDIS_SECURITY_MODE | none (default), auth, tls, auth_tls | Auth and TLS are only enforced when the selected mode requires them |
REDIS_PROVIDER | self_managed (default), elasticache, azure_cache | Explicit provider selection; never inferred from the hostname |
REDIS_PASSWORD | secret reference | Required for auth / auth_tls |
REDIS_URI | full redis:// or rediss:// URI | Optional; takes precedence over the split host/port variables |
REDIS_TLS_CA_PATH | file path | Only for private-CA endpoints; managed providers use publicly trusted CAs and need no CA bundle |
Choose your deployment mode
In-cluster Redis with authentication
Enable auth on the bundled Redis and point it at the same secret:
redis:
auth:
enabled: true
existingSecret: <redis-secret-name>
existingSecretPasswordKey: password
Component env values: REDIS_SECURITY_MODE: "auth", REDIS_PROVIDER: "self_managed".
AWS ElastiCache (auth + in-transit TLS)
Use the cluster's primary endpoint and auth token. Component env values: REDIS_SECURITY_MODE: "auth_tls", REDIS_PROVIDER: "elasticache".
Azure Cache for Redis / Azure Managed Redis (auth + TLS)
Component env values: REDIS_SECURITY_MODE: "auth_tls", REDIS_PROVIDER: "azure_cache". Set the secret's host/port to the cache endpoint (6380 for Azure Cache for Redis; 10000 for Azure Managed Redis) and password to the access key.
Celery opens two Redis connections: the broker (job queue) and the result backend. The broker always uses logical database 0. The result backend is set by REDIS_RESULT_BACKEND_DB, which defaults to 0, so single-database caches such as Azure Managed Redis work without extra configuration. Broker and result-backend keys use separate namespaces, so sharing database 0 is safe.
On 3.26.4 and earlier REDIS_RESULT_BACKEND_DB does not exist and the result backend defaults to database 1. On those releases, point a single-database cache at database 0 by supplying the full result-backend URI through REDIS_RESULT_BACKEND instead.
When using an external managed cache, disable the bundled Redis: redis.enabled: false.
Values changes
Add the three variables to every Redis-consuming env block in your values files (adjust mode/provider per the section above):
REDIS_SECURITY_MODE:
value: "auth_tls"
REDIS_PROVIDER:
value: "azure_cache"
REDIS_PASSWORD:
valueFrom:
secretKeyRef:
name: "{{ .Values.global.secrets.redis }}"
key: password
The env blocks to update:
| Chart | Component |
|---|---|
| base | API deployment |
| base | metrics-server (drives worker autoscaling; do not skip) |
| base | billing scaled job (if enabled) |
| base | Celery Flower (if enabled; see below) |
| eval | every ScaledJob env block (GPU / memory / CPU, report generation, deep-dive relabel) |
| guard | data-processing, fine-tuning jobs |
Flower's broker URL is built in its command line rather than from the resolver, so update it explicitly:
command: ["celery", "--broker=rediss://:$(REDIS_PASSWORD)@$(REDIS_HOST):$(REDIS_PORT)/0?ssl_cert_reqs=required", "flower"]
(For auth without TLS use redis:// and drop the ssl_cert_reqs parameter.)
The KEDA triggers: blocks need no changes; workers scale through the platform's metrics-server, which is why the metrics-server env block is mandatory.
Finally, add the password key to the Redis secret. With External Secrets Operator:
data:
- secretKey: password
remoteRef:
key: <your-secret-manager-key>
Rollout order
- Create the password/access key in your secret manager and sync it to the cluster secret. Verify the
passwordkey is present before proceeding; pods block on a missing secret key. - For managed caches, run the connectivity pre-check (below) before touching the platform.
- Apply the updated values through your GitOps flow and reconcile. Redis (if in-cluster) and all consumers roll together; brief connection errors while both sides converge are normal.
Connectivity pre-check (managed cache)
PW=$(kubectl -n <namespace> get secret <redis-secret-name> -o jsonpath='{.data.password}' | base64 -d)
HOST=$(kubectl -n <namespace> get secret <redis-secret-name> -o jsonpath='{.data.host}' | base64 -d)
PORT=$(kubectl -n <namespace> get secret <redis-secret-name> -o jsonpath='{.data.port}' | base64 -d)
kubectl -n <namespace> run redis-check --rm -i --restart=Never --image=<your-registry>/redis:<tag> \
--command -- redis-cli --tls -h "$HOST" -p "$PORT" -a "$PW" ping
# expect: PONG. Only if you set REDIS_RESULT_BACKEND_DB to a non-zero index, repeat with
# `-n <index>` before `ping` to confirm that logical database is reachable.
Verification
kubectl -n <namespace> get pods # all Running
kubectl -n <namespace> logs deploy/dynamoai-api | grep -i redis # no auth/connection errors
kubectl -n <namespace> get scaledjobs # READY = True
curl -is https://<api-host>/health/ready | head -1 # HTTP 200
Then submit a small evaluation job end-to-end: worker pods should appear and the job should progress past "Preparing".
Rollback
Revert the values commit (restores REDIS_SECURITY_MODE: none and, for in-cluster, auth.enabled: false) and reconcile. Redis queue and progress data are transient, so switching modes never migrates data, but in-flight jobs during the switch are lost and must be resubmitted.
Troubleshooting
| Symptom | Likely cause |
|---|---|
NOAUTH Authentication required in component logs | Component missing REDIS_SECURITY_MODE/REDIS_PASSWORD env (or running a pre-3.26.4 image that ignores them) |
Workers never scale; ScaledJobs READY: Unknown | metrics-server cannot reach Redis; check its logs first |
CreateContainerConfigError on API/metrics pods | password key missing from the Redis secret |
Managed cache: ERR SELECT is not allowed or ERR DB index is out of range | The result backend is pointed at a logical database the cache does not expose. Set REDIS_RESULT_BACKEND_DB: 0 (the default), or on 3.26.4 and earlier override the full REDIS_RESULT_BACKEND URI to database 0 |
| Pods still using old endpoint after a secret change | Env vars are read at container start; kubectl rollout restart the consumers |