- Authors

- Name
- Phillip Pham
- @ddppham
Service Accounts absichern: Token-Sicherheit und RBAC in Kubernetes
TL;DR - Kurzfassung
Jeder Kubernetes-Namespace hat einen default Service Account, der automatisch in jeden Pod gemountet wird -- mit einem nie ablaufenden Token. Das ist ein Sicherheitsrisiko. Deaktivieren Sie automountServiceAccountToken, erstellen Sie dedizierte Service Accounts pro Workload mit minimalen RBAC-Rechten, und nutzen Sie Bound Service Account Tokens oder Workload Identity für Cloud-Integrationen.
Service Accounts sind die Identität von Workloads in Kubernetes. Jeder Pod bekommt automatisch einen Service Account zugewiesen, und mit diesem Account erhält er ein Token für die Kubernetes-API. Das Problem: In der Standardkonfiguration ist dieses Token unbegrenzt gültig und hat oft mehr Rechte als nötig.
# Prüfen, welches Token in einem Pod gemountet ist
kubectl exec -it my-pod -- cat /var/run/secrets/kubernetes.io/serviceaccount/token
# Dieses Token kann für API-Zugriffe missbraucht werden
# Alle Service Accounts mit ihren Secrets auflisten
kubectl get serviceaccounts --all-namespaces -o wide
Warum der Default Service Account ein Risiko ist
Der default Service Account existiert in jedem Namespace und wird automatisch jedem Pod zugewiesen, der keinen eigenen SA definiert. Das führt zu drei konkreten Problemen:
Automatisches Token-Mount: Jeder Pod erhält unter /var/run/secrets/kubernetes.io/serviceaccount/ ein API-Token. Bei einem Container-Ausbruch hat der Angreifer sofort Zugriff auf die Kubernetes-API.
Geteilte Identität: Alle Pods ohne expliziten SA teilen dieselbe Identität. RBAC-Regeln können nicht zwischen verschiedenen Workloads unterscheiden.
Legacy-Tokens ohne Ablaufdatum: Vor Kubernetes 1.24 waren SA-Tokens als Secrets gespeichert und liefen nie ab. In vielen Clustern existieren diese Tokens noch.
Schritt 1: Auto-Mount deaktivieren
Die wichtigste Maßnahme: Verhindern Sie, dass Service Account Tokens automatisch in Pods gemountet werden.
# Option A: Auto-Mount auf Service-Account-Ebene deaktivieren
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
namespace: production
automountServiceAccountToken: false
---
# Option B: Auto-Mount auf Pod-Ebene deaktivieren (überschreibt SA-Einstellung)
apiVersion: v1
kind: Pod
metadata:
name: webapp
namespace: production
spec:
automountServiceAccountToken: false
containers:
- name: webapp
image: registry.example.com/webapp:v2.1.0
Deaktivieren Sie das Auto-Mount auf dem default Service Account in jedem Namespace:
# Default SA in allen Namespaces absichern
for ns in $(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}'); do
kubectl patch serviceaccount default -n "$ns" \
-p '{"automountServiceAccountToken": false}'
done
Schritt 2: Dedizierte Service Accounts erstellen
Jeder Workload braucht einen eigenen Service Account mit minimalen Rechten. Das ermöglicht granulare RBAC-Kontrolle und klare Zuordnung.
# Dedizierter SA für eine Backend-Anwendung
apiVersion: v1
kind: ServiceAccount
metadata:
name: backend-api
namespace: production
labels:
app: backend-api
team: platform
automountServiceAccountToken: false
---
# Minimale RBAC-Rolle: Nur ConfigMaps lesen
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: backend-api-role
namespace: production
rules:
- apiGroups: ['']
resources: ['configmaps']
verbs: ['get', 'list', 'watch']
resourceNames: ['backend-config', 'feature-flags']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: backend-api-binding
namespace: production
subjects:
- kind: ServiceAccount
name: backend-api
namespace: production
roleRef:
kind: Role
name: backend-api-role
apiGroup: rbac.authorization.k8s.io
---
# Deployment mit dediziertem SA
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-api
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: backend-api
template:
metadata:
labels:
app: backend-api
spec:
serviceAccountName: backend-api
automountServiceAccountToken: true # Gezielt aktivieren, weil die App API-Zugriff braucht
containers:
- name: backend-api
image: registry.example.com/backend:v3.0.1
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop: ['ALL']
Beachten Sie: automountServiceAccountToken: true wird hier bewusst gesetzt, weil die Anwendung API-Zugriff benötigt. Die RBAC-Rolle beschränkt diesen Zugriff auf das absolute Minimum.
Schritt 3: Bound Service Account Tokens nutzen
Seit Kubernetes 1.22 unterstützt der API-Server Bound Service Account Tokens. Diese haben drei entscheidende Vorteile gegenüber Legacy-Tokens:
- Zeitlich begrenzt: Tokens laufen nach einer konfigurierbaren Dauer ab (Standard: 1 Stunde)
- An einen Pod gebunden: Das Token wird ungültig, wenn der Pod gelöscht wird
- Audience-beschränkt: Das Token ist nur für einen bestimmten Empfänger gültig
# Token-Projektion mit begrenzter Gültigkeit
apiVersion: v1
kind: Pod
metadata:
name: secure-app
namespace: production
spec:
serviceAccountName: backend-api
automountServiceAccountToken: false # Standard-Mount deaktivieren
containers:
- name: app
image: registry.example.com/app:v1.0.0
volumeMounts:
- name: sa-token
mountPath: /var/run/secrets/tokens
readOnly: true
volumes:
- name: sa-token
projected:
sources:
- serviceAccountToken:
path: api-token
expirationSeconds: 3600 # Token läuft nach 1 Stunde ab
audience: api.internal # Nur für diesen Empfänger gültig
Das kubelet erneuert das Token automatisch, bevor es abläuft. Die Anwendung muss das Token bei jedem API-Aufruf erneut von der Datei lesen, anstatt es beim Start einmalig im Speicher zu halten.
Schritt 4: Workload Identity in der Cloud
In Cloud-Umgebungen ersetzt Workload Identity die manuelle Verwaltung von Cloud-Credentials in Kubernetes-Secrets. Der Pod authentifiziert sich über seinen Service Account direkt beim Cloud-Provider.
| Cloud | Feature | Mechanismus |
|---|---|---|
| GKE | Workload Identity | SA wird mit Google SA verknüpft |
| EKS | IAM Roles for Service Accounts | OIDC-basierte Federation |
| AKS | Workload Identity (Azure AD) | Federated Credentials |
Beispiel: AWS EKS mit IAM Roles for Service Accounts
# Service Account mit IAM-Role-Annotation
apiVersion: v1
kind: ServiceAccount
metadata:
name: s3-reader
namespace: data-pipeline
annotations:
# Diese Annotation verknüpft den K8s-SA mit einer AWS IAM-Rolle
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/s3-read-only
automountServiceAccountToken: false
---
apiVersion: v1
kind: Pod
metadata:
name: data-processor
namespace: data-pipeline
spec:
serviceAccountName: s3-reader
containers:
- name: processor
image: registry.example.com/processor:v2.0.0
# AWS SDK erkennt die projected Credentials automatisch
# Kein AWS_ACCESS_KEY_ID oder AWS_SECRET_ACCESS_KEY nötig
Der Vorteil: Es gibt keine statischen Cloud-Credentials mehr im Cluster. Die temporären Tokens werden vom Cloud-Provider ausgestellt und automatisch rotiert.
Service Accounts auditieren
Prüfen Sie regelmäßig, welche Service Accounts existieren und welche Rechte sie haben:
# Alle SAs mit Auto-Mount-Status auflisten
kubectl get serviceaccounts --all-namespaces \
-o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.automountServiceAccountToken}{"\n"}{end}'
# Rechte eines spezifischen SA prüfen
kubectl auth can-i --list \
--as=system:serviceaccount:production:backend-api
# Ungenutzte SAs finden (keine Pods referenzieren sie)
kubectl get pods --all-namespaces \
-o jsonpath='{range .items[*]}{.spec.serviceAccountName}{"\n"}{end}' | \
sort -u > /tmp/used-sas.txt
FAQ
Kann ich den Default Service Account einfach löschen?
Nein. Kubernetes erstellt den default Service Account automatisch in jedem Namespace neu. Stattdessen sollten Sie automountServiceAccountToken: false auf dem Default SA setzen. So existiert er zwar weiterhin, wird aber nicht mehr automatisch in Pods gemountet.
Was passiert mit laufenden Pods, wenn ich Auto-Mount deaktiviere?
Laufende Pods sind nicht betroffen. Die Änderung wirkt sich nur auf neue Pods aus. Bestehende Pods behalten ihr gemountetes Token bis zum nächsten Neustart.
Wie erkenne ich Legacy-Tokens in meinem Cluster?
Legacy-Tokens sind als Secrets vom Typ kubernetes.io/service-account-token gespeichert. Mit kubectl get secrets --all-namespaces --field-selector type=kubernetes.io/service-account-token finden Sie alle. In Clustern ab Version 1.24 werden diese nicht mehr automatisch erstellt.
Braucht jeder Pod einen eigenen Service Account?
Nicht zwingend jeder Pod, aber jeder Workload-Typ sollte einen eigenen SA haben. Pods, die dieselbe Anwendung in verschiedenen Replicas ausführen, können denselben SA teilen. Unterschiedliche Anwendungen sollten getrennte SAs mit spezifischen RBAC-Regeln bekommen.
Funktioniert Workload Identity auch On-Premises?
Workload Identity ist ein Cloud-spezifisches Feature. On-Premises können Sie eine ähnliche Architektur mit SPIFFE/SPIRE aufbauen, das Pod-Identitäten über X.509-Zertifikate bereitstellt und mit externen Systemen wie HashiCorp Vault integriert werden kann.
Kubernetes-Security & Compliance?
Security-Audits, Penetration Tests und Compliance-Beratung für Ihre Container-Infrastruktur. BSI-Grundschutz, DSGVO, ISO 27001.
Kubernetes-Beratung gesucht?
Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
RBAC Best Practices: Kubernetes-Zugriff sicher steuern
Kubernetes RBAC richtig konfigurieren: Role vs. ClusterRole, praxisnahe Beispiele für Developer- und CI/CD-Rollen und die häufigsten Fehler vermeiden.
Kubernetes Security Audit: Die komplette Checkliste
Kubernetes Security Audit systematisch durchführen: CIS Benchmark mit kube-bench, RBAC-Review, Network Policies prüfen und Image-Scanning mit Trivy.
Kubernetes Forbidden Error lösen: RBAC Debugging Guide
Kubernetes Forbidden Error systematisch debuggen: kubectl auth can-i, ClusterRoleBindings prüfen und fehlende RBAC-Berechtigungen mit Beispielen beheben.
Kubernetes Bastion Host einrichten: SSH-Tunnel und Teleport
Bastion Host für private Kubernetes-Cluster einrichten. SSH-Tunneling, kubectl-Proxy, RBAC-Integration und moderne Alternativen wie Teleport und HashiCorp Boundary.
DSGVO-konforme Kubernetes-Cluster richtig konfigurieren
Praxisleitfaden für DSGVO-konforme Kubernetes-Cluster: Encryption at Rest, RBAC, Network Policies und automatisiertes Audit-Logging korrekt konfigurieren.