Best practices for managing secrets and credentials for KEDA: TriggerAuthentication, podIdentity IRSA, Azure AD Workload Identity, GCP IAM, HashiCorp Vault integration, rotation, and least privilege IAM policies for accessing queues and streams.

In episode 12 we wrapped up the HTTP Add-on. But there's one thing we've been using without discussing seriously: credentials. Every scaler — SQS, RabbitMQ, Prometheus, databases — needs access to an external system, and managing that access correctly is the difference between secure autoscaling and a data leak. In this episode we cover secret management best practices, podIdentity across the three clouds, HashiCorp Vault integration, rotation, and the principle of least privilege.
The golden rule of KEDA security: a ScaledObject never contains credentials. All secrets are stored in Kubernetes Secrets, then referenced via TriggerAuthentication (namespace-scoped) or ClusterTriggerAuthentication (cluster-wide). Credentials written directly in a ScaledObject's metadata will sit in plain text in etcd and can be read by anyone with read access.
The simplest approach is mapping a key in a Secret to a scaler parameter.
apiVersion: v1
kind: Secret
metadata:
name: rabbitmq-secret
stringData:
host: amqp://user:password@rabbitmq.prod.svc:5672
---
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: rabbitmq-auth
spec:
secretTargetRef:
- parameter: host
name: rabbitmq-secret
key: hostsecretTargetRef maps a key in the Secret to a scaler parameter. Never write secrets as literals in files that go into Git — use External Secrets, sealed secrets, or injection from the platform. Take inventory of the auth in use with kubectl get triggerauthentication -n production.
All three cloud providers support identity federation: the pod uses an identity granted by the control plane, with no static secrets that need manual rotation. KEDA simply points to the provider on the TriggerAuthentication.
apiVersion: v1
kind: ServiceAccount
metadata:
name: keda-operator
namespace: keda
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/keda-sqs-roleThe role-arn annotation is attached to the KEDA operator's ServiceAccount. That role should only contain the permissions needed — for example sqs:GetQueueAttributes for an SQS trigger.
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: azure-auth
spec:
podIdentity:
provider: azure-workload
identityId: "12345678-1234-1234-1234-123456789012"The KEDA operator is set up with Azure AD Workload Identity using clientId, tenantId, and federatedIdentityCredentials that bind the ServiceAccount to a managed identity.
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: gcp-auth
spec:
podIdentity:
provider: gcpTip
Choose podIdentity whenever possible: there are no secrets to rotate manually, audit trails are recorded in the cloud, and policies can be revoked at any time via IAM.
For environments already using Vault, KEDA has a built-in authentication provider. Credentials are fetched from Vault when the trigger is evaluated, not copied into etcd.
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: vault-auth
spec:
secretTargetRef:
- parameter: host
name: keda-secrets
key: host
vault:
address: http://vault.vault.svc:8200
authentication: kubernetes
kubernetes:
role: keda-role
mount: kubernetes
secrets:
- parameter: host
key: rabbitmq
path: secret/data/keda/rabbitmqThe authentication: kubernetes method makes KEDA log into Vault through its ServiceAccount. Rotation is done in Vault without any redeployment.
Note
Vault handles rotation, not KEDA. When a secret is rotated, the next trigger automatically uses the new value as long as KEDA doesn't cache its read. Monitor keda_scaler_errors_total to detect secret read failures early.
The most important principle: the narrowest permissions possible. The KEDA operator only needs to read metrics — not write or delete messages.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["sqs:GetQueueAttributes", "sqs:ListQueues"],
"Resource": "arn:aws:sqs:ap-southeast-3:123456789012:orders"
}
]
}For Kafka, give the consumer role only read operations (DescribeGroup, DescribeTopic, Fetch) on the specific topics and groups — no wildcards. For Redis and NATS, create users with read-only permissions. Also restrict RBAC: anyone who can read Secrets can read their credentials.
keda_scaler_errors_total and restrict Secret-reader RBAC.Credentials are now secure, workloads are stable, and autoscaling is running. But you work in a cluster shared by many teams — how do you isolate them? In episode 14 we discuss Multi-Tenancy & RBAC: ClusterTriggerAuthentication, per-namespace scaler restrictions, admission webhooks, and OPA/Gatekeeper policies to control KEDA usage. See you there!