Kubernetes Secrets: Warum Base64 keine Verschlüsselung ist
Ein Kubernetes Secret ist Base64, lesbar für jeden mit den passenden Rechten. Wo Secrets überall durchsickern, und was ein Secret Manager, Rotation und saubere Rechte ändern.

echo cGFzc3dvcmQ= | base64 -d ergibt password. Das ist der ganze Schutz, den ein Kubernetes Secret von sich aus bietet. Base64 ist eine Kodierung, damit beliebige Bytes in YAML passen, keine Verschlüsselung. Das ist kein Fehler von Kubernetes, sondern Absicht: Secrets sind ein eigener Objekttyp, damit man sie mit Rechten anders behandeln kann als eine ConfigMap. Geschützt sind sie nur so gut wie diese Rechte.
Wer kann ein Kubernetes Secret lesen?
- Jeder mit `get` oder `list` auf Secrets im Namespace. Das Recht ist in vielen Rollen enthalten, die niemand genauer ansieht, etwa in
edit. - Jeder, der einen Pod im Namespace starten darf. Er bindet das Secret einfach in seinen Pod ein und liest es aus. Wer Pods anlegen darf, darf faktisch Secrets lesen.
- Operatoren und Controller mit clusterweiten Rechten. Ein Monitoring-Agent, ein Backup-Werkzeug, eine CI mit Admin-Token: Jeder von ihnen kann alle Secrets lesen, und ein Leck bei einem von ihnen ist ein Leck bei allen.
- Wer an etcd kommt. Ob die Daten dort verschlüsselt liegen, entscheidet der Betreiber der Steuerungsebene. Bei einem Managed-Angebot lohnt die Nachfrage.
Wo sickern Secrets durch?
Das Secret-Objekt ist selten die eigentliche Lücke. Die Werte landen unterwegs an anderen Stellen:
Im Git-Repository. Ein secret.yaml mit Base64-Werten ist im Klartext eingecheckt, nur umständlicher zu lesen. Einmal im Verlauf, bleibt es dort.
In Helm-Values. Helm speichert die Values jeder Revision in einem Release-Secret im Namespace. Ein Passwort, das in values.yaml stand, liegt dort in jeder Revision, auch nachdem es längst getauscht wurde.
Direkt in der Pod-Vorlage. Ein Wert, der als env: value: im Deployment steht statt über eine Referenz auf ein Secret, ist für jeden sichtbar, der Deployments lesen darf, also für viele mehr als die, die Secrets lesen dürfen.
In CI-Logs und Chat-Verläufen. Ein echo $DATABASE_URL zum Debuggen, ein kopierter Connection-String im Team-Chat. Beides lebt länger als der Schlüssel sollte.
Was schützt Secrets wirklich?
Rechte eng schneiden
Niemand braucht im Alltag Lesezugriff auf Secrets. Menschen deployen, sie lesen keine Passwörter. Rollen ohne get secrets, keine clusterweiten Admin-Tokens für Werkzeuge, und wer Pods anlegen darf, ist bewusst ausgewählt.
Ein Secret Manager als Quelle der Wahrheit
Ein Secret Manager wie der von Scaleway hält Werte verschlüsselt, versioniert, mit Zugriffsrechten und Protokoll. Die Anwendung bekommt den Wert beim Start, entweder weil ihn das Deployment beim Ausrollen holt oder weil der External Secrets Operator ihn in ein Kubernetes Secret synchronisiert. Ehrlich gesagt: Auch dann liegt der Wert am Ende in einem Secret im Namespace, denn der Pod braucht ihn. Gewonnen ist, dass es eine Quelle gibt, die nicht in Git, nicht in Helm-Values und nicht auf Laptops steht.
Nicht auslesbar nach dem Speichern
Ein Secret, das man nach dem Speichern nie wieder angezeigt bekommt, kann man nicht versehentlich kopieren. Wer den Wert braucht, braucht ihn in der Anwendung, nicht auf dem Bildschirm.
Rotation, die ankommt
Ein Schlüssel ist erst rotiert, wenn die Anwendung ihn benutzt. Umgebungsvariablen liest ein Prozess beim Start. Wer im Secret Manager eine neue Version anlegt und nicht neu startet, hat nur die Hälfte getan. Eine Rotation braucht also zwei Schritte: neue Version, dann ein Neustart, und eine Anzeige, welche Instanz noch mit der alten läuft.
Eine Checkliste
- Kein Secret im Git-Repository, auch nicht Base64-kodiert.
- Keine Passwörter in Helm-Values oder als Klartext in der Pod-Vorlage.
- Menschen haben keinen Lesezugriff auf Secrets in der Produktion.
- Jeder Wert hat eine Quelle, idealerweise einen Secret Manager.
- Jede Rotation endet mit einem Neustart, und jemand prüft, dass er stattfand.
- Das Protokoll zeigt, wer ein Secret geändert hat, nie den Wert.
Ein Beispiel: den Stripe-Schlüssel rotieren
So sieht eine Rotation aus, die wirklich ankommt, am Beispiel eines Zahlungsanbieter-Schlüssels:
- Neuen Schlüssel erzeugen. Beim Anbieter einen neuen Schlüssel anlegen. Viele Anbieter, Stripe eingeschlossen, lassen den alten für eine gewählte Zeit weiter gelten. Das ist das Fenster für den Wechsel.
- Neue Version im Secret Manager. Den Wert dort als neue Version speichern, nicht im Chat, nicht in einer Datei.
- Neustart. Die Anwendung neu starten, damit sie den neuen Wert liest. Prüfen, dass alle Instanzen neu gestartet sind, nicht nur eine.
- Prüfen. Eine Testzahlung, ein Blick in die Logs: keine Authentifizierungsfehler.
- Alten Schlüssel widerrufen. Erst jetzt, und dann wirklich.
Der häufigste Fehler liegt zwischen Schritt 2 und 3: Die neue Version ist gespeichert, aber niemand startet neu. Zwei Wochen später läuft der alte Schlüssel ab, und die Zahlungen brechen am Samstagabend ein.
External Secrets Operator: wann er sich lohnt
Der External Secrets Operator läuft im Cluster und synchronisiert Werte aus einem Secret Manager in Kubernetes Secrets. Er lohnt sich, wenn viele Anwendungen dieselben Werte brauchen, wenn Werte sich häufig ändern oder wenn Ihre Sicherheitsrichtlinie verlangt, dass Werte nur innerhalb des Clusters aufgelöst werden. Der Preis: ein weiterer Controller mit Rechten auf den Secret Manager, der gepflegt, aktualisiert und überwacht werden will. Für wenige Anwendungen mit seltenen Änderungen reicht es, die Werte beim Ausrollen aus dem Secret Manager zu holen.
Kleine Schritte für diese Woche
Wer nicht alles auf einmal umbauen kann, fängt so an: Das Git-Repository nach Base64-Blöcken und Passwörtern durchsuchen, Treffer rotieren. Prüfen, wer im Cluster get secrets darf, und die Liste kürzen. Und für den nächsten neuen Schlüssel gleich den Secret Manager nutzen statt einer Umgebungsvariable im Manifest.
Wie Clusterward damit umgeht
In Clusterward ist ein Secret nach dem Speichern nicht mehr auslesbar, auch nicht für Administratoren, und liegt AES-256-GCM-verschlüsselt oder in Scaleway Secret Manager, in lesbaren Ordnern pro Anwendung, Umgebung und Service. Helm-Charts bekommen Geheimnisse über Platzhalter, statt dass sie im Klartext in den gepflegten Values stehen. Clusterward prüft alle zehn Minuten, ob ein Secret außerhalb eine neue Version bekommen hat, zeigt an, welche Instanz noch die alte nutzt, und startet auf Wunsch automatisch neu. Die Auslieferung über den External Secrets Operator ist pro Cluster wählbar. Das Audit-Log nennt nur Namen, nie Werte. Mehr unter Secrets; was davon ein Prüfer als Nachweis sieht, unter Audit & NIS2 und im Beitrag NIS2 im Kubernetes-Betrieb.
Fazit
Base64 schützt nichts, Rechte schützen. Halten Sie Werte aus Git, Helm-Values und Pod-Vorlagen heraus, geben Sie Menschen keinen Lesezugriff und machen Sie einen Secret Manager zur einzigen Quelle. Und rotieren Sie so, dass die neue Version auch in der Anwendung ankommt.
Wo liegen Ihre Secrets heute? Schreiben Sie uns, wie Ihre Anwendungen an Passwörter und Schlüssel kommen. Wir zeigen, wo sie mitlesbar sind und wie der Umzug in einen Secret Manager aussieht. Frage stellen →
Quellen und weiterführende Links
Häufige Fragen
- Nicht von sich aus. Die Werte eines Kubernetes Secrets sind nur Base64-kodiert, damit beliebige Bytes in YAML passen, und lassen sich mit base64 -d sofort lesen. Geschützt sind Secrets nur durch Rechte. Ob die Daten in etcd verschlüsselt liegen, entscheidet der Betreiber der Steuerungsebene; bei Managed-Angeboten lohnt die Nachfrage.