Teams verlagern Secrets aus dem Cluster in einen externen Store — und erzeugen als Erstes ein neues Secret: das Token für den Zugriff auf genau diesen Store. Ein Vault-Token in einer ConfigMap, ein AWS-Key in einer Operator-Variable — «ein Secret für den Zugriff auf die Secrets» wirft die Aufgabe auf den Anfang zurück. Laut Verizon DBIR 2025 beginnen über 60 % der Cloud-Vorfälle mit geleakten Credentials. Die funktionierende Kombination für 2026 schließt die Schleife vollständig: der External Secrets Operator synchronisiert Secrets aus dem externen Store, und Workload Identity beseitigt den letzten statischen Schlüssel — jenen, mit dem sich der Operator am Store authentifiziert.
Warum ein natives Secret keine Source of Truth ist
Ein Kubernetes Secret liegt in etcd als base64 — das ist Kodierung, keine Verschlüsselung. Solange Encryption at Rest nicht explizit aktiviert ist (--encryption-provider-config, in Produktion mit KMS-Provider), umgeht ein direkter Lesezugriff auf etcd oder ein Backup davon das gesamte RBAC. Doch selbst ein verschlüsseltes natives Secret taugt nicht als Primärquelle: keine Versionierung, kein Audit, keine automatische Rotation, gebunden an einen Cluster — Multi-Cluster wird zu Copy-Paste — und in Git gehört es unter GitOps erst recht nicht: Plaintext in der Commit-Historie lebt für immer.
Die Konsequenz: das «wahre» Secret lebt in einem externen Store. Default ist Vault oder sein BSL-freier Fork OpenBao (API-kompatibel, unter der Linux Foundation); Alternativen sind AWS Secrets Manager, GCP Secret Manager und Azure Key Vault. Cloud-managed Stores haben eine Preisfalle: $0.40 pro Secret und Monat machen aus 500 Secrets rund $2.400 im Jahr — noch vor den API-Gebühren; selbst betriebener Vault kann at scale günstiger sein.
ESO: eine CRD-Fassade über 50+ Backends
Der External Secrets Operator (ein CNCF-Projekt) ist der universelle Klebstoff zwischen Store und Cluster. Ein ClusterSecretStore beschreibt die Backend-Verbindung; ein ExternalSecret ist die deklarative Anforderung: «synchronisiere diesen Pfad in ein gewöhnliches K8s Secret». Die Anwendung weiß nichts von Vault — sie liest das Secret über das vertraute valueFrom: secretKeyRef. Ein Backend-Wechsel bedeutet eine Änderung am SecretStore, nicht an den Anwendungen.
Über dem Basis-Paar sitzen ClusterExternalSecret (Fan-out eines Secrets in viele Namespaces für Multi-Tenant-Plattformen) und PushSecret (die Gegenrichtung: aus dem Cluster in den Store). In Git liegt dabei nur das ExternalSecret — eine Referenz auf einen Pfad, nie der Wert.
Workload Identity: keine Credentials für die Credentials
Ein Bootstrap-Secret bleibt: womit authentifiziert sich der Operator selbst am Store? Die Antwort — mit nichts Statischem. Der Mechanismus ist in allen Clouds identisch: der Pod erhält ein projected ServiceAccount-Token, audience-gebunden an den OIDC-Endpunkt der Cloud, und das Cloud-IAM validiert es direkt. Auf EKS ist das IRSA — die Annotation eks.amazonaws.com/role-arn am ServiceAccount, mit einer IAM Trust Policy, die auf das exakte Paar aus Namespace und ServiceAccount zeigt — oder das modernere EKS Pod Identity. Auf GKE heißt es Workload Identity, auf AKS Azure Workload Identity: dasselbe Muster mit anderer Annotation.
Für Vault übernimmt die kubernetes auth method dieselbe Rolle: die Vault-Rolle ist fest an ServiceAccount-Name und Namespace gebunden (bound_service_account_names plus bound_service_account_namespaces), das Token lebt eine Stunde. Die Kompromittierung eines Pods im Nachbar-Namespace bringt nichts. Der eine Vorbehalt: die föderierte Rolle muss least-privilege sein. Ihr «für die Demo» AdministratorAccess zu geben heißt, sämtliche Risiken des statischen Schlüssels wieder einzusammeln — nur ohne den Schlüssel selbst.
Rotation ist ein Prozess, kein Ereignis
refreshInterval am ExternalSecret bestimmt, wie oft der Store abgefragt wird: 1–5 Minuten bedeuten schnelle Rotation um den Preis von Backend-Last; 1–24 Stunden schonen das Backend, aber das Secret veraltet. Ein geänderter Wert im Store erreicht das K8s Secret automatisch, doch Pods lesen Secrets beim Start — ein Restart ist nötig. Diese Lücke schließt stakater/reloader: die Annotation reloader.stakater.com/auto am Deployment, und der Restart passiert von selbst, sobald sich das Secret ändert.
Die oberste Stufe sind dynamic secrets in Vault: Datenbank-Credentials werden pro Anfrage erzeugt, jedes mit eigener TTL und automatischem Widerruf. Rotation hört auf, ein Problem zu sein — jede Instanz der Anwendung hält ihre eigenen kurzlebigen Credentials.
Checkliste und Fallen
Vault KV v2: im remoteRef.key ist das Segment /data/ Pflicht — etwa secret/data/prod/app/db. Ohne dieses meldet ESO SecretSynced: True, während das Secret leer bleibt: die übelsten Fehler sind die, die wie Erfolg aussehen.
creationPolicy: Owner am Target — sonst gibt es einen Ownership-Konflikt beim manuellen kubectl edit. Ein langes refreshInterval für kurzlebige Credentials macht die Rotation sinnlos. Ein geteiltes Secret für zwanzig Anwendungen macht RBAC grobkörnig: einem einzelnen Service den Zugriff zu entziehen wird unmöglich.
Env vars gegen Dateien: Umgebungsvariablen sind in /proc, in Crash-Dumps und in kubectl describe sichtbar; der Trend 2026 sind file-mounted Secrets über den CSI-Driver für das Sensibelste. Encryption at Rest in etcd ist die Basisschicht, die ESO nicht ersetzt: das synchronisierte Secret landet weiterhin in etcd.
Das Fazit: der Store beantwortet «wo leben die Secrets», ESO «wie erreichen sie den Pod», Workload Identity «wie läuft das alles ohne einen einzigen langlebigen Schlüssel». Von unten lassen sich die Schichten nicht entfernen: ohne die ersten beiden hat Workload Identity nichts mehr zu schützen. Und wie ein Secret unterwegs nicht im Repository landet — von Secret-Scan bis Admission-Policies.