SOPS a age v roku 2026: Šifrovanie tajomstiev pre GitOps a Kubernetes
Praktický návod na SOPS + age pre GitOps: šifrovanie tajomstiev v Kubernetes s Fluxom a ArgoCD, hardvérové kľúče (YubiKey, TPM 2.0), rotácia a threat model pre rok 2026.
SOPS (Secrets OPerationS) je nástroj od CNCF, ktorý šifruje hodnoty v YAML, JSON, ENV a INI súboroch tak, aby ste tajomstvá mohli bezpečne commitovať do gitu. V kombinácii s age, moderným a minimalistickým šifrovacím nástrojom od Filippa Valsordu, dostávate v roku 2026 najčistejšie GitOps riešenie pre správu tajomstiev v Kubernetes, Terraforme a Ansible. Tento sprievodca vám ukáže celý pipeline: vygenerovanie kľúčov, integráciu s Flux a ArgoCD, hardvérovo viazané kľúče (YubiKey, TPM 2.0), rotáciu, threat model a to, čo v praxi zlyhá ako prvé.
SOPS 3.9 (december 2025) šifruje iba hodnoty. Kľúče zostávajú v čitateľnom tvare, takže diff v gite ostáva zmysluplný a pull requesty prehľadné.
age je predvolený backend pre tímové nasadenia bez cloudového KMS: 62-znakový verejný kľúč, žiadne konfigurovateľné parametre, žiadny footgun.
Pre Kubernetes v produkcii kombinujte SOPS s Fluxom (natívna podpora) alebo ArgoCD + KSOPS pluginom. Nikdy nedešifrujte tajomstvá v CI runneri.
Hardvérová izolácia cez age-plugin-yubikey alebo age-plugin-tpm znižuje blast radius: aj kompromitovaný workstation neexfiltruje privátny kľúč.
Rotácia je jednoduchá. Príkaz sops updatekeys re-šifruje DEK novým setom recipientov bez zmeny plaintextu, kľúčové rotácie robte kvartálne.
Threat model SOPS nezabraňuje bežcovi CI/CD prečítať dešifrované tajomstvo. Správnym miestom pre decryption je runtime target (kubelet, Terraform provider), nie build.
Prečo SOPS + age v roku 2026
Priznám sa. Keď som v roku 2019 prvý raz kreslila diagram pre secrets flow v Kubernetes, mala som na tabuli šesť boxov: Vault, konzumujúci pod, sidecar, init container, TLS pre komunikáciu, a niekde vzadu HSM. Bolo to bezpečné, ale krehké. Dnes tie isté tri deploymenty zvládame s dvoma binárkami (sops a age) a bez behajúceho secret store. Blast radius výpadku sa zmrštil z „nikto sa nedostane do klastra" na „posledný známy stav v gite platí".
SOPS bol pôvodne Mozilla projekt. V novembri 2023 sa presunul pod CNCF ako getsops/sops a od verzie 3.9 (december 2025) má stabilnú integráciu s age recipient formátom, natívnu podporu premennej SOPS_AGE_KEY_CMD pre dynamické načítanie kľúča a lepšie audit logy. Release notes na GitHube uvádzajú aj podporu pre age-plugin-* ekosystém, čo otvára cestu k YubiKey a TPM 2.0 recipientom bez zmeny SOPS súborov.
age (viď age-encryption.org) je „file encryption tool" špecifikovaný v jednom PDF. Nemá algoritmické voľby, nemá konfiguráciu, nemá session mode. To je bezpečnostná vlastnosť: čím menej gombíkov, tým menej príležitostí pre chybnú konfiguráciu. Verejný kľúč vyzerá takto: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p. Presne 62 znakov, žiadny format flag.
Kombinácia rieši reálny problém, ktorý mám každý deň: ako dostať heslo databázy do produkčného clusteru bez toho, aby som ho niekedy videla v čitateľnom tvare v gite, v CI logu alebo v Slack správe. Odpoveď je jednoduchá. Nezobrazuje sa nikde, decryption prebehne až v cieli (kubelet cez Flux Kustomize controller, Terraform provider, Ansible callback).
Threat model: čo SOPS chráni a čo nie
Než napíšem prvý príkaz, opýtam sa vždy to isté: čo praskne ako prvé, keď mi útočník získa X? Pre SOPS + age vyzerá threat model takto:
Chráni pred: náhodným leakom cez git push, exfiltráciou repozitára, čítaním backupu, kompromitáciou build serveru, ktorý nemá privátny kľúč.
Nechráni pred: kompromitáciou nody, kde beží dekryptor (kubelet s privátnym kľúčom v tmpfs), kompromitáciou developerského notebooku s privátnym kľúčom, cieleným útokom na PR (útočník pridá recipient s vlastným verejným kľúčom).
Ten posledný bod je subtílny a dôležitý. SOPS umožňuje komukoľvek s prístupom k plaintextu pridať nového recipienta, pretože reencryption s novým setom kľúčov je bežná operácia. Preto musíte v CI vynútiť, že sa .sops.yaml a recipient listy v hlavičkách zašifrovaných súborov nemenia mimo dvoch schválených procesov: onboarding a rotácia. Kontrolu urobte v pre-merge hooku, ktorý porovná recipient listy so „schváleným zoznamom" v samostatnom, chránenom mieste (napr. GitHub environment secret alebo Vault KV).
Druhý blast-radius reflex: kde privátny kľúč skutočne žije? Na developer workstation v ~/.config/sops/age/keys.txt je to iba súbor. Root a útočník s kernel exploitom ho prečítajú. Ak to nie je akceptovateľné (a pre produkčné kľúče určite nie je), presuňte ho do YubiKey alebo TPM (viď sekcia nižšie). Pre bezpečnosť runtime prostredia, ktoré rozbaľuje tajomstvá, pozri aj spevnenie systemd služieb a sandboxing. Dešifrovací proces by mal bežať s minimálnym syscall setom.
Inštalácia SOPS 3.9 a age 1.2 na Linuxe
Na Debiane 13 (Trixie), Ubuntu 24.04 LTS aj Fedore 41 sťahujte priamo z GitHub releases. Distribučné balíky často zaostávajú o niekoľko verzií a stratíte tak podporu pre age plugin API. Overte SHA256 checksum a podpis:
Pre kompletnú reprodukovateľnosť build pipeline si všímajte, či vaša distribúcia binárok ponúka aj podpisy Sigstore Cosign. Je to nový štandard pre CNCF projekty. Ak vás zaujíma hlbšie fungovanie keyless podpisov, prečítajte si Sigstore Cosign v roku 2026: keyless podpisovanie a SLSA atestácie.
Vygenerujte primárny age kľúč pre svoj tím. Konvencia, ktorá sa mi osvedčila: každý developer má vlastný kľúč, plus per-environment „deployment" kľúč držaný v Kubernetes secrete alebo hardvéri:
mkdir -p ~/.config/sops/age
age-keygen -o ~/.config/sops/age/keys.txt
chmod 600 ~/.config/sops/age/keys.txt
# public key vypíše na stderr
# Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
Prvý zašifrovaný secret krok za krokom
Ukážem produkčnú konfiguráciu, aká beží u mňa v tíme. Vytvorte v repozitári .sops.yaml, konfiguračný súbor, ktorý povie SOPS-u, ktoré cesty šifrovať akými recipientmi:
Vytvorte plaintext YAML a zašifrujte ho. Kľúčové: encrypted_regex zaisťuje, že iba data a stringData polia sú zašifrované. Metadata (menný priestor, labely, anotácie) ostávajú čitateľné, čo umožňuje Kustomize prekrytia a diff v pull requestoch:
Otvorte súbor v editore. Uvidíte, že username, password a connection sú nahradené blobmi tvaru ENC[AES256_GCM,data:...,iv:...,tag:...,type:str], zatiaľčo metadata.name, namespace a všetky YAML kľúče sú čitateľné. Na konci pribudne sops: sekcia s recipient listom a MAC-om celého súboru. MAC deteguje aj tampering s poradím kľúčov, nielen s hodnotami.
Editovanie prebieha priamo cez sops kubernetes/prod/db-credentials.enc.yaml. Otvorí sa $EDITOR s dešifrovaným obsahom a po uložení sa opäť zašifruje. Nikdy nedešifrujte cez sops -d do súboru, ktorý potom omylom commitnete (áno, tú chybu som už spravila).
SOPS v Kubernetes: Flux, ArgoCD a KSOPS
Flux CD má SOPS zabudovaný priamo v kustomize-controller-i od verzie 2.0. To je najčistejší setup, aký v roku 2026 poznám. Žiadny sidecar, žiadny webhook, žiadny operator navyše. Nasadíte age privátny kľúč ako Kubernetes secret v flux-system namespace a Flux ho automaticky použije pri reconciliácii:
ArgoCD nemá SOPS v jadre, takže musíte použiť KSOPS plugin ako custom Config Management Plugin. Setup je zložitejší (build vlastného ArgoCD image alebo sidecar), ale funguje spoľahlivo. Pre nové inštalácie odporúčam Flux, pre existujúce ArgoCD deploymenty KSOPS.
Dôležitý bezpečnostný detail: kubelet vidí dešifrované tajomstvá ako obyčajný Kubernetes Secret v etcd (base64, nezašifrované). Ak túto expozíciu chcete odstrániť, kombinujte SOPS s etcd encryption at rest (EncryptionConfiguration s kms alebo aescbc providerom). Bez toho ste len presunuli plaintext z gitu do etcd. Pre kompletné zabezpečenie kontajnerového runtime pozri zabezpečenie kontajnerov na Linuxe 2026.
Hardvérovo viazané kľúče: YubiKey a TPM 2.0
Súbor keys.txt na disku je najslabší článok reťaze. Útočník s prístupom k user home directory ho prečíta a získa dešifrovaciu schopnosť všetkých tajomstiev, ktoré ste kedy commitovali. Riešenie? Privátny kľúč nikdy neopustí hardvérový bezpečnostný modul.
Pre YubiKey 5 (firmware 5.7+) použite age-plugin-yubikey. Kľúč sa vygeneruje priamo na karte v PIV slote a nikdy z nej nevyjde:
cargo install age-plugin-yubikey
# alebo cez binárku z github.com/str4d/age-plugin-yubikey/releases
age-plugin-yubikey --generate \
--slot 1 \
--name aisha-workstation \
--touch-policy cached \
--pin-policy once
# vypíše verejný kľúč pre .sops.yaml:
# age1yubikey1qwt50d05nh5vutpdzmlg5wn80xq5negm4uvpl0u0nq9h5f0uezwc5rk8dhc
Pri každej SOPS operácii vás plugin vyzve k dotyku YubiKey. Human presence check zabraňuje malware-u dešifrovať tajomstvá v pozadí. Pre serverovú stranu (deployment kľúč v Kubernetes clusteri) použite age-plugin-tpm, ktorý viaže kľúč na TPM 2.0 čip serveru. Aj keď útočník získa root, kľúč nedokáže exfiltrovať bez fyzického prístupu k TPM.
Toto je Zero Trust prístup v praxi: identita kľúča je viazaná na fyzické zariadenie, nie na filesystém, ktorý sa dá skopírovať. Pre kritické tajomstvá (databázové heslá produkcie, root CA kľúče) je hardvérová izolácia povinným minimom, nie voľbou. age-plugin-tpm repo obsahuje detailný setup pre svTPM v QEMU aj reálne TPM 2.0 čipy.
Integrácia s Terraformom a Ansible
SOPS nie je len pre Kubernetes. Terraform provider carlpett/sops umožňuje priamo čítať zašifrované súbory ako data source:
Varovanie: Terraform state súbor obsahuje plaintext hodnoty. Ukladajte state do S3 s KMS encryption a povoľte use_lockfile = true pre S3 native lock (Terraform 1.10+). Nikdy neukladajte state lokálne alebo v gite.
Pre Ansible je najčistejšia integrácia cez community plugin community.sops:
Ansible callback plugin automaticky rozpozná SOPS súbory podľa sops: hlavičky a dešifruje ich in-memory. Rovnaký privátny kľúč z ~/.config/sops/age/keys.txt sa použije transparentne.
Rotácia kľúčov a offboarding členov tímu
Kľúčová vlastnosť SOPS-u: dešifruje sa data encryption key (DEK) unikátny pre každý súbor, nie samotný obsah. To znamená, že rotácia recipient listu je O(n) v počte súborov, ale nemení plaintext. Diff v gite bude minimálny (zmení sa iba sops: sekcia).
Spustite find . -name '*.enc.yaml' -exec sops updatekeys --yes {} \;. SOPS re-šifruje DEK novým setom recipientov.
Commitnite zmeny. Diff bude obsahovať iba zmenené sops: hlavičky.
Kľúč, ktorý mal odchádzajúci člen, sa síce nedá „revoknúť" (kryptografická matematika je jednosmerná), ale všetky budúce commity a nové tajomstvá sú pre neho nedostupné.
Pre tajomstvá, ktoré ex-člen mohol lokálne dešifrovať pred odchodom, spustite rotáciu samotných tajomstiev: vygenerujte nové DB heslá, API tokeny a podobne. Toto je najdôležitejší krok, ktorý sa často vynechá.
Tip: Automatizujte kvartálnu rotáciu deployment kľúčov cez cron alebo Kubernetes CronJob. Pridajte alert do SIEM-u (napr. Wazuh) na neočakávané volanie sops --decrypt mimo CI runnera.
SOPS vs Sealed Secrets vs External Secrets Operator
Tri najčastejšie riešenia pre Kubernetes secrets management v roku 2026. Každé rieši iný problém, takže voľba závisí od threat modelu a operačných možností:
Vlastnosť
SOPS + age
Sealed Secrets
External Secrets Operator
Cieľové úložisko tajomstva
Git (šifrované)
Git (šifrované)
Externý store (Vault, AWS SM)
Diff v pull requestoch
Áno (metadata čitateľné)
Nie (celý blob)
N/A (v gite nie sú tajomstvá)
Rotácia master kľúča
sops updatekeys, minimálny diff
Kubectl re-encrypt, celý blob sa mení
Rotujete v external store
Multi-cluster deploy
Jeden git source, N klastrov
Kľúč per klaster, secrets per klaster
Vault referuje z ľubovoľného klastra
Závislosť runtime
Žiadna (build-time decrypt)
Sealed-secrets-controller
ESO + external store dostupný
Hardvérová izolácia kľúča
Áno (age-plugin-yubikey/tpm)
Nie (kľúč v Kubernetes secrete)
Nepriamo (cez Vault)
Vhodné pre
GitOps, malé/stredné tímy
Jednoduché deployments
Enterprise s existujúcim Vault
Ak nemáte HashiCorp Vault alebo cloudový secret manager, SOPS + age je najlepšia voľba. Ak máte Vault, kombinujte ESO pre bežné tajomstvá a SOPS pre bootstrap (Vault admin token, unseal keys). Je to jediný spôsob, ako uzavrieť „secret zero" problém bez ručného zásahu.
Časté otázky
Je SOPS bezpečnejší ako Sealed Secrets?
Obe šifrujú tajomstvá pre bezpečné uloženie v gite. SOPS ponúka lepšiu čitateľnosť diffov (iba hodnoty sú šifrované, metadata zostávajú v plaintexte) a nezávislosť od klastrového controlleru. Sealed Secrets viaže kľúč na konkrétny klaster, čo komplikuje multi-cluster deploy. Pre nové projekty v roku 2026 odporúčam SOPS + age; Sealed Secrets ostáva relevantný len pre legacy setupy.
Môžem použiť SSH kľúč miesto age kľúča?
Áno, age natívne podporuje SSH Ed25519 a RSA verejné kľúče ako recipientov. Stačí v .sops.yaml uviesť ssh-ed25519 AAAA.... SOPS ich prevedie cez age wrapper. Pre nové kľúče odporúčam natívne age kľúče (kratšie, jednoduchšie), ale reuse existujúcich SSH kľúčov je pohodlný spôsob onboardingu.
Ako zálohovať age privátny kľúč?
Vytlačte ho na papier v QR kódoch a uložte do trezoru, alebo použite rage (Rust implementácia) s --passphrase pre offline zálohovanie. Nikdy neposielajte privátny kľúč cez email alebo cloudový storage bez ďalšej vrstvy šifrovania. Pre YubiKey si vygenerujte druhý fyzický kľúč ako backup, priradený k rovnakému recipientovi v .sops.yaml.
Čo sa stane, keď stratím jediný privátny kľúč, ktorý dokáže dešifrovať produkčné tajomstvá?
Tajomstvá sú kryptograficky nedostupné, SOPS nemá backdoor. Preto musíte mať vždy minimálne dva nezávislé recipient kľúče v každom .sops.yaml: primárny (napr. váš YubiKey) a záložný (napr. deployment TPM alebo offline printed backup). Toto je jediné poistenie proti výpadku.
Prečo age a nie PGP/GnuPG?
PGP má 40 rokov naakumulovanej komplexity: web of trust, subkeys, expirácie, revocation certificates, algoritmické voľby. Väčšina týchto funkcií je pre secrets management v gite zbytočná a zvyšuje šancu na chybnú konfiguráciu. age má jeden algoritmus (X25519 + ChaCha20-Poly1305), žiadne voľby, žiadne metadata. Filippo Valsorda ho navrhol práve preto, aby nahradil PGP pre file encryption use case.
Nastavte automatické odomykanie LUKS diskov na Linuxe cez NBDE (Clevis + Tang) alebo TPM2 sealing pomocou systemd-cryptenroll. Praktický sprievodca s SSS threshold politikou, evil maid ochranou a rotáciou kľúčov v roku 2026.
Kompletný sprievodca nasadením Falco 0.41 na Linux a Kubernetes s modern_ebpf driverom. YAML pravidlá, Falcosidekick, automatická remediation cez Talon a mapovanie detekcií na MITRE ATT&CK for Containers.
Kompletný sprievodca inštaláciou, konfiguráciou a automatizáciou AIDE 0.19 na RHEL 10, Debian 13 a Ubuntu 26.04. Systemd timery, ochrana databázy pred manipuláciou, integrácia s Wazuh SIEM a mapovanie na CIS, PCI DSS a NIST compliance.