Aller au contenu principal

Secrets chiffrés avec SealedSecrets

Un Secret Kubernetes n'est pas chiffré. Son contenu est encodé en base64, ce qui se décode en une commande. Le committer dans Git, c'est publier vos mots de passe en clair pour quiconque a accès au dépôt.

Vos namespaces hosted-* vous laissent gérer vos secrets en autonomie, sans passer par notre équipe. La condition : les chiffrer avant qu'ils touchent votre dépôt. C'est le rôle de SealedSecrets.

Pourquoi SealedSecrets ?

SealedSecrets (Bitnami) repose sur du chiffrement asymétrique. Vous scellez un secret avec un certificat public que tout le monde peut avoir. Seul le contrôleur installé dans le cluster peut le déchiffrer, avec une clé privée qui ne quitte jamais le cluster.

Le résultat du scellement est un objet SealedSecret : un fichier chiffré, sans danger à committer dans Git. Une fois appliqué, le contrôleur le déchiffre et crée un Secret Kubernetes standard, que vos applications consomment normalement.

Point clé : le chiffrement est lié au namespace (mode strict, par défaut). Un SealedSecret scellé pour hosted-votreorg-app-prod ne se déchiffre que dans ce namespace. Copié ailleurs, il échoue. C'est ce qui rend l'objet sûr dans Git et impossible à réutiliser contre un autre namespace.

Ce que ça change pour vos namespaces hosted-*

Avant, ajouter un secret voulait dire ouvrir un ticket et attendre l'équipe ops. Maintenant, le compte de service de votre organisation a le droit de créer, modifier et supprimer des SealedSecret dans vos propres namespaces hosted-*, et nulle part ailleurs.

Concrètement :

  • Vous êtes autonome. Vous scellez, vous committez, vous appliquez. Pas d'intermédiaire.
  • Vos secrets restent cloisonnés. Vous ne pouvez pas déchiffrer, ni même lire, les secrets d'une autre organisation. La clé privée reste dans kube-system, hors de votre portée.
  • Votre dépôt devient la source de vérité. Le SealedSecret vit dans Git aux côtés de vos manifestes. Vos secrets suivent le même flux GitOps que le reste de votre déploiement.

Prérequis

  • Votre kubeconfig hosted-* (celui que nous vous avons fourni) configuré avec kubectl.
  • kubeseal installé en local :
# macOS
brew install kubeseal

# Linux (adapter la version)
curl -sL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.31.0/kubeseal-0.31.0-linux-amd64.tar.gz" \
| tar -xz kubeseal && sudo install kubeseal /usr/local/bin/

Étapes

1. Récupérer le certificat public

Le certificat public sert à sceller. Récupérez-le une fois et gardez-le :

kubeseal --controller-name=sealed-secrets --controller-namespace=kube-system \
--fetch-cert > sealed-secrets.pem

2. Écrire le secret en clair, en local

Générez le manifeste du Secret sans jamais l'appliquer au cluster (--dry-run=client) :

kubectl create secret generic app-credentials \
--namespace hosted-votreorg-app-prod \
--from-literal=DATABASE_PASSWORD='votre-mot-de-passe' \
--dry-run=client -o yaml > secret.yaml

Ce fichier contient votre secret en clair. Il ne doit jamais être committé. Supprimez-le à la fin.

3. Sceller

kubeseal --cert sealed-secrets.pem \
--namespace hosted-votreorg-app-prod \
--format yaml < secret.yaml > sealed-secret.yaml

sealed-secret.yaml contient un objet SealedSecret chiffré. Le namespace est verrouillé dans le chiffrement : c'est le --namespace passé ici qui décidera où l'objet peut être déchiffré.

4. Committer

rm secret.yaml            # on ne garde jamais le clair
git add sealed-secret.yaml
git commit -m "chore: add app database credentials"

5. Appliquer

kubectl apply -f sealed-secret.yaml

Le contrôleur détecte le SealedSecret, le déchiffre et crée le Secret Kubernetes correspondant dans votre namespace.

Vérification

# Le SealedSecret est bien présent
kubectl get sealedsecret -n hosted-votreorg-app-prod

# Le contrôleur a créé le Secret standard à partir de lui
kubectl get secret app-credentials -n hosted-votreorg-app-prod

Vos pods consomment ensuite ce Secret comme n'importe quel autre, via envFrom, valueFrom.secretKeyRef ou un volume monté.

Bonnes pratiques

  • Ne committez jamais le Secret en clair. Seul le SealedSecret va dans Git. Ajoutez secret.yaml à votre .gitignore par sécurité.
  • Un scellement est lié à un namespace ET à un nom. Pour renommer un secret ou le déplacer dans un autre namespace, il faut le re-sceller à partir du clair. On ne « bouge » pas un SealedSecret.
  • La clé privée et ses sauvegardes sont gérées par France Nuage. Vous n'avez rien à sauvegarder de ce côté. En cas de restauration du cluster, vos SealedSecret redeviennent déchiffrables sans action de votre part.
  • Faites tourner vos secrets comme d'habitude : re-scellez la nouvelle valeur, committez, appliquez. Le contrôleur met le Secret à jour.
Rotation du certificat

Le certificat public change lors des rotations de clé du cluster. Si un scellement échoue avec une erreur de certificat, relancez l'étape 1 pour récupérer le certificat à jour.

Prochaines étapes