Gestion des secrets - 06 - SOPS + age : chiffrer ses secrets dans git

Chiffrer ses fichiers de secrets avec SOPS et age. Les secrets dans git, mais chiffres. Simple, efficace, pas cher.

06 - SOPS + age : chiffrer ses secrets dans git

Ce que tu vas apprendre

  • Installer et configurer SOPS avec age
  • Chiffrer, dechiffrer et éditer des fichiers de secrets
  • Intégrer SOPS dans un pipeline CI/CD GitLab pour le déploiement

Prerequisites

Un terminal, git, et 5 minutes. C'est tout.


L'idee

Tu as un fichier .env avec tes secrets. Tu veux le versionner dans git (pour le partage, l'historique, le backup) mais sans que n'importe qui puisse le lire. La solution : chiffrer le fichier avant de le committer. Seules les personnes qui ont la clé de dechiffrement peuvent acceder aux valeurs.

C'est exactement ce que font SOPS et age ensemble. Et c'est ma solution préférée pour les petits projets comme paltemps.fr.

SOPS et age : qui fait quoi

SOPS (Secrets OPerationS) est un outil développé a l'origine par Mozilla. Il sait chiffrer des fichiers YAML, JSON, ENV et INI en ne chiffrant que les valeurs (pas les clés). Tu vois la structure du fichier, mais pas le contenu.

age est un outil de chiffrement moderne créé par Filippo Valsorda (qui bosse sur la crypto dans Go). C'est le remplacant de PGP pour le commun des mortels : pas de keyring, pas de web of trust, pas de configuration incomprehensible. Une clé, un fichier, c'est tout.

SOPS gere la logique (quel champ chiffrer, comment éditer). age gere le chiffrement. Ensemble, ils forment la solution la plus simple que je connaisse pour mettre des secrets dans git.

Si tu as lu la serie sur le chiffrement, age utilise X25519 pour l'échange de clés et ChaCha20-Poly1305 pour le chiffrement symetrique. Du solide.

Installation

bash# macOS
brew install sops age

# Linux (Debian/Ubuntu)
sudo apt install age
# SOPS : telecharger le binaire depuis GitHub
curl -LO https://github.com/getsops/sops/releases/download/v3.9.4/sops-v3.9.4.linux.amd64
sudo mv sops-v3.9.4.linux.amd64 /usr/local/bin/sops
sudo chmod +x /usr/local/bin/sops

# Verifier
age --version
sops --version

Generer une clé age

bashage-keygen -o ~/.config/sops/age/keys.txt

Ca généré deux choses :

  • Une clé publique (commence par age1...) que tu partages
  • Une clé privee (dans le fichier) que tu gardes secrete
bashcat ~/.config/sops/age/keys.txt
# # created: 2026-03-28T10:00:00+01:00
# # public key: age1qms5qm5x3rkwt06yrgqv6due9jkdxd5x2v8n4qxmwz8f0kzm0rsd3fwxr
# AGE-SECRET-KEY-1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

La clé publique, tu peux la coller dans le README du projet ou la donner a tes collegues. La clé privee, tu la gardes sur ta machine et tu la stockes comme variable CI/CD protégée dans GitLab.

Configurer SOPS

Cree un fichier .sops.yaml a la racine de ton projet :

yamlcreation_rules:
  - path_regex: \.env\.enc$
    age: "age1qms5qm5x3rkwt06yrgqv6due9jkdxd5x2v8n4qxmwz8f0kzm0rsd3fwxr"
  - path_regex: secrets\.ya?ml$
    age: "age1qms5qm5x3rkwt06yrgqv6due9jkdxd5x2v8n4qxmwz8f0kzm0rsd3fwxr"

Tu peux spécifier plusieurs clés publiques si plusieurs personnes doivent pouvoir dechiffrer :

yamlcreation_rules:
  - path_regex: \.env\.enc$
    age: "age1alice...,age1bob...,age1ci..."

Chaque personne listee peut dechiffrer avec sa clé privee. Pratique pour une équipe de 2 a 5 devs.

Chiffrer un fichier .env

bash# Chiffrer
sops --encrypt .env > .env.enc

# Verifier le contenu chiffre
cat .env.enc

Le résultat ressemble a ca :

ANTHROPIC_API_KEY=ENC[AES256_GCM,data:xxx,iv:xxx,tag:xxx,type:str]
SMTP_PASS=ENC[AES256_GCM,data:xxx,iv:xxx,tag:xxx,type:str]
ADMIN_PASSWORD=ENC[AES256_GCM,data:xxx,iv:xxx,tag:xxx,type:str]

Les noms des variables sont visibles (tu sais quels secrets existent) mais les valeurs sont chiffrees. C'est voulu : ca permet de faire un diff git et de voir quelles variables ont change, sans exposer les valeurs.

Dechiffrer

bash# Vers stdout
sops --decrypt .env.enc

# Vers un fichier
sops --decrypt .env.enc > .env

SOPS cherche automatiquement la clé privee dans ~/.config/sops/age/keys.txt. Tu peux aussi spécifier le chemin avec la variable d'environnement SOPS_AGE_KEY_FILE.

Editer un fichier chiffre

Pas besoin de dechiffrer, éditer, rechiffrer manuellement. SOPS ouvre le fichier dans ton éditeur :

bashsops .env.enc

Ca dechiffre en mémoire, ouvre $EDITOR, et rechiffre a la sauvegarde. Les valeurs que tu n'as pas touchees ne changent pas (le chiffrement est stable), donc le diff git ne montre que ce qui a réellement ete modifie.

SOPS avec YAML (pour les fichiers de config)

Pour les fichiers YAML, SOPS est encore plus malin. Il chiffre les valeurs mais garde les clés en clair :

bash# secrets.yaml avant chiffrement
database:
  host: db.internal
  password: supersecret
api:
  anthropic_key: sk-ant-xxx
bashsops --encrypt secrets.yaml > secrets.enc.yaml
yaml# secrets.enc.yaml
database:
  host: ENC[AES256_GCM,data:xxx...]
  password: ENC[AES256_GCM,data:xxx...]
api:
  anthropic_key: ENC[AES256_GCM,data:xxx...]
sops:
  age:
    - recipient: age1qms5qm5x3rkwt06yrgqv6due9jkdxd5x2v8n4qxmwz8f0kzm0rsd3fwxr
      enc: |
        -----BEGIN AGE ENCRYPTED FILE-----
        xxx
        -----END AGE ENCRYPTED FILE-----

Tu peux meme exclure certains champs du chiffrement avec encrypted_regex dans .sops.yaml pour ne chiffrer que les champs sensibles (password, key, token) et laisser le reste en clair.

Le workflow complet

Voici comment ca fonctionne au quotidien :

bash# 1. Tu modifies un secret
sops .env.enc
# (ton editeur s'ouvre, tu changes la valeur, tu sauvegardes)

# 2. Tu commites le fichier chiffre
git add .env.enc
git commit -m "rotate ANTHROPIC_KEY"

# 3. Tu pushes
git push origin main

# 4. Le pipeline CI/CD dechiffre et deploie

Le .gitignore contient .env (le fichier en clair) mais PAS .env.enc (le fichier chiffre). C'est l'inverse de ce qu'on fait habituellement.

Intégration CI/CD GitLab

Dans GitLab, stocke la clé privee age comme variable CI/CD protégée :

  1. Settings > CI/CD > Variables
  2. Ajoute SOPS_AGE_KEY avec le contenu de ~/.config/sops/age/keys.txt
  3. Coche "Protected" et "Masked"

Dans ton .gitlab-ci.yml :

yamldeploy:
  stage: deploy
  before_script:
    - mkdir -p ~/.config/sops/age
    - echo "$SOPS_AGE_KEY" > ~/.config/sops/age/keys.txt
  script:
    - sops --decrypt .env.enc > .env
    - docker compose up -d --build
  after_script:
    - rm -f .env  # Nettoyage du fichier en clair
    - rm -f ~/.config/sops/age/keys.txt
  only:
    - main

Le fichier .env en clair n'existe que pendant le déploiement. Il est supprime juste apres. La clé privee aussi.

Pourquoi c'est ma solution préférée pour les petites équipes

Comparons avec les alternatives vues dans les articles précédents :

  • Pas de service cloud a configurer (contrairement a Google Secret Manager ou AWS)
  • Pas de serveur a maintenir (contrairement a HashiCorp Vault)
  • Les secrets sont dans git (versioning, historique, backup gratuit)
  • Le partage est résolu : un nouveau dev clone le repo, il a les fichiers chiffres. Tu lui donnes la clé privee (une seule fois, en personne ou via un canal sécurisé)
  • Ca fonctionne avec n'importe quel hébergement (VPS OVH, Hetzner, Scaleway, n'importe quoi)

Le compromis : pas de contrôle d'acces fin (tout le monde avec la clé voit tout), pas d'audit trail (a part l'historique git), pas de rotation automatique. Pour une équipe de 1 a 5 personnes, c'est acceptable.

Au-dela de 5 personnes, ou si tu as besoin de savoir qui a accede a quel secret et quand, passe a un vault cloud.


Navigation : Precedent : 05 - HashiCorp Vault | Suivant : 07 - Secrets dans CI/CD


Sources

Retrouve d'autres articles techniques sur paltemps.fr.

Réservez un audit gratuit de 30 minutes. Je vous montre concrètement ce qu'on peut automatiser.