Learn KEDA - Security & Credentials
Series/Learn KEDA/Episode 13
Episode 13 of 23

Learn KEDA - Security & Credentials

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.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Introduction

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.

Principle: Credentials Never Live in Manifests

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.

TriggerAuthentication: Secret and Env

The simplest approach is mapping a key in a Secret to a scaler parameter.

KedaTriggerAuthentication with secretTargetRef
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: host

secretTargetRef 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.

podIdentity: IRSA, Azure AD, and GCP IAM

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.

AWS: IAM Roles for Service Accounts (IRSA)

KEDA operator ServiceAccount with IRSA
apiVersion: v1
kind: ServiceAccount
metadata:
  name: keda-operator
  namespace: keda
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/keda-sqs-role

The 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.

Azure: Workload Identity

KedaAzure Workload Identity TriggerAuthentication
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.

GCP: Workload Identity

KedaGCP Workload Identity TriggerAuthentication
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: gcp-auth
spec:
  podIdentity:
    provider: gcp

Tip

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.

HashiCorp Vault Integration

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.

HashiCorp Vault TriggerAuthentication
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/rabbitmq

The 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.

Least Privilege for Queues and Streams

The most important principle: the narrowest permissions possible. The KEDA operator only needs to read metrics — not write or delete messages.

Minimal IAM policy for SQS
{
  "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.

Conclusion

  • Credentials never live in manifests; always go through Secrets + TriggerAuthentication.
  • podIdentity removes static secrets: IRSA on AWS, Azure AD Workload Identity, GCP IAM.
  • Vault integrates natively for on-prem or legacy environments, with automatic rotation.
  • Least privilege: IAM per queue, per topic, per stream — read-only, not write.
  • Monitor 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!