Flux CD Flux CD

Gérer les secrets dans Git avec SOPS et age

Chiffrez les Secrets Kubernetes avant de les committer, et laissez Flux les déchiffrer dans le cluster.

12 min Intermédiaire

GitOps place la configuration de votre cluster dans Git, y compris les Secrets. Committer un Secret Kubernetes en clair expose ses valeurs à toute personne qui peut lire le dépôt, car les données d’un Secret ne sont qu’encodées en base64. Le kustomize-controller de Flux sait déchiffrer les fichiers chiffrés avec Mozilla SOPS, ce qui vous permet de committer des Secrets chiffrés et de garder tout le système dans Git. Ce guide utilise des clés age, l’option la plus simple.

Installer les outils et créer une clé

Installez age et sops (par exemple brew install age sops), puis générez une paire de clés :

age-keygen -o age.agekey

Le fichier de sortie contient la clé privée, et la commande affiche la clé publique (elle commence par age1). Gardez la clé privée hors de Git. Sauvegardez-la dans un endroit sûr, car si vous la perdez vous ne pourrez plus déchiffrer vos secrets. Flux 2.9 ajoute aussi la prise en charge du chiffrement post-quantique d’age, si vos politiques l’exigent.

Donner la clé privée au cluster

Stockez la clé privée sous forme de Secret dans le même namespace que la Kustomization Flux qui l’utilisera :

kubectl create secret generic sops-age \
  --namespace=flux-system \
  --from-file=age.agekey=/dev/stdin < age.agekey

La clé dans le Secret doit se terminer par .agekey. Supprimez le fichier local age.agekey ou déplacez-le dans un gestionnaire de mots de passe une fois qu’il est conservé en sécurité ailleurs.

Configurer SOPS dans le dépôt

Créez .sops.yaml à la racine de votre dépôt pour que tout le monde chiffre de la même façon. Remplacez la clé par votre clé publique :

creation_rules:
  - path_regex: .*\.yaml
    encrypted_regex: ^(data|stringData)$
    age: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

encrypted_regex ne chiffre que les champs data et stringData, de sorte que tout le reste du manifeste reste lisible pour la relecture et pour que Flux le traite. Vous pouvez lister plusieurs destinataires age (séparés par des virgules) pour que les coéquipiers et la clé du cluster puissent tous déchiffrer.

Chiffrer un Secret

Écrivez le manifeste du Secret en local, par exemple apps/webapp/db-credentials.yaml :

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
  namespace: webapp
stringData:
  username: webapp
  password: s3cr3t-value

Chiffrez-le sur place :

sops --encrypt --in-place apps/webapp/db-credentials.yaml

Ouvrez le fichier : les valeurs username et password sont maintenant du texte chiffré et un bloc sops: avec des métadonnées a été ajouté. Il est sans risque de le committer. Pour le modifier plus tard, exécutez sops apps/webapp/db-credentials.yaml, qui déchiffre dans votre éditeur et rechiffre à l’enregistrement. Pour vérifier ce que vous allez committer, assurez-vous que les valeurs ne sont plus lisibles.

Indiquer à Flux de déchiffrer

Ajoutez un bloc decryption à la Kustomization Flux qui applique le dossier :

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: webapp
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./apps/webapp
  prune: true
  decryption:
    provider: sops
    secretRef:
      name: sops-age

Committez et poussez. Pendant la réconciliation, kustomize-controller déchiffre le fichier en mémoire et applique un Secret normal au cluster. Vérifiez-le :

flux reconcile kustomization webapp --with-source
kubectl get secret db-credentials -n webapp

Dépannage et bonnes pratiques

Si la Kustomization signale une erreur de déchiffrement, vérifiez que le Secret sops-age existe dans le même namespace que la Kustomization, que le nom de sa clé se termine par .agekey, et que le fichier a été chiffré avec la clé publique correspondante. kubectl describe kustomization webapp -n flux-system affiche l’erreur.

  • Utilisez une clé différente par environnement pour qu’une clé de dev ne puisse pas lire les secrets de production.
  • Faites la rotation des clés en ajoutant le nouveau destinataire, en rechiffrant (sops updatekeys), puis en retirant l’ancien.
  • Les clés KMS cloud (AWS KMS, Azure Key Vault, Google Cloud KMS) ainsi que HashiCorp Vault ou OpenBao fonctionnent aussi, et évitent de distribuer des fichiers de clés. Configurez-les avec l’identité de workload et omettez secretRef là où la plateforme fournit les identifiants.
  • Si vous préférez garder les secrets entièrement hors de Git, utilisez l’External Secrets Operator pour les synchroniser depuis un coffre-fort, et laissez Flux ne gérer que les objets ExternalSecret.

Guides populaires