Vous devez stocker des credentials dans votre dépôt Git, mais les commiter en clair est impensable ? SOPS résout ce problème en chiffrant uniquement les valeurs de vos fichiers YAML, JSON ou ENV, tout en gardant les clés lisibles. Résultat : vos secrets sont protégés, mais vous pouvez toujours faire des diffs et des reviews sur la structure du fichier.
Contrairement à Ansible Vault qui chiffre le fichier entier (rendant les diffs impossibles), ou à HashiCorp Vault qui nécessite une infrastructure dédiée, SOPS offre un compromis pragmatique : chiffrement fort + workflow Git natif.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Installation : installer SOPS et age sur Linux, macOS et Windows
- Chiffrement : chiffrer des fichiers YAML, JSON, ENV, INI et binaire
- Chiffrement sélectif : ne chiffrer que certaines clés avec
encrypted_regex - Injection de secrets : utiliser
exec-envetexec-filepour injecter des secrets sans fichier intermédiaire - Manipulation : modifier (
set/unset), extraire (extract), faire tourner les clés (rotate) - Multi-clés : configurer plusieurs clés pour une équipe et les key groups Shamir
- Intégrations : Ansible, Kubernetes, CI/CD durcis, intégration Git diff
Qu'est-ce que SOPS ?
Section intitulée « Qu'est-ce que SOPS ? »SOPS (Secrets OPerationS) est un éditeur de fichiers chiffrés créé par Mozilla (maintenant maintenu par la communauté sous getsops/sops). Il supporte les formats YAML, JSON, ENV, INI et binaire.
La version actuelle est la v3.12.1 (mars 2026).
Pourquoi SOPS plutôt qu'autre chose ?
Section intitulée « Pourquoi SOPS plutôt qu'autre chose ? »Le choix se joue sur un arbitrage simple : acceptez-vous d'exploiter un service centralisé pour vos secrets, ou préférez-vous qu'ils vivent dans le dépôt Git avec le code ? SOPS occupe la case « pas d'infrastructure » tout en gardant le multi-destinataires et les diffs lisibles, ce que ni Ansible Vault ni un simple fichier chiffré ne permettent.
| Critère | SOPS + age | Ansible Vault | HashiCorp Vault |
|---|---|---|---|
| Stockage | Fichiers Git | Fichiers Git | Service centralisé |
| Diffs lisibles | ✅ Oui (clés visibles) | ❌ Non (blob chiffré) | N/A |
| Infrastructure | Aucune | Aucune | Serveur + HA |
| Multi-clés | ✅ Natif | ❌ 1 mot de passe | ✅ Policies avancées |
| Cloud KMS | ✅ AWS/GCP/Azure | ❌ | ✅ Transit |
Comment SOPS chiffre les fichiers ?
Section intitulée « Comment SOPS chiffre les fichiers ? »SOPS ne chiffre que les valeurs, pas les noms de clés ni la hiérarchie du
document. Chaque valeur est remplacée par un bloc ENC[AES256_GCM,...] qui
contient les données chiffrées, le vecteur d'initialisation et le tag
d'authentification. Un bloc sops: est ajouté en fin de fichier : il stocke la
data key chiffrée pour chaque destinataire et un MAC qui détecte toute
modification manuelle du fichier.
database: host: db.example.com username: admin password: super-secret-123database: host: db.example.com # Non chiffré (pas sensible) username: ENC[AES256_GCM,data:dUdUrO0=,iv:...,tag:...,type:str] password: ENC[AES256_GCM,data:GIwjxyzsbNqb,iv:...,tag:...,type:str]sops: age: - recipient: age1jk54cwqnaw2utp7... enc: | -----BEGIN AGE ENCRYPTED FILE----- ... -----END AGE ENCRYPTED FILE----- lastmodified: "2026-03-06T16:15:05Z" version: 3.12.1Avantage : vous pouvez reviewer les changements de structure (nouvelles clés, suppressions) sans avoir accès aux secrets.
Installation
Section intitulée « Installation »SOPS est un binaire statique unique, sans dépendance ni service à démarrer.
L'installation se résume donc à récupérer ce binaire, vérifier son empreinte et
le placer dans le PATH. Il faut ensuite installer le backend de
chiffrement choisi, age dans ce guide, car SOPS ne chiffre rien tout seul.
Prérequis
Section intitulée « Prérequis »SOPS ne fabrique pas de clé : il délègue le chiffrement de la data key à un backend, et vous devez en choisir un avant la première commande. Le tableau ci-dessous résume le cas d'usage typique de chacun.
| Backend | Usage recommandé | Avantage |
|---|---|---|
| age | Équipes, projets personnels | Simple, pas de service |
| AWS KMS | Projets AWS | IAM intégré |
| GCP KMS | Projets GCP | IAM intégré |
| Azure Key Vault | Projets Azure | Azure AD intégré |
| HashiCorp Vault | Entreprise | Transit encryption |
Installer SOPS
Section intitulée « Installer SOPS »Le projet publie un binaire par plateforme, accompagné d'un fichier
sops-v3.12.1.checksums.txt. Récupérez toujours les deux : sans vérification
d'empreinte, rien ne distingue le binaire officiel d'un binaire substitué en
cours de route.
# Télécharger le binaire ET le fichier de sommes publié avec la releasecurl -sLO https://github.com/getsops/sops/releases/download/v3.12.1/sops-v3.12.1.linux.amd64curl -sLO https://github.com/getsops/sops/releases/download/v3.12.1/sops-v3.12.1.checksums.txt
# Vérifier l'intégrité AVANT d'installer quoi que ce soitsha256sum --check --ignore-missing sops-v3.12.1.checksums.txt# sops-v3.12.1.linux.amd64: Réussi
chmod +x sops-v3.12.1.linux.amd64sudo mv sops-v3.12.1.linux.amd64 /usr/local/bin/sops
# Vérifiersops --version# sops 3.12.1 (latest)brew install sops
# Vérifiersops --version# Via Scoopscoop install sops
# Ou télécharger depuis GitHub Releases# https://github.com/getsops/sops/releasesasdf plugin add sopsasdf install sops latestasdf global sops latest
sops --versionInstaller age
Section intitulée « Installer age »L'archive Linux contient deux exécutables : age pour chiffrer et
déchiffrer, age-keygen pour générer les clés. SOPS a besoin des deux, donc
installez-les ensemble. La release ne publie pas de fichier de sommes global :
l'empreinte SHA-256 de chaque artefact est affichée sur la page de release
GitHub, et c'est celle-ci que la commande ci-dessous compare.
# Télécharger l'archive age v1.3.0 (sans l'extraire tout de suite)curl -sLO https://github.com/FiloSottile/age/releases/download/v1.3.0/age-v1.3.0-linux-amd64.tar.gz
# Empreinte SHA-256 de l'artefact publiée sur la release GitHub v1.3.0echo "2635f17e469b8c829055151dcbf77effe1fbefe182cb7b308aee5d0e5d923aae age-v1.3.0-linux-amd64.tar.gz" \ | sha256sum --check# age-v1.3.0-linux-amd64.tar.gz: Réussi
# Extraire seulement si la vérification a réussitar xzf age-v1.3.0-linux-amd64.tar.gzsudo install -m 0755 age/age age/age-keygen /usr/local/bin/rm -rf age age-v1.3.0-linux-amd64.tar.gz
# Vérifierage --version# v1.3.0brew install age
age --versionscoop install age# ou winget install FiloSottile.ageChiffrer avec age (recommandé)
Section intitulée « Chiffrer avec age (recommandé) »Le cycle complet tient en trois commandes : générer une paire de clés,
chiffrer avec la clé publique, déchiffrer avec la clé privée. La clé publique
age1... se partage sans risque et se committe dans .sops.yaml ; la clé
privée reste sur le poste et dans un gestionnaire de mots de passe. Aucun
service n'intervient, ce qui rend le workflow utilisable hors ligne.
Créer une clé age
Section intitulée « Créer une clé age »age-keygen écrit la clé privée dans le fichier indiqué et affiche la clé
publique sur la sortie standard. SOPS cherche par défaut ses identités dans
~/.config/sops/age/keys.txt, d'où le chemin retenu ici.
-
Créer le répertoire pour les clés
Fenêtre de terminal mkdir -p ~/.config/sops/age -
Générer une clé
Fenêtre de terminal age-keygen -o ~/.config/sops/age/keys.txt# Sortie :# Public key: age1jk54cwqnaw2utp7uwk6nvehr6rsfwrwulhf8kk9lxcw9qy92cf0qfu6nam -
Sauvegarder la clé publique
Notez la clé publique (
age1...), vous en aurez besoin pour chiffrer. La clé privée est danskeys.txt.
Chiffrer un fichier
Section intitulée « Chiffrer un fichier »sops encrypt écrit le résultat sur la sortie standard : sans redirection,
le fichier chiffré s'affiche dans le terminal et le fichier d'origine reste en
clair sur le disque. Pensez donc à supprimer ce dernier une fois le fichier
chiffré committé.
# Créer un fichier de testcat > secrets.yaml << 'EOF'database: host: db.example.com username: admin password: super-secret-123api: token: sk-1234567890abcdefEOF
# Chiffrer avec votre clé publique agesops encrypt --age age1jk54cwqnaw2utp7uwk6nvehr6rsfwrwulhf8kk9lxcw9qy92cf0qfu6nam \ secrets.yaml > secrets.enc.yaml
# Vérifier le résultatcat secrets.enc.yamlDéchiffrer un fichier
Section intitulée « Déchiffrer un fichier »Aucune option de clé n'est nécessaire au déchiffrement : la liste des
destinataires est inscrite dans le bloc sops: du fichier, et SOPS essaie les
identités qu'il trouve. La variable SOPS_AGE_KEY_FILE sert quand la clé
privée n'est pas à l'emplacement par défaut.
# SOPS cherche automatiquement dans ~/.config/sops/age/keys.txtsops decrypt secrets.enc.yaml
# Ou spécifier le fichier de cléSOPS_AGE_KEY_FILE=~/keys/ma-cle.txt sops decrypt secrets.enc.yamlÉditer un fichier chiffré
Section intitulée « Éditer un fichier chiffré »sops edit est la commande à privilégier au quotidien : le contenu déchiffré
n'existe que dans un fichier temporaire que SOPS supprime à la fermeture de
l'éditeur, et seules les valeurs réellement modifiées sont re-chiffrées.
# Ouvre le fichier déchiffré dans $EDITOR, re-chiffre à la sauvegardesops edit secrets.enc.yamlAutres formats supportés
Section intitulée « Autres formats supportés »SOPS gère nativement les formats JSON, ENV, INI et binaire. Le format est détecté automatiquement par l'extension du fichier.
# Chiffrer un fichier JSONsops encrypt --age age1... config.json > config.enc.json
# Déchiffrersops decrypt config.enc.json# Chiffrer un fichier .envcat > .env << 'EOF'DB_HOST=db.example.comDB_PASSWORD=super-secret-123API_TOKEN=sk-1234567890abcdefEOF
sops encrypt --age age1... .env > .env.enc
# Déchiffrer : retrouve le format clé=valeur originalsops decrypt .env.enc# DB_HOST=db.example.com# DB_PASSWORD=super-secret-123# API_TOKEN=sk-1234567890abcdef# Chiffrer un fichier INIsops encrypt --age age1... config.ini > config.enc.ini
# Déchiffrersops decrypt config.enc.ini# Chiffrer un fichier binaire (certificat, clé SSH, etc.)sops encrypt --age age1... certificate.pem > certificate.enc.pem
# Déchiffrersops decrypt certificate.enc.pem > certificate.pemLe contenu binaire est encodé en base64 dans le fichier chiffré. Contrairement aux autres formats, SOPS ne peut pas préserver la structure (il n'y a pas de clés/valeurs dans un binaire).
Chiffrement in-place
Section intitulée « Chiffrement in-place »L'option -i (ou --in-place) modifie le fichier directement, sans créer de
second fichier. C'est pratique pour les scripts d'automatisation.
# Chiffrer sur placesops encrypt -i --age age1... secrets.yaml
# Déchiffrer sur placesops decrypt -i secrets.enc.yamlStdin et stdout
Section intitulée « Stdin et stdout »Depuis SOPS 3.10, vous pouvez chiffrer et déchiffrer via des pipes. C'est utile pour intégrer SOPS dans des scripts sans fichier intermédiaire.
# Chiffrer depuis stdin (JSON)echo '{"secret": "from-stdin"}' | \ sops encrypt --input-type json --output-type json \ --age age1... /dev/stdin
# Écrire le résultat dans un fichiersops decrypt secrets.enc.yaml --output secrets.yamlChiffrement sélectif
Section intitulée « Chiffrement sélectif »Par défaut, SOPS chiffre toutes les valeurs d'un fichier. Mais souvent, certaines valeurs ne sont pas sensibles (noms d'hôtes, URLs publiques). Le chiffrement sélectif garde ces valeurs lisibles pour faciliter les reviews Git.
encrypted_regex : ne chiffrer que certaines clés
Section intitulée « encrypted_regex : ne chiffrer que certaines clés »L'option --encrypted-regex permet de ne chiffrer que les clés qui
correspondent à une expression régulière.
# Ne chiffrer que les clés "password" et "token"sops encrypt --age age1... \ --encrypted-regex '^(password|token)$' \ secrets.yaml > secrets.enc.yamlRésultat : host et username restent en clair, seuls password et
token sont chiffrés.
database: host: db.example.com # En clair username: admin # En clair password: ENC[AES256_GCM,data:...,type:str] # Chiffréapi: token: ENC[AES256_GCM,data:...,type:str] # Chiffréunencrypted_regex : exclure certaines clés
Section intitulée « unencrypted_regex : exclure certaines clés »L'inverse de encrypted_regex : tout est chiffré sauf les clés
correspondant au pattern.
# Tout chiffrer sauf host et usernamesops encrypt --age age1... \ --unencrypted-regex '^(host|username)$' \ secrets.yaml > secrets.enc.yamlencrypted_suffix / unencrypted_suffix
Section intitulée « encrypted_suffix / unencrypted_suffix »Vous pouvez aussi filtrer par suffixe de clé. C'est utile quand vos conventions de nommage distinguent déjà les données sensibles.
# Ne chiffrer que les clés qui se terminent par "_secret"sops encrypt --age age1... \ --encrypted-suffix '_secret' \ config.yaml > config.enc.yamlConfigurer dans .sops.yaml
Section intitulée « Configurer dans .sops.yaml »Pour éviter de passer ces options à chaque commande, déclarez-les dans
.sops.yaml :
creation_rules: # Prod : ne chiffrer que les secrets - path_regex: 'prod/.*' age: age1abc... encrypted_regex: '^(password|token|secret|key)$'
# Dev : tout chiffrer - path_regex: '.*' age: age1abc...Injecter des secrets sans fichier intermédiaire
Section intitulée « Injecter des secrets sans fichier intermédiaire »L'un des risques de sops decrypt > secrets.yaml est que le fichier déchiffré
reste sur disque. SOPS propose deux commandes pour éviter ce problème :
exec-env et exec-file.
exec-env : secrets comme variables d'environnement
Section intitulée « exec-env : secrets comme variables d'environnement »sops exec-env déchiffre un fichier et injecte chaque clé/valeur comme
variable d'environnement pour la commande spécifiée. Les secrets ne
transitent jamais par un fichier.
# Injecter les secrets comme variables d'environnementsops exec-env secrets.enc.env 'echo DB_PASSWORD=$DB_PASSWORD'# DB_PASSWORD=super-secret-123exec-env --pristine : environnement propre
Section intitulée « exec-env --pristine : environnement propre »Le flag --pristine lance la commande dans un environnement vierge,
contenant uniquement les secrets déchiffrés. Aucune variable de l'environnement
parent n'est héritée ($HOME, $PATH, etc. sont absents).
# Environnement propre : seuls les secrets sont disponiblessops exec-env --pristine secrets.enc.env \ 'echo HOME=$HOME DB_PASSWORD=$DB_PASSWORD'# HOME= DB_PASSWORD=super-secret-123C'est utile pour éviter les fuites de contexte : un script malveillant ne peut
pas lire $AWS_ACCESS_KEY_ID ou d'autres variables de votre session.
exec-file : secrets via fichier temporaire
Section intitulée « exec-file : secrets via fichier temporaire »sops exec-file déchiffre le fichier dans un fichier temporaire (ou un
FIFO nommé) et le passe à la commande via {}. Le fichier est supprimé
automatiquement après exécution.
# Le fichier déchiffré est accessible via {}sops exec-file secrets.enc.yaml 'cat {}'# database:# host: db.example.com# username: admin# password: super-secret-123
# Exemple concret : passer à kubectlsops exec-file k8s-secrets.enc.yaml \ 'kubectl apply -f {}'exec-file fonctionne avec tous les formats, y compris le YAML imbriqué
(contrairement à exec-env).
Modifier un fichier chiffré sans éditeur
Section intitulée « Modifier un fichier chiffré sans éditeur »Les commandes set, unset et extract permettent de manipuler un fichier
chiffré par programme, sans ouvrir d'éditeur interactif.
set : modifier une valeur
Section intitulée « set : modifier une valeur »sops set modifie en place : il n'y a pas de sortie standard à rediriger,
le fichier chiffré est réécrit directement. Si la clé visée n'existe pas encore,
elle est créée.
# Modifier le mot de passe dans le fichier chiffrésops set secrets.enc.yaml '["database"]["password"]' '"new-password-456"'
# Vérifiersops decrypt --extract '["database"]["password"]' secrets.enc.yaml# new-password-456La syntaxe de chemin utilise le format JSON path : ["clé"]["sous-clé"].
La valeur doit être entre guillemets doubles (c'est du JSON).
unset : supprimer une clé
Section intitulée « unset : supprimer une clé »sops unset retire la clé et sa valeur du fichier, également en place. Le
parent n'est pas nettoyé : supprimer la dernière sous-clé laisse un objet vide
(api: {}), visible dans la sortie ci-dessous.
# Supprimer la clé api.tokensops unset secrets.enc.yaml '["api"]["token"]'
# Vérifier : la clé n'existe plussops decrypt secrets.enc.yaml# database:# host: db.example.com# username: admin# password: super-secret-123# api: {}extract : lire une valeur spécifique
Section intitulée « extract : lire une valeur spécifique »extract déchiffre et retourne uniquement la valeur demandée, sans le
reste du fichier. C'est idéal pour les scripts.
# Extraire une seule valeursops decrypt --extract '["database"]["password"]' secrets.enc.yaml# super-secret-123
# Extraire une sous-arborescence complètesops decrypt --extract '["database"]' secrets.enc.yaml# host: db.example.com# username: admin# password: super-secret-123Vérifier l'état d'un fichier
Section intitulée « Vérifier l'état d'un fichier »La commande filestatus indique si un fichier est chiffré ou non. C'est utile
dans les scripts de CI pour éviter de commiter des secrets en clair.
sops filestatus secrets.enc.yaml# {"encrypted":true}
sops filestatus secrets.yaml# {"encrypted":false}Exemple d'utilisation dans un pre-commit hook :
#!/bin/bashfor file in $(git diff --cached --name-only -- '*.enc.yaml'); do status=$(sops filestatus "$file" | python3 -c \ "import sys,json; print(json.load(sys.stdin)['encrypted'])") if [ "$status" != "True" ]; then echo "ERREUR: $file n'est pas chiffré !" exit 1 fidoneConfiguration multi-clés
Section intitulée « Configuration multi-clés »Pour une équipe, vous voulez que plusieurs personnes puissent déchiffrer les secrets. SOPS supporte plusieurs clés dans un même fichier.
Ajouter plusieurs clés
Section intitulée « Ajouter plusieurs clés »Les destinataires se séparent par une virgule, sans espace. SOPS chiffre une seule fois les données avec la data key, puis chiffre cette data key séparément pour chaque destinataire : ajouter une personne n'alourdit donc presque pas le fichier.
# Chiffrer pour 2 personnessops encrypt \ --age age1abc...,age1def... \ secrets.yaml > secrets.enc.yamlChaque personne peut déchiffrer avec sa propre clé privée.
Fichier de configuration .sops.yaml
Section intitulée « Fichier de configuration .sops.yaml »Pour éviter de spécifier les clés à chaque commande, créez .sops.yaml
à la racine du projet :
creation_rules: # Secrets de production : équipe ops + KMS - path_regex: secrets/prod/.*\.yaml$ key_groups: - age: - age1abc... # Alice (ops) - age1def... # Bob (ops) kms: - arn: arn:aws:kms:eu-west-1:123456:key/xxx
# Secrets de dev : équipe dev - path_regex: secrets/dev/.*\.yaml$ age: age1ghi...,age1jkl...
# Par défaut : clé personnelle - age: age1mno...Avec cette configuration :
# SOPS applique automatiquement les bonnes cléssops encrypt secrets/prod/database.yaml > secrets/prod/database.enc.yamlMettre à jour les clés d'un fichier (updatekeys)
Section intitulée « Mettre à jour les clés d'un fichier (updatekeys) »Quand un membre quitte l'équipe ou qu'une nouvelle personne arrive, utilisez
updatekeys pour synchroniser les clés du fichier avec la configuration
.sops.yaml.
# Mettre à jour les clés sans confirmation interactivesops updatekeys -y secrets.enc.yaml
# Sortie :# Syncing keys for file secrets.enc.yaml# Group 1# age1abc... (existant)# +++ age1xyz... (ajouté)# --- age1old... (retiré)SOPS re-chiffre la data key pour les nouveaux destinataires et supprime l'accès pour les clés retirées. Les valeurs chiffrées ne changent pas (seul l'enveloppe change).
Rotation des clés (rotate)
Section intitulée « Rotation des clés (rotate) »La commande rotate génère une nouvelle data key et re-chiffre toutes les
valeurs du fichier. C'est une bonne pratique après un incident de sécurité ou
lors d'une rotation planifiée.
# Rotation de la data keysops rotate -i secrets.enc.yamlAprès la rotation, les anciennes data keys sont obsolètes. Si un attaquant avait capturé le fichier avant la rotation, il ne peut pas déchiffrer la nouvelle version même s'il possédait l'ancienne data key.
Key groups et Shamir
Section intitulée « Key groups et Shamir »Pour les secrets critiques, SOPS supporte le partage de secret de Shamir
(Shamir's Secret Sharing). Le principe : la data key est découpée en N
parts, et il faut au minimum M parts pour la reconstruire (M ≤ N).
Exemple : 3 key groups avec un seuil de 2. Il faut pouvoir déchiffrer avec au moins 2 groupes sur 3 pour récupérer le secret.
creation_rules: - path_regex: 'critical/.*' shamir_threshold: 2 key_groups: - age: - age1abc... # Équipe ops - age: - age1def... # Équipe sécurité - age: - age1ghi... # Backup offline# Chiffrer : SOPS crée 3 partssops encrypt critical/master-key.yaml > critical/master-key.enc.yaml
# Déchiffrer : il faut accès à au moins 2 des 3 clés privéessops decrypt critical/master-key.enc.yamlChiffrer avec AWS KMS
Section intitulée « Chiffrer avec AWS KMS »Sur un projet déjà hébergé chez AWS, KMS évite de distribuer des clés privées : l'autorisation de déchiffrer devient une politique IAM, révocable sans toucher aux fichiers. Chaque appel de déchiffrement est tracé dans CloudTrail, ce qu'aucun backend local ne fournit. La contrepartie est la dépendance réseau, un poste hors ligne ou une région indisponible bloque le déchiffrement.
-
Créer une clé KMS
Fenêtre de terminal aws kms create-key \--description "SOPS encryption key" \--tags TagKey=Purpose,TagValue=SOPS# Noter l'ARN : arn:aws:kms:eu-west-1:123456:key/xxx-xxx -
Chiffrer avec KMS
Fenêtre de terminal sops encrypt \--kms arn:aws:kms:eu-west-1:123456:key/xxx-xxx \secrets.yaml > secrets.enc.yaml -
Déchiffrer (les credentials AWS sont utilisés automatiquement)
Fenêtre de terminal sops decrypt secrets.enc.yaml
Combiner age et KMS
Section intitulée « Combiner age et KMS »Dans un même key group, les backends sont alternatifs : n'importe lequel
suffit à retrouver la data key. C'est la parade directe au risque décrit
ci-dessus, puisqu'une clé age conservée hors ligne reste utilisable même si
KMS est injoignable.
creation_rules: - path_regex: .*\.yaml$ key_groups: - age: - age1abc... # Backup local kms: - arn: arn:aws:kms:eu-west-1:123456:key/xxxSi KMS est indisponible, la clé age permet toujours de déchiffrer.
Intégrations
Section intitulée « Intégrations »SOPS n'est utile en production que s'il s'insère dans les outils qui consomment les secrets. Le principe reste le même partout : le fichier chiffré est versionné, et seule la clé privée est fournie à l'exécution, par variable d'environnement ou par rôle IAM. Les quatre intégrations qui suivent couvrent les cas les plus fréquents : Ansible, Kubernetes, la CI/CD et la revue de code.
SOPS et Ansible
Section intitulée « SOPS et Ansible »La collection community.sops permet de déchiffrer les fichiers SOPS
directement dans vos playbooks.
-
Installer la collection
Fenêtre de terminal ansible-galaxy collection install community.sops -
Utiliser le lookup
---- name: Déployer avec secrets SOPShosts: alltasks:- name: Lire les secretsansible.builtin.debug:msg: "{{ lookup('community.sops.sops', 'secrets.enc.yaml') }}"- name: Utiliser une valeur spécifiqueansible.builtin.debug:msg: "Password: {{ (lookup('community.sops.sops', 'secrets.enc.yaml') | from_yaml).database.password }}" -
Exporter la clé pour Ansible
Fenêtre de terminal export SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txtansible-playbook playbook.yml
SOPS et Kubernetes
Section intitulée « SOPS et Kubernetes »L'opérateur sops-secrets-operator
déchiffre automatiquement les SopsSecret en Secret Kubernetes.
apiVersion: isindir.github.com/v1alpha3kind: SopsSecretmetadata: name: my-secretspec: secretTemplates: - name: my-k8s-secret stringData: username: ENC[AES256_GCM,data:...] password: ENC[AES256_GCM,data:...]SOPS et CI/CD
Section intitulée « SOPS et CI/CD »Un runner n'a pas de clé dans ~/.config : la clé privée arrive par la variable
SOPS_AGE_KEY, qui contient directement le texte de la clé et court-circuite
la recherche de fichier. Les deux exemples ci-dessous installent SOPS avec
vérification d'empreinte, puis déchiffrent le fichier versionné. Déclarez la
variable comme protégée et masquée, sinon elle apparaît dans les journaux du
job.
name: Deployon: push: branches: [main]
# Permissions minimales au niveau du workflowpermissions: {}
jobs: deploy: runs-on: ubuntu-latest permissions: contents: read steps: # Action épinglée par SHA (pas de tag mutable) - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false
- name: Install SOPS run: | curl -sLO https://github.com/getsops/sops/releases/download/v3.12.1/sops-v3.12.1.linux.amd64 curl -sLO https://github.com/getsops/sops/releases/download/v3.12.1/sops-v3.12.1.checksums.txt sha256sum --check --ignore-missing sops-v3.12.1.checksums.txt chmod +x sops-v3.12.1.linux.amd64 sudo mv sops-v3.12.1.linux.amd64 /usr/local/bin/sops sops --version
- name: Decrypt secrets env: SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }} run: | sops decrypt secrets.enc.yaml > secrets.yamldeploy: image: alpine:3.24.1@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b before_script: - apk add --no-cache curl coreutils - curl -sLO https://github.com/getsops/sops/releases/download/v3.12.1/sops-v3.12.1.linux.amd64 - curl -sLO https://github.com/getsops/sops/releases/download/v3.12.1/sops-v3.12.1.checksums.txt - sha256sum --check --ignore-missing sops-v3.12.1.checksums.txt - chmod +x sops-v3.12.1.linux.amd64 && mv sops-v3.12.1.linux.amd64 /usr/local/bin/sops - sops --version script: - export SOPS_AGE_KEY="$SOPS_AGE_KEY" - sops decrypt secrets.enc.yaml > secrets.yaml variables: SOPS_AGE_KEY: $SOPS_AGE_KEY # Variable CI/CD protégée + masquéeIntégration Git diff
Section intitulée « Intégration Git diff »SOPS peut s'intégrer à git diff pour afficher les valeurs déchiffrées
dans les diffs, au lieu des blobs ENC[AES256_GCM,...]. C'est utile pour les
code reviews.
-
Configurer
.gitattributes*.enc.yaml diff=sopsdiffer*.enc.json diff=sopsdiffer -
Configurer Git pour utiliser SOPS
Fenêtre de terminal git config diff.sopsdiffer.textconv "sops decrypt" -
Vérifier :
git diffaffiche maintenant les valeurs en clair pour les fichiers chiffrés par SOPS.
Dépannage
Section intitulée « Dépannage »La plupart des erreurs SOPS viennent de trois causes : la clé privée introuvable, un destinataire absent du fichier, ou une édition manuelle qui casse le MAC. Le tableau ci-dessous associe chaque message d'erreur réel à sa cause et à la correction à appliquer.
| Problème | Cause | Solution |
|---|---|---|
no such file: keys.txt | Chemin de clé incorrect | Vérifier SOPS_AGE_KEY_FILE ou créer ~/.config/sops/age/keys.txt |
could not decrypt | Clé privée non correspondante | Vérifier que votre clé publique est dans le fichier chiffré |
failed to create writer for recipient: pq plugin | Clé PQ age 1.3.0 | SOPS ne supporte pas les clés PQ, utilisez age1... standard |
yaml: unmarshal errors | Format invalide | Vérifier la syntaxe YAML avant chiffrement |
MAC mismatch | Fichier corrompu ou modifié manuellement | Restaurer depuis Git |
cannot use complex value in environment | YAML imbriqué avec exec-env | Utiliser un fichier .env ou YAML plat |
no matching creation rules found | .sops.yaml sans règle correspondante | Vérifier les path_regex dans .sops.yaml |
Recovery failed (Shamir) | Pas assez de key groups disponibles | Avoir accès à au moins shamir_threshold clés privées |
Vérifier les clés d'un fichier
Section intitulée « Vérifier les clés d'un fichier »Avant de conclure à une clé perdue, vérifiez qui figure réellement parmi les
destinataires du fichier. Ce contrôle règle le cas fréquent d'un nouvel
arrivant qui n'a jamais été ajouté par updatekeys.
# Voir qui peut déchiffrersops decrypt --show-all-keys secrets.enc.yaml 2>&1 | grep -E "age|kms"
# Vérifier si un fichier est chiffrésops filestatus secrets.enc.yaml# {"encrypted":true}Bonnes pratiques
Section intitulée « Bonnes pratiques »Ces quatre règles règlent les problèmes qui apparaissent après quelques mois d'usage en équipe, pas le jour de l'installation : le départ d'un collègue, la perte d'un poste, la divergence des conventions entre projets. Les appliquer dès le début coûte quelques minutes ; les rattraper impose de re-chiffrer l'ensemble des fichiers.
- Une clé par personne : chaque membre de l'équipe a sa propre clé age, ce qui facilite la révocation quand quelqu'un part
- Sauvegarder les clés : stockez les clés privées dans un gestionnaire de mots de passe (perte de clé = secrets irrécupérables)
.sops.yamlversionné : committez ce fichier pour que toute l'équipe utilise les mêmes règles- KMS en production : combinez age (backup) + KMS (rotation automatique, audit)
Pattern de structure recommandé
Section intitulée « Pattern de structure recommandé »Séparer dev/ et prod/ par répertoire permet d'écrire des path_regex
distincts dans .sops.yaml, donc d'attribuer des clés différentes par
environnement sans commande particulière. Le suffixe .enc.yaml uniformise le
filtrage dans les hooks Git et dans .gitattributes.
Répertoireproject/
- .sops.yaml Configuration des clés
Répertoiresecrets/
Répertoiredev/
- database.enc.yaml
Répertoireprod/
- database.enc.yaml
- README.md Instructions pour l'équipe
À retenir
Section intitulée « À retenir »- SOPS chiffre les valeurs, pas les clés : les diffs Git restent lisibles
- age est recommandé : simple, pas de service, compatible partout
- PGP est déprécié : migrez vers age pour les nouveaux projets
- age 1.3.0 post-quantum : non supporté par SOPS (janvier 2026), utilisez les clés standard
- Chiffrement sélectif :
encrypted_regexgarde les données non sensibles lisibles exec-env/exec-file: injectez les secrets sans fichier intermédiaire sur disqueset/unset/extract: manipulez les fichiers chiffrés par programme- Multi-clés natif : chaque membre de l'équipe a sa clé, révocation via
updatekeys - Key groups Shamir : aucune personne seule ne peut déchiffrer les secrets critiques
.sops.yaml: centralisez la configuration des clés et les règles de chiffrement dans le repo- KMS pour la prod : audit, rotation automatique, intégration IAM
Prochaines étapes
Section intitulée « Prochaines étapes »Ressources
Section intitulée « Ressources »- Documentation officielle : getsops.io
- GitHub : getsops/sops
- age : github.com/FiloSottile/age
- Collection Ansible : community.sops
- Kubernetes Operator : sops-secrets-operator