SOPS vs. Age: Secrets verschlüsselt in Git speichern

Secrets in Git zu speichern gilt als Anti-Pattern — doch mit den richtigen Tools wird es zur sicheren Praxis. SOPS (Secrets OPerationS) und Age sind zwei Werkzeuge, die Secrets verschlüsseln, bevor sie ins Repository landen. Beide ergänzen sich häufig, adressieren aber unterschiedliche Probleme. Dieser Vergleich zeigt, wie sie funktionieren, wo sie sich unterscheiden — und wie man sie in GitOps-Workflows mit Kubernetes einsetzt.

Das Problem: Secrets in Git

Kubernetes-Manifeste, Helm-Values und GitOps-Repos enthalten regelmäßig sensible Daten: API-Keys, Datenbankpasswörter, TLS-Zertifikate. Wer diese unverschlüsselt committet, riskiert Datenlecks. Die typischen Lösungen:

  • Sealed Secrets / External Secrets Operator: Secrets werden im Cluster verwaltet, nicht im Repo (vgl. External Secrets vs. Sealed Secrets)
  • Vault: Zentrales Secrets-Management außerhalb von Git (vgl. Vault vs. Infisical)
  • SOPS + Age/GPG: Secrets verschlüsselt in Git speichern — der Fokus dieses Artikels

Was ist Age?

Age (ausgesprochen wie das englische Wort "age") ist ein minimalistisches Verschlüsselungs-Tool, das 2021 von Filippo Valsorda (Google) veröffentlicht wurde. Das Designziel ist Einfachheit: keine Konfigurationsdateien, keine Schlüsselbunde, kein PGP-Overhead.

Age verschlüsselt beliebige Dateien:

# Schlüsselpaar erstellen
age-keygen -o ~/.config/age/key.txt
# Ausgabe: Public Key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p

# Datei verschlüsseln
age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p secrets.yaml > secrets.yaml.age

# Datei entschlüsseln
age -d -i ~/.config/age/key.txt secrets.yaml.age > secrets.yaml

Age unterstützt:

  • X25519 (Standard): Modernes Elliptic-Curve-Kryptographie
  • SSH-Schlüssel: Bestehende SSH-Keys als Empfänger nutzen
  • Passphrase-Verschlüsselung: Für interaktive Nutzung
  • Plugin-System: Erweiterbar für Hardware-Security-Keys (YubiKey via age-plugin-yubikey)

Age ist kein vollständiges Secrets-Management-System — es verschlüsselt Binärdateien und Textdateien, kennt aber keine Struktur. Hier kommt SOPS ins Spiel.

Was ist SOPS?

SOPS (Mozilla, 2017) ist ein CLI-Tool und eine Bibliothek, die strukturierte Dateien (YAML, JSON, ENV, INI) partiell verschlüsselt. Der Schlüssel: SOPS verschlüsselt nur die Werte, nicht die Schlüsselnamen. Das Ergebnis ist lesbar und diff-bar in Git:

# Originaldatei (secrets.yaml)
database:
  password: "meinSicheresPasswort123!"
  host: "db.example.com"
api_key: "sk-abc123xyz"

# Nach SOPS-Verschlüsselung mit Age
database:
  password: ENC[AES256_GCM,data:xyz...,iv:...,tag:...,type:str]
  host: db.example.com  # NICHT verschlüsselt (kein Geheimnis)
api_key: ENC[AES256_GCM,data:abc...,iv:...,tag:...,type:str]
sops:
  age:
  - recipient: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
    enc: |
      -----BEGIN AGE ENCRYPTED FILE-----
      ...
      -----END AGE ENCRYPTED FILE-----
  lastmodified: "2026-09-11T08:00:00Z"
  version: 3.8.1

SOPS unterstützt als Verschlüsselungs-Backend:

  • Age (empfohlen für neue Setups)
  • GPG (historisch, komplexer)
  • AWS KMS, Azure Key Vault, GCP KMS (für Cloud-Umgebungen)
  • HashiCorp Vault Transit (für On-Premises-Enterprises)

SOPS + Age: Die optimale Kombination

SOPS und Age sind komplementär, nicht konkurrierend. Age ist der Verschlüsselungs-Algorithmus; SOPS ist der Orchestrator, der entscheidet, was verschlüsselt wird und wie Schlüssel verwaltet werden.

Konfiguration

# .sops.yaml (im Repo-Root)
creation_rules:
  - path_regex: k8s/.*\.yaml$
    age: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
  - path_regex: .*/secrets/.*
    age: >-
      age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p,
      age1team_member_2_public_key
# Secret erstellen und verschlüsseln
sops --encrypt secrets/db.yaml > secrets/db.enc.yaml

# Secret bearbeiten (öffnet Editor, speichert verschlüsselt)
sops secrets/db.enc.yaml

# In CI/CD entschlüsseln
export SOPS_AGE_KEY_FILE=~/.config/age/key.txt
sops --decrypt secrets/db.enc.yaml | kubectl apply -f -

Multi-Empfänger: Teamzugang

Ein wichtiger Vorteil von SOPS: Eine Datei kann für mehrere Schlüssel verschlüsselt werden. Jedes Teammitglied und jede CI/CD-Pipeline erhält eigene Age-Schlüssel — niemand teilt denselben privaten Schlüssel.

# Neuen Empfänger hinzufügen
sops --rotate --add-age age1NEW_TEAM_MEMBER secrets/db.enc.yaml

GitOps-Integration: Argo CD und Flux

Argo CD mit SOPS (via argocd-vault-plugin)

# Application mit SOPS-Entschlüsselung
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  annotations:
    argocd.argoproj.io/hook: PreSync
spec:
  source:
    plugin:
      name: argocd-vault-plugin

Moderner Ansatz: argocd-cmp-plugin mit SOPS direkt als Config Management Plugin:

# argocd-cm ConfigMap
configManagementPlugins: |
  - name: sops
    generate:
      command: ["sh", "-c"]
      args: ["sops -d $ARGOCD_APP_SOURCE_PATH/secrets.yaml | kubectl apply -f -"]

Flux CD mit SOPS (nativ unterstützt)

Flux hat native SOPS-Unterstützung seit v2 — kein Plugin nötig:

# flux-system/gotk-sync.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: my-app
spec:
  decryption:
    provider: sops
    secretRef:
      name: sops-age  # Secret mit dem privaten Age-Schlüssel
  sourceRef:
    kind: GitRepository
    name: my-repo
# Age-Schlüssel als Kubernetes-Secret für Flux
kubectl create secret generic sops-age   --namespace=flux-system   --from-file=age.agekey=~/.config/age/key.txt

SOPS vs. Age: Feature-Vergleich

Feature Age (direkt) SOPS + Age
Struktur-bewusst Nein (alles oder nichts) Ja (nur Values)
Git-Diff-freundlich Nein (ganze Datei binär) Ja (Schlüssel sichtbar)
Multi-Empfänger Via Age-Optionen Native, konfigurierbar
KMS-Integration Nein Ja (AWS/Azure/GCP)
Rotation Manuell sops --rotate
Kubernetes-Native Via kubectl Via Flux/Argo-Plugin
Lernkurve Minimal Niedrig-mittel

Vergleich mit alternativen Ansätzen

Ansatz Vorteile Nachteile
SOPS + Age Git-nativ, diff-bar, offline Key-Distribution manuell
Sealed Secrets Kubernetes-nativ, einfach Nur für K8s, kein GitOps-Editor
External Secrets Vault/AWS-Integration Externe Abhängigkeit
GPG statt Age Weit verbreitet Komplexer, veraltetes UX
Vault + KV Enterprise-ready Mehr Infrastruktur

Wann SOPS + Age, wann Alternativen?

SOPS + Age ist optimal wenn:

  • Secrets verschlüsselt im Git-Repository liegen sollen
  • GitOps mit Flux oder Argo CD genutzt wird
  • Kein KMS-Dienst vorhanden ist (kein AWS/Azure/GCP)
  • Mehrere Teammitglieder Zugriff benötigen (Multi-Empfänger)
  • Diff-Sichtbarkeit in Pull-Requests wichtig ist

Alternativen bevorzugen wenn:

  • AWS/Azure/GCP im Einsatz: SOPS + KMS direkt (ohne Age)
  • Einfachster K8s-Setup: Sealed Secrets
  • Enterprise On-Premises: Vault Transit + External Secrets

Fazit

Age allein reicht für einfache Datei-Verschlüsselung. Wer YAML-/JSON-Dateien strukturiert verschlüsseln und mit GitOps-Tools wie Argo CD oder Flux nutzen möchte, braucht SOPS als Orchestrator über Age als Backend. Die Kombination SOPS + Age ist 2026 der Standard für GitOps-konforme Secret-Verwaltung ohne Cloud-KMS-Abhängigkeit.

Für Kubernetes-Umgebungen mit hohen Compliance-Anforderungen lohnt der Blick auf External Secrets Operator vs. Sealed Secrets und Vault vs. Infisical als ergänzende oder alternative Lösungen.

Weiterführende Artikel

Verwandte Technologien im Techradar