Veröffentlicht am

GitOps Secrets: SOPS und Sealed Secrets im Vergleich

Teilen:
Authors

TL;DR

Secrets gehören nicht als Klartext in Git. Sealed Secrets verschlüsselt direkt im Cluster, SOPS nutzt externe Schlüssel wie age oder KMS, und der External Secrets Operator holt Secrets aus Vaults. Welche Lösung passt, hängt von Teamgröße, Cloud-Provider und vorhandener Infrastruktur ab.


Secrets in GitOps: Das Grundproblem

GitOps verlangt, dass der gesamte Cluster-State in Git liegt. Kubernetes Secrets sind aber nur Base64-kodiert — nicht verschlüsselt. Wer ein Secret als YAML committed, legt Passwörter praktisch im Klartext ab.

Drei Tools lösen dieses Problem auf unterschiedliche Weise. Hier ist ein praxisnaher Vergleich.

# So NICHT — Base64 ist keine Verschlüsselung
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  password: cGFzc3dvcmQxMjM=  # echo -n "password123" | base64

Sealed Secrets (Bitnami)

Sealed Secrets besteht aus einem Controller im Cluster und dem CLI-Tool kubeseal. Der Controller generiert ein asymmetrisches Schlüsselpaar. Du verschlüsselst lokal mit dem Public Key — entschlüsseln kann nur der Controller im Cluster.

Installation

# Controller installieren
helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
helm install sealed-secrets sealed-secrets/sealed-secrets \
  --namespace kube-system

# CLI installieren
# macOS
brew install kubeseal
# Linux
KUBESEAL_VERSION=0.27.3
curl -LO "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz"
tar -xzf kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz
sudo mv kubeseal /usr/local/bin/

SealedSecret erstellen

# Normales Secret erstellen (wird nicht applied)
kubectl create secret generic db-credentials \
  --from-literal=password=mein-sicheres-pw \
  --dry-run=client -o yaml > secret.yaml

# Mit kubeseal verschlüsseln
kubeseal --format yaml < secret.yaml > sealed-secret.yaml

Das Ergebnis ist eine SealedSecret-Ressource, die sicher in Git committed werden kann:

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: db-credentials
  namespace: default
spec:
  encryptedData:
    password: AgBy3i4OJSWK+PiTySYZZA9rO...  # RSA-verschlüsselt
  template:
    metadata:
      name: db-credentials

Der Controller entschlüsselt die SealedSecret automatisch und erstellt daraus ein normales Kubernetes Secret.

Mozilla SOPS mit age

SOPS (Secrets OPerationS) verschlüsselt einzelne Werte innerhalb von YAML- oder JSON-Dateien. In Kombination mit age brauchst du keinen Cloud-KMS — nur ein Schlüsselpaar.

Setup mit age

# age installieren
# macOS
brew install age
# Linux
sudo apt install age

# Schlüsselpaar generieren
age-keygen -o age-key.txt
# Public key: age1abc123...

# SOPS installieren
brew install sops  # oder via GitHub Release

Konfiguration

Erstelle eine .sops.yaml im Repository-Root:

creation_rules:
  - path_regex: .*\.secret\.yaml$
    age: "age1abc123def456..."  # Dein Public Key
  - path_regex: .*\.enc\.yaml$
    age: "age1abc123def456..."

Secrets verschlüsseln

# Secret-Datei verschlüsseln
sops --encrypt --in-place k8s/overlays/prod/db.secret.yaml

# Zum Bearbeiten (entschlüsselt temporär im Editor)
sops k8s/overlays/prod/db.secret.yaml

# Entschlüsseln
sops --decrypt k8s/overlays/prod/db.secret.yaml

SOPS verschlüsselt nur die Werte, nicht die Schlüssel. Das macht Diffs lesbar:

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
data:
  password: ENC[AES256_GCM,data:abc123...,tag:xyz...]
sops:
  age:
    - recipient: age1abc123...
      enc: |
        -----BEGIN AGE ENCRYPTED FILE-----

SOPS mit Flux CD

Flux hat native SOPS-Integration. Der Decryption-Key wird als Secret im Cluster hinterlegt:

# age-Key als Secret im Cluster
kubectl create secret generic sops-age \
  --namespace flux-system \
  --from-file=age.agekey=age-key.txt

# In der Kustomization SOPS aktivieren
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: app-secrets
  namespace: flux-system
spec:
  decryption:
    provider: sops
    secretRef:
      name: sops-age
  path: ./k8s/overlays/prod
  sourceRef:
    kind: GitRepository
    name: main-repo

External Secrets Operator

Der dritte Ansatz: Secrets liegen gar nicht in Git, sondern in einem externen Secret Store (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault). Der External Secrets Operator synchronisiert sie in den Cluster.

helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets \
  --namespace external-secrets --create-namespace
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: db-credentials
  data:
    - secretKey: password
      remoteRef:
        key: production/database
        property: password

Vergleich der drei Ansätze

KriteriumSealed SecretsSOPS + ageExternal Secrets
Secrets in GitJa (verschlüsselt)Ja (verschlüsselt)Nein (nur Referenz)
Externe AbhängigkeitKeineKeineVault/Cloud KMS
ArgoCD-IntegrationNativPlugin nötigNativ
Flux-IntegrationVia ControllerNativVia Controller
Key-RotationController-RestartRe-EncryptAutomatisch
Multi-ClusterUmständlichEinfachEinfach

Sealed Secrets eignet sich für Teams, die alles in Git haben wollen und einen einzelnen Cluster betreiben. Der Nachteil: Der Private Key lebt nur im Cluster. Bei Cluster-Verlust ohne Key-Backup sind alle Secrets verloren.

SOPS ist flexibler bei Multi-Cluster-Setups. Derselbe verschlüsselte File funktioniert überall, wo der age-Key verfügbar ist. Flux-Nutzer profitieren von der nativen Integration.

External Secrets passt zu Organisationen, die bereits einen zentralen Secret Store betreiben. Secrets werden nie in Git gespeichert — dafür braucht man aber stabile Netzwerkverbindungen zum Store.

ArgoCD-Integration

Für ArgoCD mit Sealed Secrets brauchst du keine Extra-Konfiguration — der Controller läuft im Cluster und verarbeitet SealedSecret-Ressourcen automatisch.

Für SOPS mit ArgoCD gibt es das argocd-vault-plugin oder den Weg über ein Init-Container-Setup mit Kustomize:

# argocd-repo-server Patch für SOPS
apiVersion: apps/v1
kind: Deployment
metadata:
  name: argocd-repo-server
  namespace: argocd
spec:
  template:
    spec:
      containers:
        - name: argocd-repo-server
          env:
            - name: SOPS_AGE_KEY_FILE
              value: /app/config/age/age-key.txt
          volumeMounts:
            - name: age-key
              mountPath: /app/config/age
      volumes:
        - name: age-key
          secret:
            secretName: sops-age-key

FAQ

Welche Lösung ist am einfachsten für den Einstieg?

Sealed Secrets. Installation dauert unter fünf Minuten, und der Workflow ist simpel: Secret erstellen, kubeseal ausführen, Ergebnis committen. Kein externes Key-Management nötig.

Was passiert bei Sealed Secrets, wenn der Cluster neu aufgesetzt wird?

Ohne Backup des Signing-Keys kannst du bestehende SealedSecrets nicht mehr entschlüsseln. Sichere den Key regelmäßig: kubectl get secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key -o yaml > sealed-secrets-key-backup.yaml

Kann ich SOPS und Sealed Secrets kombinieren?

Technisch ja, aber es erhöht die Komplexität ohne klaren Vorteil. Entscheide dich für einen Ansatz pro Cluster oder Umgebung.

Wie funktioniert Key-Rotation bei SOPS?

Neuen age-Key generieren, .sops.yaml aktualisieren, dann alle Dateien neu verschlüsseln: find . -name "*.secret.yaml" -exec sops updatekeys {} \;. Der alte Key kann danach entfernt werden.

Ist der External Secrets Operator auch ohne Cloud nutzbar?

Ja, mit HashiCorp Vault als Backend. Vault kann on-premises laufen und unterstützt alle Features des External Secrets Operators inklusive automatischer Rotation.


Nächster Schritt: Wenn du bereits ArgoCD nutzt, starte mit Sealed Secrets für einzelne Cluster oder SOPS für Multi-Cluster-Setups. Für eine umfassende GitOps-Einführung mit ArgoCD lies unseren ArgoCD ApplicationSet Guide.

Kubernetes-Expertise gesucht?

Managed Services, Beratung, Training oder Security – wir unterstützen deutsche Unternehmen bei allen Kubernetes-Themen.

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