TL;DR — Résumé Rapide
SOPS chiffre les valeurs YAML/JSON en gardant les clés lisibles. Guide: age, KMS, rotation des clés, CI/CD, Kubernetes et intégration GitOps ArgoCD.
Mozilla SOPS (Secrets OPerationS) résout l’un des problèmes les plus difficiles de GitOps : comment stocker des secrets dans le contrôle de version sans les exposer. Contrairement aux outils qui chiffrent des fichiers entiers, SOPS chiffre uniquement les valeurs dans les fichiers YAML, JSON, ENV et INI — gardant les clés en clair pour que les diffs restent lisibles.
Pourquoi SOPS? Le Problème des Secrets dans Git
Committer des secrets en clair dans Git est un incident de sécurité en attente de se produire :
- Variables d’environnement uniquement — Fonctionne en runtime mais ne versionne pas les changements de secrets.
- Vault / External Secrets — Puissant mais nécessite une infrastructure et un accès en ligne.
- git-crypt — Chiffre des fichiers entiers ; les diffs deviennent des blobs binaires inutilisables.
- SOPS — Chiffre uniquement les valeurs. Les clés restent en clair. Les fichiers se comparent normalement.
Un fichier chiffré avec SOPS ressemble à ceci :
database:
password: ENC[AES256_GCM,data:abc123...,iv:...,tag:...,type:str]
host: db.example.com # ← non chiffré, pas un secret
Installation
# macOS
brew install sops age
# Ubuntu/Debian
apt install age
wget https://github.com/getsops/sops/releases/latest/download/sops-v3.x.x.linux.amd64 \
-O /usr/local/bin/sops && chmod +x /usr/local/bin/sops
Backends de Chiffrement
| Backend | Idéal Pour | Infrastructure |
|---|---|---|
| age | Défaut moderne simple | Aucune |
| PGP/GPG | Héritage, largement supporté | Trousseau GPG |
| AWS KMS | Équipes natives AWS | Compte AWS + IAM |
| GCP KMS | Équipes natives GCP | Projet GCP |
| Azure Key Vault | Environnements Azure | Abonnement Azure |
| HashiCorp Vault | Multi-cloud, on-prem | Cluster Vault |
Pour les nouveaux projets, age est la valeur par défaut recommandée.
age: Approfondissement
# Générer une paire de clés
age-keygen -o ~/.config/sops/age/keys.txt
# Public key: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Définir la variable d'environnement
export SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt
# Permissions correctes
chmod 600 ~/.config/sops/age/keys.txt
age supporte également les clés SSH comme destinataires, utile si votre équipe a déjà des clés SSH.
Configuration de .sops.yaml
creation_rules:
- path_regex: secrets/.*\.yaml$
age: >-
age1alice1111111111111111111111111111111111111111111111111111111,
age1bob2222222222222222222222222222222222222222222222222222222222
- path_regex: k8s/.*secret.*\.yaml$
kms: "arn:aws:kms:us-east-1:123456789:key/mrk-abc123"
Groupes de clés et seuil de Shamir pour exiger M parmi N parties pour déchiffrer :
creation_rules:
- path_regex: critical/.*
key_groups:
- age:
- age1alice...
- age1bob...
- kms:
- arn: "arn:aws:kms:us-east-1:123456789:key/mrk-abc123"
shamir_threshold: 2
Chiffrer et Éditer des Fichiers
# Chiffrer vers un nouveau fichier
sops --encrypt secrets.yaml > secrets.enc.yaml
# Ouvrir dans l'éditeur (déchiffre, édite, re-chiffre à la sauvegarde)
sops secrets.enc.yaml
# Déchiffrer vers stdout
sops --decrypt secrets.enc.yaml
# Injecter comme variables d'environnement
sops exec-env secrets.enc.yaml 'docker-compose up'
Rotation des Clés
# 1. Ajouter nouvelle clé, supprimer ancienne du .sops.yaml
# 2. Re-chiffrer les fichiers affectés
sops updatekeys --yes secrets/db.yaml
# 3. Vérifier que l'ancienne clé ne fonctionne plus
SOPS_AGE_KEY="ancienne_clé_privée" sops --decrypt secrets/db.yaml
# Doit échouer: "could not decrypt data key"
Intégration CI/CD et Kubernetes
GitHub Actions :
- name: Déchiffrer les secrets
env:
SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}
run: sops --decrypt k8s/secrets.enc.yaml | kubectl apply -f -
Workflow Kubernetes :
kubectl create secret generic db-creds \
--from-literal=password=supersecret \
--dry-run=client -o yaml > k8s/db-secret.yaml
sops --encrypt --in-place k8s/db-secret.yaml
git add k8s/db-secret.yaml && git commit -m "Ajouter secret db chiffré"
KSOPS pour ArgoCD et le fournisseur natif de Flux permettent le déchiffrement automatique au déploiement.
SOPS vs Alternatives
| Outil | Chiffre | Diffable | Infra Requise | GitOps |
|---|---|---|---|---|
| SOPS | Valeurs uniquement | Oui | Optionnelle (age) | Excellent |
| Sealed Secrets | Secret k8s entier | Non | Contrôleur | Kubernetes seulement |
| External Secrets | Valeurs en runtime | N/A | Vault/KMS | Oui, en ligne seulement |
| git-crypt | Fichiers entiers | Non | Trousseau GPG | Limité |
| BlackBox | Fichiers entiers | Non | Trousseau PGP | Limité |
Pièges et Cas Particuliers
- Ne jamais committer la clé privée — Seule la clé publique va dans
.sops.yaml. .sops.yamldoit être à la racine du dépôt — Ou utilisez--config chemin/.sops.yaml.- Permissions du fichier de clé age — SOPS refuse un keys.txt lisible par d’autres utilisateurs. Utilisez
chmod 600. - Le seuil de Shamir doit être satisfait — Si KMS est indisponible et
shamir_threshold: 2, il faut 2 détenteurs de clés age simultanément.
Résumé
- SOPS chiffre les valeurs, pas les clés — Les fichiers restent comparables et auditables dans Git.
- age est le défaut moderne — Sans infrastructure, fonctionne hors ligne, supporte plusieurs destinataires.
.sops.yamlcreation_rules — Associez des patterns de chemin à des clés avec groupes et seuil Shamir.- Support natif Kubernetes — KSOPS pour ArgoCD, fournisseur natif pour Flux.