Secrets Management op Linux met sops en age: GitOps-veilige Encryptie in 2026
Sops en age zijn de de-facto standaard voor versleutelde secrets in Git. Deze gids behandelt installatie, KMS-integratie, GitOps-workflow met pre-commit hooks, Kubernetes-deployment en sleutelrotatie. Met werkende voorbeelden voor productie in 2026.
Secrets management op Linux met sops en age is de praktijk van het versleutelen van gevoelige configuratiebestanden (wachtwoorden, API-tokens, TLS-sleutels) met asymmetrische cryptografie, zodat ze veilig in Git kunnen worden gecommit en automatisch worden ontsleuteld op het moment van deployment. Sops (Secrets OPerationS) regelt het versleutelen op veld-niveau van YAML, JSON en .env-bestanden. Age levert moderne, audit-vriendelijke cryptografie zonder de PGP-complexiteit. In dit artikel deel ik het dreigingsmodel, de blast radius bij sleutelverlies, en een werkende GitOps-workflow die ik bij hyperscale-deployments inzet.
Sops 3.9 en age v1.2 vormen samen de de-facto standaard voor versleutelde Git-secrets in 2026, met ondersteuning voor KMS-providers, YubiKeys en SSH-sleutels.
Age gebruikt X25519 + ChaCha20-Poly1305 en is bewust simpeler dan GPG. Geen web of trust, geen subkeys, geen revocation lists, dus minder voetschoten.
Sops versleutelt alleen waardes (niet sleutels), waardoor diffs leesbaar blijven en code review werkbaar is.
De grootste blast-radius-fout is een gelekte private key zonder rotatie-plan. Gebruik altijd KMS of een hardware-token voor productie-secrets.
Een pre-commit hook met sops-detectie voorkomt dat klare-tekst secrets per ongeluk naar GitHub lekken.
Integratie met Kubernetes loopt via de SOPS operator of Helm-secrets plugin. Voor CI/CD gebruik je een KMS-rol of een sealed deploy-sleutel.
Waarom sops en age in 2026?
Eerlijk gezegd is dit de vraag waar elk security-architectuurgesprek over secrets mee begint: "wat breekt er als deze repo lekt?" Als het antwoord is "een aanvaller heeft direct productiewachtwoorden", dan is je secrets-management kapot. Sops en age zijn er om dat antwoord te veranderen in: "een aanvaller heeft versleutelde blobs zonder de KMS-rol om ze te ontsleutelen."
Sops, oorspronkelijk gebouwd door Mozilla en nu onderhouden door de CNCF, versleutelt waarden in gestructureerde bestanden (niet de hele file). Dat is de slimste design-keuze van het project. Sleutelnamen blijven leesbaar, diffs blijven reviewbaar, en je verliest geen Git-blame. Age, het project van Filippo Valsorda (voormalig Go security lead), is de bewust-simpele opvolger van GPG voor file-encryptie. Geen subkeys, geen trust web, geen ~/.gnupg-doolhof. Alleen X25519, ChaCha20-Poly1305 en een leesbaar formaat.
In 2026 is dit duo om drie redenen dominant geworden. Ten eerste: de meeste DevSecOps-pipelines draaien op GitOps, en GitOps eist dat secrets in Git leven. Ten tweede: cloud-KMS-integratie (AWS, GCP, Azure, HashiCorp Vault) is in sops productiestabiel, dus je private key hoeft nooit op een laptop te liggen. Ten derde: de getsops upstream heeft in 2025 het beheer overgenomen van Mozilla en het release-tempo verviervoudigd, met versie 3.9 als referentiepunt voor moderne deployments.
Dreigingsmodel en blast radius
Voordat je een tool kiest, teken je het dreigingsmodel. Stel je een betonnen blokje voor met drie deuren: één voor de developer die secrets toevoegt, één voor CI/CD die ze leest tijdens deploys, en één voor de runtime-host die ze gebruikt. Elke deur is een potentieel lekpunt.
De aanvalsoppervlakken die ik in incident reviews het vaakst tegenkom:
Git-lekken: een developer commit per ongeluk een klare-tekst .env. Hier helpt sops weinig als de hook niet draait, en daarom is pre-commit detectie non-negotiable.
Endpoint-compromitatie: developer-laptop wordt gestolen of geïnfecteerd. Als de private age-sleutel onversleuteld op disk staat, is alle productie compromittabel. Mitigatie: passphrase-encryptie van de sleutel, of liever YubiKey/KMS zodat de sleutel het apparaat nooit verlaat.
CI/CD-compromitatie: een aanvaller krijgt toegang tot een GitHub Actions runner. Hier wil je dat de runner een KMS-rol met scope-limiet heeft, niet een statische private key in een repo-secret.
Insider threat: een ex-medewerker heeft de sleutel nog. Rotatie zonder dataverlies is een test waar veel teams op zakken.
De blast radius bij een gelekte sops-sleutel is alles wat ooit met die sleutel is versleuteld in elke commit ooit. Git-historie vergeet niets. Dus rotatie betekent niet alleen nieuwe versleuteling, het betekent álle gelekte secrets ook bij de upstream-services (AWS-IAM, database-wachtwoorden, API-tokens) intrekken. Een goed beleid voor AppArmor-profielen op Ubuntu en Debian of systemd service hardening met sandbox-directieven beperkt secundaire schade, maar het primaire lek moet je containen door rotatie.
Sops en age installeren op Linux
Op Ubuntu 24.04 LTS en Debian 13 zijn beide tools direct beschikbaar via apt, maar de versies lopen achter. Voor 2026-actuele features installeer je vanaf de GitHub-releases:
Verifieer altijd de checksum via het SHA256SUMS-bestand op de release-pagina, en voor productie-installs ook de cosign-signature die getsops sinds 2025 publiceert (zie de Sigstore cosign-documentatie voor verificatiestappen). Dit is geen overdrive. Je vertrouwt deze binaries met je hele productie-secrets-laag.
Genereer vervolgens een persoonlijke age-sleutel:
mkdir -p ~/.config/sops/age
age-keygen -o ~/.config/sops/age/keys.txt
chmod 600 ~/.config/sops/age/keys.txt
# Toont je public key — deze ga je in .sops.yaml opnemen
grep "public key" ~/.config/sops/age/keys.txt
Je eerste versleutelde secret
Sops gebruikt een .sops.yaml in de root van je repo om te bepalen wélke bestanden met wélke sleutels worden versleuteld. Hier is een minimale configuratie voor een team van drie:
De encrypted_regex is je vriend. Standaard versleutelt sops alle waarden, maar in een Kubernetes-manifest wil je vaak alleen de gevoelige velden versleutelen zodat de rest reviewbaar blijft. Maak nu je eerste secret:
mkdir -p secrets
cat > secrets/database.yaml <<EOF
host: db.prod.internal
port: 5432
username: app
password: please-change-me
EOF
sops --encrypt --in-place secrets/database.yaml
# Open het bestand: 'host' en 'port' zijn leesbaar; 'password' is versleuteld
sops --decrypt secrets/database.yaml | head
De diff in Git toont nu zoiets als password: ENC[AES256_GCM,data:...,iv:...,tag:...]. Een reviewer kan zien dat het wachtwoordveld verandert, zonder de waarde zelf te kennen. Dat is precies de eigenschap die sops bruikbaar maakt in code review, iets wat git-crypt en blackbox bewust niet leveren.
Wat is het verschil tussen age en gpg, en hoe gebruik je KMS?
Age verschilt van GPG op drie design-assen die er voor secrets management toe doen. GPG heeft een trust web, subkey-hiërarchie, en een bestandsformaat dat al sinds 1998 gegroeid is (meer dan 200 RFC-pagina's aan complexiteit). Age heeft één algoritme (X25519 + ChaCha20-Poly1305), één bestandsformaat (zie de age v1 spec), en geen trust-state op disk. Voor file-encryptie in CI/CD is dat een feature, geen beperking.
Voor productie wil je echter geen statische private key. Sops integreert direct met cloud-KMS-providers:
# .sops.yaml voor productie met AWS KMS
creation_rules:
- path_regex: secrets/prod/.*\.yaml$
kms: arn:aws:kms:eu-west-1:123456789012:key/abcd-1234-...
aws_profile: prod-secrets-rw
- path_regex: secrets/dev/.*\.yaml$
age: age1zxqf4q7nrhz3pmvw0u8m3rczwzz4xqkwm5lq6vwz8s9j2k0xv2usvm3hxw
De flow wordt: sops genereert lokaal een random data-key, versleutelt de waarden ermee, en versleutelt vervolgens die data-key met de KMS-rol. Het kostenmodel: één KMS-call per encrypt/decrypt-operatie, niet per secret. Voor YubiKey-gebruikers ondersteunt age sinds v1.1 een age-plugin-yubikey, waarmee de private key het apparaat nooit verlaat. Dat is mijn voorkeur voor laptops die buiten de office reizen.
GitOps-workflow met pre-commit hooks
De hardste les uit incident reviews: gereedschap dat niet automatisch draait, draait niet. Een sops-workflow zonder pre-commit hook is een lek wachtend om te gebeuren. Installeer pre-commit en voeg een sops-detectie toe:
Installeer de hooks met pre-commit install. Vanaf nu wordt elke commit die een onversleuteld bestand in secrets/ bevat geweigerd. Voeg in CI dezelfde check toe als gate (pre-commit kan lokaal worden overgeslagen, maar de CI-check niet).
Voor code review: configureer git diff om versleutelde files als binaire blobs te tonen, zodat reviewers niet per ongeluk in de inhoud kijken en zo cache-side-channels ontstaan. Voeg toe aan .gitattributes:
Een aanvulling op deze workflow is een software supply chain beveiliging strategie met SBOM en Sigstore. Als je secrets-tooling zelf gecompromitteerd wordt, is je hele keten kwetsbaar. Sigstore-signed releases van getsops zijn daar de eerste verdedigingslinie.
Kubernetes en CI/CD-integratie
Voor Kubernetes zijn er drie mainstream patronen om sops-files te ontsleutelen voordat ze als Secret-objecten in de cluster terechtkomen. Welke je kiest hangt af van je deployment-tool:
Flux + SOPS: de kustomization.yaml verwijst naar een SOPS-decryption-key (uit een KMS-rol op de cluster). Flux ontsleutelt at-apply-time. Zero extra tools.
Helm-secrets: de helm-secrets plugin wraps helm install met sops-decryptie. Goede match voor teams die al op Helm zitten.
Sealed Secrets (Bitnami): alternatief patroon, niet sops-gebaseerd. Versleutelt naar één controller-public-key. Eenvoudiger maar minder flexibel met multi-recipient en KMS.
Voor GitHub Actions ziet de typische CD-job er zo uit:
Belangrijke details: gebruik OIDC voor cloud-auth (geen statische access keys in GitHub-secrets), beperk de KMS-rol tot exact één key-ARN, en wis ontsleutelde bestanden na gebruik. Voor extra hardening kun je de runner zelf draaien op een ephemeral VM met een auditd-regel die elke sops --decrypt-call logt.
Sleutelrotatie en incidentrespons
De vraag die elk security-audit stelt: "kun je morgen alle secrets roteren?" Met sops is het antwoord ja, maar alleen als je de workflow ooit hebt geoefend. Ik heb dit zelf één keer onder druk moeten doen (ex-collega, half twee 's nachts, slecht idee om dit voor het eerst live te oefenen). Het basispatroon voor het toevoegen van een nieuwe recipient en het verwijderen van een gecompromitteerde:
# Nieuwe age-key toevoegen, oude verwijderen in .sops.yaml,
# vervolgens elk versleuteld bestand opnieuw versleutelen:
for f in $(find secrets/ -name '*.yaml'); do
sops updatekeys "$f"
done
git add secrets/ .sops.yaml
git commit -m "rotate: vervang compromitatie-verdachte sleutel X"
Belangrijke nuance: sops updatekeys verandert alleen wie de waarden kan ontsleutelen, de waarden zelf blijven gelijk. Als de sleutel echt gelekt is, moet je álle upstream-credentials (database-wachtwoorden, API-tokens) óók roteren bij de service-provider, want de Git-historie bevat nog versleutelde blobs die met de gelekte sleutel ontsleutelbaar zijn.
Voor compliance-audits leg ik altijd vast: rotatieschema (per kwartaal voor productie-sleutels, direct bij personeelswisselingen), incidentresponsplan (wie revoket de KMS-rol, wie rotateert upstream-credentials), en een quarterly dry-run waar het hele team de rotatie uitvoert in staging. Een procedure die niet wordt geoefend, werkt niet onder druk.
Sops versus HashiCorp Vault: wanneer kies je welk?
Dit is de vraag die ik in elk architecture review hoor. Beide tools doen secrets management, maar ze beantwoorden verschillende vragen.
Aspect
Sops + age
HashiCorp Vault
Opslagmodel
Versleutelde files in Git
Centrale server met API
Audit trail
Git-historie (commits, blames)
Volledige API-audit log
Dynamische secrets
Nee
Ja (DB-credentials, AWS STS, etc.)
Operationele complexiteit
Laag, geen server te beheren
Hoog: HA-cluster, unseal-procedure, backups
Latency bij read
0 ms (file read)
10–50 ms (netwerk-call)
Offline werkbaar
Ja (lokaal ontsleutelen)
Nee (server moet bereikbaar zijn)
Beste use case
Statische config-secrets, GitOps
Dynamische secrets, korte TTL's, brede org
Mijn praktijkadvies: gebruik sops voor configuratie-secrets (database-URLs, TLS-certs, third-party API-tokens) die met je code mee-deployen. Gebruik Vault voor dynamische, kortlevende secrets (database-credentials per workload, AWS-credentials per CI-run) waar rotatie geautomatiseerd moet zijn op de seconde nauwkeurig. Voor de meeste teams onder de 100 engineers is sops genoeg. Voor regulated industries (PCI-DSS, HIPAA) waar elke read auditbaar moet zijn, is Vault de juiste keuze. Sops' audit trail is je Git-historie en die laat niet zien wie wanneer ontsleuteld heeft op een laptop.
Veelgestelde vragen
Waar wordt sops voor gebruikt?
Sops wordt gebruikt om gevoelige velden in YAML-, JSON- en .env-bestanden te versleutelen zodat ze veilig in Git kunnen leven. Het versleutelt alleen waarden (niet sleutels), wat code review werkbaar houdt. Veel teams gebruiken het als kernonderdeel van hun GitOps-workflow met Flux of Argo CD.
Kun je versleutelde secrets veilig naar GitHub committen?
Ja, mits de versleuteling gebeurt met een recipient-key die niet in dezelfde repo staat. Sops met age of cloud-KMS is daarvoor ontworpen. Zorg wél voor een pre-commit hook die klare-tekst detecteert, en behandel de Git-historie als de aanvalsoppervlakte. Als de sleutel ooit lekt, zijn alle historische commits ontsleutelbaar.
Is age veiliger dan GPG?
Age is moderner en bewust simpeler dan GPG, met één algoritmecombinatie (X25519 + ChaCha20-Poly1305) en geen trust-web. Voor file-encryptie en sops-recipients is age praktischer en minder foutgevoelig. GPG blijft relevant voor e-mail en pakketten-signing waar bestaande infrastructuur op gebouwd is.
Hoe ontsleutel je sops-bestanden in een CI/CD-pipeline?
De aanbevolen aanpak is OIDC-federation met een cloud-KMS-rol: de CI-runner krijgt korte-termijn credentials van AWS, GCP of Azure en sops gebruikt die om de data-key te ontsleutelen. Vermijd statische private keys in CI-secrets; die zijn moeilijker te roteren en hebben een grotere blast radius.
Wat doe je bij een gelekte sops-sleutel?
Drie acties tegelijk: revoke de sleutel in .sops.yaml met sops updatekeys voor alle bestanden, rotateer álle upstream-credentials (database-wachtwoorden, API-tokens) bij de service-providers, en voer een audit uit op de Git-historie om te bepalen welke versleutelde blobs ooit toegankelijk waren. De Git-historie vergeet niets, dus assume dat alle ooit-versleutelde secrets gecompromitteerd zijn.
Stap-voor-stap AppArmor profielen schrijven op Ubuntu 24.04 en Debian 12 met aa-genprof en aa-logprof. Inclusief enforce mode, DENIED troubleshooting en systemd integratie.
Hard systemd-services met sandbox-directieven zoals ProtectSystem, DynamicUser en SystemCallFilter. Praktische drop-ins, scoring met systemd-analyze security en troubleshooting van een te strak gehard unit-bestand in 2026.
Leer hoe je de Linux-kernel verhardt met sysctl-parameters. Stap-voor-stap gids met netwerk-hardening, ASLR, eBPF-beveiliging, boot-parameters, kernel-hardening-checker audit en Ansible-automatisering — afgestemd op CIS Benchmarks 2026.