· Kubernetes  · 3 Min. Lesezeit

Secrets im Git, aber verschlüsselt: SOPS in der Praxis

GitOps heißt, alles steht in Git. Passwörter und Token eben nicht, ein Klartext-Secret im Repo ist ein Leak mit Historie. Wie SOPS Secrets verschlüsselt, ohne dass sie undiffbar werden, und wie ein Operator sie im Cluster wieder entschlüsselt.

GitOps heißt, alles steht in Git. Passwörter und Token eben nicht, ein Klartext-Secret im Repo ist ein Leak mit Historie. Wie SOPS Secrets verschlüsselt, ohne dass sie undiffbar werden, und wie ein Operator sie im Cluster wieder entschlüsselt.

GitOps lebt davon, dass der komplette Soll-Zustand in Git steht. Komplett? Passwörter, API-Token und Schlüssel eben nicht. Ein Secret im Klartext ist einmal committet für immer in der Historie, auch wenn man es später löscht. Ich habe genau so einen Fund erlebt: ein Datenbank-Passwort im Klartext mitten in den Werten eines Charts. Das ist ein Stoppsignal, kein Detail. SOPS löst das Problem sauber.

Verschlüsseln, aber diffbar bleiben

SOPS verschlüsselt gezielt nur die Werte, nicht die Struktur. Mit einem age-Schlüssel und einer encrypted-regex, die nur data und stringData erfasst, wird aus dem Klartext das hier:

SOPS verschlüsselt die Secret-Werte zu ENC[AES256_GCM,...], während Schlüsselnamen und Struktur lesbar bleiben. So bleibt die Datei diffbar, ohne die Geheimnisse preiszugeben.

Der Clou: Die Schlüsselnamen und der Aufbau bleiben lesbar, nur die Werte werden zu ENC[...]. Im Git-Diff sieht man also, dass sich ein Secret geändert hat, ohne den Wert zu sehen. Ein verschlüsselter Klumpen ohne Struktur wäre wertlos für Reviews, SOPS trifft genau die Mitte.

Im Cluster entschlüsselt der Operator

Die verschlüsselte Datei kommt als SopsSecret-Ressource ins Repo. Im Cluster liest ein Operator (etwa der sops-secrets-operator von isindir) diese Ressource, entschlüsselt sie mit dem age-Privatschlüssel und erzeugt daraus das echte Kubernetes-Secret. Der Operator ist damit die Instanz, die die Chiffre wieder zu einem nutzbaren Secret macht. Der private Schlüssel liegt einmal, out-of-band, im Cluster und verlässt ihn nie. Wer das Repo liest, sieht nur Chiffre.

Die Reihenfolge-Falle

Ein Fehler, den man einmal macht: die erste SopsSecret synchronisieren, bevor der Operator (oder das kustomize-Plugin KSOPS) installiert ist. Dann landet der verschlüsselte Text ungeprüft als vermeintliches Secret im Cluster, und die Anwendung startet mit Chiffre statt Passwort. Die Entschlüsselungs-Schicht ist ein Prerequisite: erst der Operator, dann die Secrets.

Ehrlich: Ein Schlüssel bleibt

SOPS macht Secrets nicht magisch sicher, es verlagert das Problem. Statt vieler Geheimnisse gibt es jetzt ein Geheimnis, das wirklich zählt: den age-Privatschlüssel. Der gehört nicht ins Git, sondern einmal pro Cluster sicher hinterlegt und ordentlich gesichert. Ist er weg, sind alle Secrets weg. Ist er kompromittiert, sind alle kompromittiert. Dieses eine Geheimnis gut zu hüten ist deutlich machbarer, als Dutzende Klartext-Werte aus jedem Repo herauszuhalten.

Sie wollen Secrets versionieren, ohne sie preiszugeben? Ich richte verschlüsselte Secret-Verwaltung ein, die zu Ihrem GitOps passt, und sorge dafür, dass der Schlüssel dahin gehört, wo er sicher ist. Mehr unter IT-Sicherheit & ISMS, das Erstgespräch ist unverbindlich.

Alex Jabi, Jabi IT

Alex Jabi

Ich betreue IT, Informationssicherheit und Datenschutz für KMU und Praxen an der Bergstraße und im Odenwald, persönlich, dokumentiert und ohne Cloud-Zwang.

Mehr über mich
Zurück zum Blog

Passende Artikel

Alle Artikel »
Wenn der einzige Zugang die Rancher-Shell ist

Wenn der einzige Zugang die Rancher-Shell ist

Manche Umgebungen geben keinen direkten Cluster-Zugang her: kein kubeconfig, kein kubectl von außen, nur die Kubectl-Shell in Rancher. Das ist unbequem, aber eine sinnvolle Einschränkung, und man kann sehr sauber damit arbeiten.