
Un mot de passe écrit dans un cookbook part en clair dans Git. Les data bags de Chef sortent la donnée du code, mais ne la protègent pas pour autant : un data bag ordinaire est lisible par tous. Ce module chiffre vraiment les secrets avec les data bags chiffrés (AES-256-GCM), les fait déchiffrer par le nœud au moment de la convergence, et empêche leur fuite dans les journaux. Public visé : intermédiaires ayant déjà déployé un cookbook sur une vraie machine.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre pourquoi un data bag clair ne suffit pas.
- Chiffrer un data bag avec une clé partagée.
- Consommer un secret dans une recette sans le journaliser.
- Savoir quand passer à chef-vault.
Prérequis
Section intitulée « Prérequis »- Savoir écrire une recette et converger un nœud avec knife-zero.
Un data bag ordinaire ne protège rien
Section intitulée « Un data bag ordinaire ne protège rien »Un data bag est un conteneur de données JSON, rangé hors des cookbooks. C'est déjà un progrès : le mot de passe ne traîne plus au milieu du code. Mais un data bag ordinaire reste un fichier JSON en clair. Versionné, il expose le secret à quiconque a accès au dépôt ; sur le poste, il est lisible par tout compte qui passe par là.
Il faut donc une couche de chiffrement. Chef la fournit nativement avec les data bags chiffrés : les valeurs sont chiffrées avec une clé secrète, et seuls ceux qui possèdent cette clé peuvent les relire.
Créer la clé de chiffrement
Section intitulée « Créer la clé de chiffrement »Tout repose sur un secret partagé. On le génère une fois, avec suffisamment d'entropie, et on le protège comme l'actif le plus sensible du dépôt :
openssl rand -base64 512 | tr -d '\r\n' > .chef/encrypted_data_bag_secretchmod 600 .chef/encrypted_data_bag_secretIl faut aussi indiquer à Chef où vivent les data bags, dans .chef/config.rb :
data_bag_path File.join(File.dirname(__FILE__), '..', 'data_bags')Chiffrer un data bag
Section intitulée « Chiffrer un data bag »On part d'un fichier JSON en clair, rangé hors du dépôt (par exemple dans un répertoire temporaire), qui décrit le secret :
{ "id": "db", "user": "appuser", "password": "S3cr3t-MySQL-2026"}La commande knife data bag from file le chiffre avec la clé et l'enregistre
dans le dépôt :
knife data bag create passwords -zknife data bag from file passwords /tmp/chef-secrets/db.json \ --secret-file .chef/encrypted_data_bag_secret -zUpdated data_bag_item[passwords::db]Le fichier écrit dans data_bags/passwords/db.json ne contient plus rien de
lisible : chaque valeur devient un bloc chiffré en AES-256-GCM.
{ "id": "db", "user": { "encrypted_data": "Noie9gXmnlHnHRtQuHb8Jf+rsoCh7lhvMWQ=\n", "iv": "g3JpE0SdXX9Y25V5\n", "auth_tag": "KO+XqEqzb5xS4Z0KC74jTA==\n", "version": 3, "cipher": "aes-256-gcm" }, "password": { "encrypted_data": "ToL5cv6xpC5Be9XZTASzeFqcJ7qD3z9UNz296h6EfLlHaiV+\n", "iv": "B7EpMnqRtmCL3iXp\n", ... }}C'est ce fichier-là que vous versionnez, sans risque.
Vérifier le chiffrement
Section intitulée « Vérifier le chiffrement »Le test décisif tient en deux commandes. Sans la clé, knife n'affiche que le
chiffré :
knife data bag show passwords db -zid: dbpassword: auth_tag: JKtJ+M1T/49AgbCNizX6WA== cipher: aes-256-gcm encrypted_data: ToL5cv6xpC5Be9XZTASzeFqcJ7qD3z9UNz296h6EfLlHaiV+Avec la clé, le secret réapparaît :
knife data bag show passwords db --secret-file .chef/encrypted_data_bag_secret -zid: dbpassword: S3cr3t-MySQL-2026user: appuserDistribuer la clé aux nœuds
Section intitulée « Distribuer la clé aux nœuds »Le nœud doit posséder la clé pour déchiffrer pendant la convergence. Par
convention, elle se pose dans /etc/chef/encrypted_data_bag_secret, en
0600 et appartenant à root :
sudo install -o root -g root -m 0600 secret /etc/chef/encrypted_data_bag_secretEn pratique, on ne fait pas ce geste à la main : knife bootstrap accepte
l'option --secret-file, qui installe la clé sur le nœud au moment de son
enrôlement. La clé arrive donc avec la machine, une fois pour toutes.
Consommer le secret dans une recette
Section intitulée « Consommer le secret dans une recette »La recette charge la clé depuis le nœud, déchiffre le data bag, puis écrit la
configuration applicative. Deux détails comptent : le mode 0600 du fichier
produit, et surtout l'attribut sensitive true.
secret = Chef::EncryptedDataBagItem.load_secret( '/etc/chef/encrypted_data_bag_secret')creds = Chef::EncryptedDataBagItem.load('passwords', 'db', secret)
directory '/etc/appdb' do owner 'root' group 'root' mode '0750'end
file '/etc/appdb/database.yml' do owner 'root' group 'root' mode '0600' sensitive true content <<~CONF production: adapter: mysql2 username: #{creds['user']} password: #{creds['password']} CONFendTravaux pratiques : converger avec le secret
Section intitulée « Travaux pratiques : converger avec le secret »On ajoute la recette au run-list du nœud, et on converge :
knife zero converge 'name:web1'Recipe: appsecrets::default * directory[/etc/appdb] action create - create new directory /etc/appdb - change mode from '' to '0750' * file[/etc/appdb/database.yml] action create - create new file /etc/appdb/database.yml - suppressed sensitive resource - change mode from '' to '0600'
Infra Phase complete, 4/13 resources updated in 04 secondsLa ligne suppressed sensitive resource est la preuve que sensitive true
fait son travail : Chef a bien écrit le fichier, mais n'a rien montré de son
contenu.
Le résultat sur la machine est exactement celui attendu, avec des permissions strictes :
sudo stat -c '%a %U:%G' /etc/appdb/database.ymlsudo cat /etc/appdb/database.yml600 root:rootproduction: adapter: mysql2 username: appuser password: S3cr3t-MySQL-2026Prouver l'idempotence
Section intitulée « Prouver l'idempotence »Une seconde convergence ne doit rien changer : le nœud est déjà conforme.
* directory[/etc/appdb] action create (up to date) * file[/etc/appdb/database.yml] action create (up to date)« up to date » sur les deux ressources : le secret est en place, Chef le constate et n'écrit rien. La chaîne est complète : chiffré dans le dépôt, déchiffré sur le nœud, jamais journalisé, fichier en 0600.
La limite : une seule clé pour tout le parc
Section intitulée « La limite : une seule clé pour tout le parc »Ce modèle a un défaut structurel qu'il faut regarder en face. La clé est partagée : tous les nœuds qui la possèdent peuvent déchiffrer tous les data bags, y compris ceux qui ne les concernent pas. Un serveur web compromis donne accès aux secrets de la base de données.
chef-vault répond exactement à cela : il chiffre chaque secret pour les clés publiques des nœuds autorisés, individuellement. Un serveur ne peut alors déchiffrer que ce qui lui a été destiné, et l'ajout d'un nœud se fait sans redistribuer une clé maîtresse.
Dépannage
Section intitulée « Dépannage »Les échecs de déchiffrement ont presque toujours la même origine : le nœud n'a pas la bonne clé. Voici comment les distinguer.
| Symptôme | Cause probable | Solution |
|---|---|---|
Cannot find a secret file | Le nœud n'a pas la clé | Poser /etc/chef/encrypted_data_bag_secret (ou bootstrapper avec --secret-file) |
DecryptionFailure à la convergence | La clé du nœud diffère de celle du chiffrement | Redéployer la même clé sur le nœud |
| Le data bag s'affiche en clair | Créé sans --secret-file | Le recréer avec la clé : il n'a jamais été chiffré |
| Le mot de passe apparaît dans la sortie | sensitive true oublié | L'ajouter, puis changer le secret exposé |
id visible malgré le chiffrement | Comportement normal | Ne jamais mettre d'information sensible dans un identifiant |
À retenir
Section intitulée « À retenir »- Un data bag ordinaire est en clair : il sort la donnée du code, il ne la protège pas.
- Un data bag chiffré protège les valeurs en AES-256-GCM ; il est donc versionnable sans risque.
- Seules les valeurs sont chiffrées : l'
idet les noms de champs restent lisibles. - La clé
encrypted_data_bag_secretne va jamais dans Git et se distribue aux nœuds viaknife bootstrap --secret-file. sensitive trueempêche Chef d'afficher le secret dans la sortie de convergence, donc dans les logs et la CI.- La clé partagée est la limite du modèle : chef-vault chiffre par nœud, mais exige un serveur Chef.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Gérer ses secrets : les principes, indépendamment de l'outil.
- HashiCorp Vault : centraliser les secrets et passer à la rotation automatique.