Chapitre 1. Pourquoi gérer les secrets ?
Objectifs pédagogiques¶
Définir un secret de façon opérationnelle. Classer les secrets d'une infrastructure. Expliquer, mécanisme par mécanisme, comment un secret fuit. Décrire son cycle de vie. Expliquer pourquoi la rotation manuelle échoue. Formuler le problème du secret zéro.
Prérequis¶
Prérequis généraux du cursus. Une familiarité avec Git et les conteneurs aide à suivre les démonstrations de la section 1.3.
Cours¶
1.1 Ce qu'est un secret, et ce qui n'en est pas¶
Un secret est une donnée dont la seule connaissance confère un pouvoir : s'authentifier, déchiffrer, signer, agir au nom d'un tiers. Un mot de passe de base, une clé privée TLS, un jeton d'API répondent tous à cette définition. Le point commun n'est pas la nature de la donnée mais celle de son pouvoir : le secret est un porteur d'autorité. Celui qui le présente est cru sur parole. Un secret volé fonctionne aussi bien pour l'attaquant que pour son propriétaire, et le système ne fait pas la différence.
Trois notions se confondent constamment et doivent être séparées.
Une donnée sensible cause un préjudice si elle est divulguée : données personnelles, financières, propriété intellectuelle. Elle ne confère pas de pouvoir d'action. La liste des clients d'Astrea est sensible ; elle ne permet pas de se connecter à la base qui la contient. Le mot de passe de cette base n'intéresse aucun concurrent ; il permet de tout lire. Les deux se protègent, par des moyens différents.
Une donnée chiffrée est illisible sans sa clé. Chiffrer ne supprime pas le problème du secret, il le déplace : on remplace « protéger dix gigaoctets » par « protéger trente-deux octets ». L'échange est excellent, mais ce n'est pas une disparition. Ce déplacement se retrouve à chaque étage de Vault : la barrière chiffre le stockage, la clé racine protège la barrière, le mécanisme de scellement protège la clé racine. Une question structure ce raisonnement jusqu'au dernier chapitre : « et cette clé-là, qui la protège ? »
Un secret n'est pas confidentiel par nature mais par fonction. Un identifiant de rôle, un nom d'utilisateur, un identifiant de clé n'en sont pas : les connaître ne suffit pas à agir. La discipline consiste à séparer ce qui peut circuler librement de ce qui confère le pouvoir, et à ne protéger au prix fort que le second. AppRole repose entièrement sur ce découpage (chapitre 10).
1.2 Typologie des secrets¶
Six familles, chacune avec son cycle de vie, ses lieux de fuite et son moteur Vault de prédilection.
Mots de passe et comptes de service. Comptes humains, comptes techniques de bases, comptes d'annuaire et d'équipements. La famille la plus ancienne et la plus mal gérée : créés une fois, partagés, jamais changés parce que « trop de choses en dépendent ».
Clés d'API et jetons d'accès. Clés cloud, jetons SaaS, jetons personnels de forge, jetons OAuth. Conçus pour des machines, donc copiés dans des configurations et des pipelines, donc multipliés. Une clé d'API cloud est souvent le secret le plus puissant de l'organisation.
Clés privées et certificats. Clés TLS, clés SSH, clés de signature. Durée de vie longue et compromission silencieuse : une clé copiée ne laisse aucune trace.
Chaînes de connexion. postgres://billing:MotDePasse@db-pg-01:5432/billing agrège adresse, compte et mot de passe. Faite pour être copiée-collée, elle livre la cible en même temps que la clé.
Clés de chiffrement. Leur perte est aussi grave que leur vol, et leur rotation exige de rechiffrer ou de gérer des versions.
Secrets d'amorçage. Jetons d'enrôlement, credentials initiaux : les secrets qui servent à obtenir les autres. Peu nombreux, très puissants, ils posent le problème du secret zéro (section 1.9).
1.3 Où fuient les secrets : le code et l'exécution¶
Un secret ne fuit presque jamais par cryptanalyse. Il fuit parce qu'il a été posé en clair là où quelqu'un pouvait le lire.
Le code source et son historique. Le mot de passe écrit « en attendant » part dans Git. Deux mécanismes aggravent la situation. La diffusion : chaque clone emporte le secret, sur chaque poste, chaque runner, chaque miroir. Et Git n'oublie rien : supprimer le secret dans un commit suivant le retire du fichier courant, pas de l'historique, où git log -p le retrouve en quelques secondes. Réécrire l'historique ne purge ni les clones, ni les forks, ni les caches de la forge. La seule réponse correcte est de considérer le secret comme compromis et de le révoquer. Les rapports annuels de GitGuardian détectent de l'ordre de dix millions de nouveaux secrets par an dans les seuls dépôts publics de GitHub.
Les variables d'environnement. L'alternative réflexe est meilleure, mais faible. Sous Linux, l'environnement initial d'un processus est exposé dans /proc/<pid>/environ, lisible par le propriétaire du processus et par root.
[Démonstration] : sur votre propre machine uniquement.
# Lancer un processus avec un secret dans son environnement
DB_PASSWORD='S3cret-de-demo' sleep 300 &
# Lire l'environnement du processus depuis /proc
# tr transforme les separateurs nuls en sauts de ligne pour l'affichage
tr '\0' '\n' < /proc/$!/environ | grep DB_PASSWORD
Tout processus s'exécutant sous la même identité peut faire cette lecture. L'environnement fuit aussi par des canaux indirects : vidages de diagnostic, pages de débogage des frameworks web, processus enfants qui héritent de tout. Dans le monde des conteneurs, il fait partie de la définition même du conteneur.
[Démonstration] : sur vos propres conteneurs uniquement.
# docker inspect affiche la configuration complete du conteneur,
# dont le tableau Env : toute variable passee avec -e ou ENV y figure en clair
docker inspect --format '{{json .Config.Env}}' mon-conteneur
Quiconque accède au démon Docker lit les secrets de tous les conteneurs.
1.4 Où fuient les secrets : la chaîne de livraison¶
Les fichiers de configuration. Fichiers .env, application.properties, inventaires : les secrets y sont en clair par construction. Trois mécanismes dominent. Le fichier finit dans Git malgré le .gitignore, ajouté après le premier commit ou contourné par un exemple rempli. Ses permissions sont trop larges. Il est copié vers un poste, une préproduction, un ticket de support. Chaque copie est une instance nouvelle, avec sa propre durée de vie.
Les pipelines d'intégration continue. Ils concentrent des secrets par nécessité et les exposent de trois façons. Les journaux : un echo de débogage, une commande verbeuse, un outil qui imprime sa configuration. Le masquage des plateformes est un filet de dernier recours, pas une protection : il échoue dès que le secret est encodé, coupé ou inséré dans une URL. Les contributions externes : un pipeline qui exécute du code externe avec les secrets du dépôt cible offre un moyen d'exfiltration. Les artefacts et caches : un secret du build peut se figer dans l'image produite.
Les images de conteneurs. Une image est un empilement de couches conservées. Un secret copié à une étape reste dans sa couche même si une étape ultérieure le supprime : la suppression masque, elle ne réécrit pas. Les registres publics sont scannés en permanence ; le délai entre la publication d'une clé cloud valide et sa première utilisation frauduleuse se mesure en minutes.
Les Secrets Kubernetes. Le nom est trompeur : base64 est un encodage, pas un chiffrement. La valeur est décodable par quiconque peut la lire. Ces objets sont stockés dans etcd, et leur chiffrement au repos est une option à activer explicitement côté serveur d'API ; certaines distributions managées le font, d'autres non. S'y ajoutent tout détenteur des droits de lecture des Secrets du namespace, et les sauvegardes d'etcd non chiffrées.
1.5 Où fuient les secrets : l'exploitation¶
Les journaux applicatifs. Une chaîne de connexion dans un message d'erreur, un jeton dans une URL tracée, un en-tête recopié par un intergiciel de débogage. Les journaux sont ensuite centralisés, indexés, conservés des mois et accessibles largement, précisément parce qu'on les croit non sensibles.
Les sauvegardes. Une sauvegarde est une copie fidèle. Elle échappe aux contrôles d'accès du système d'origine et a la mémoire longue : un secret supprimé partout il y a deux ans existe encore dans les sauvegardes d'il y a deux ans. Toute rotation d'un secret compromis doit interroger les copies passées.
La supervision et l'analyse. Les agents applicatifs capturent requêtes, paramètres et en-têtes ; les collecteurs d'erreurs capturent des contextes entiers. Chacun peut charrier des secrets vers une plateforme tierce, avec sa rétention et ses utilisateurs.
Conclusion structurelle : chaque copie est une surface d'attaque, et les copies se multiplient seules. Une solution sérieuse s'attaque au nombre de copies, à leur durée de vie et à la capacité de les révoquer, pas seulement à la solidité du coffre.
1.6 Le secret sprawl¶
Le secret sprawl est l'étalement non maîtrisé des secrets. Il ne résulte pas d'incompétence mais d'une somme de décisions locales raisonnables. Le développeur met le mot de passe dans un .env local. Il le partage par messagerie pour dépanner un collègue. Le collègue le colle en préproduction. L'astreinte le recopie dans ses notes. Le script de migration le prend en argument, et l'historique du shell le retient.
Six mois plus tard, le mot de passe existe en huit exemplaires connus et un nombre inconnu d'exemplaires oubliés. Personne ne peut répondre aux deux questions qui comptent : qui peut lire ce secret aujourd'hui, et que casse-t-on si on le change ?
La seconde verrouille le système. L'incapacité à inventorier rend la rotation risquée, le risque la fait reporter, le report allonge la durée de vie, la durée de vie multiplie les copies, et les copies rendent l'inventaire impossible. Le cercle ne se brise pas par la discipline individuelle mais par l'architecture : une source unique, des consommateurs qui viennent chercher au lieu de détenir, des durées courtes par construction.
1.7 Le cycle de vie d'un secret¶
creation --> distribution --> utilisation --> rotation
^ |
| v
+---- (nouvelle version)
revocation (a tout moment, en urgence) --> destruction
Création. Qui génère le secret, avec quelle entropie, et qui le voit à cet instant ? Un mot de passe inventé par un humain est faible et déjà connu. La création fixe aussi le périmètre initial : un secret créé large le restera.
Distribution. L'étape la plus dangereuse, car elle implique un transport et un dépôt. Une distribution correcte minimise les intermédiaires, ne laisse pas de copie en transit et permet de savoir qui a reçu quoi.
Utilisation. Le secret est-il protégé en mémoire et en transit, et son usage laisse-t-il une trace exploitable ? Un secret partagé entre dix services rend la seconde question sans réponse.
Rotation. Remplacement planifié. C'est une mesure d'hygiène et un test de réversibilité : qui sait faire tourner ses secrets sait où ils sont utilisés. Elle exige une période de recouvrement, faute de quoi elle impose une coupure.
Révocation. Invalidation immédiate et non planifiée. La rotation se prépare, la révocation se subit. Elle exige que le secret soit révocable côté cible et que l'on sache quels services vont tomber. Le temps de révocation est une métrique de sécurité de premier ordre.
Destruction. Effacement des copies devenues inutiles, sauvegardes comprises. L'étape la plus ignorée ; son absence explique les secrets morts qui ressuscitent lors des restaurations.
Grille de lecture : face à une pratique ou un outil, passer ces six étapes en revue et demander ce qu'il améliore à chacune. Un coffre qui ne traite que le stockage traite la partie facile.
1.8 Les approches traditionnelles et leurs limites¶
Les fichiers chiffrés dans le dépôt. Le progrès est réel : plus de clair dans l'historique, et les secrets suivent le flux de revue. Trois limites structurelles. Le déchiffrement a lieu chez chaque consommateur, donc le clair réapparaît partout où l'on déploie. Il n'existe ni trace de lecture ni révocation : retirer l'accès à qui a déjà cloné ne retire rien. Et la question centrale se déplace : les fichiers sont chiffrés avec une clé, que personne ne protège ni ne fait tourner.
Le gestionnaire de mots de passe d'équipe. Excellent pour les secrets manipulés par des humains. Ses limites apparaissent dès qu'on y branche des machines : l'accès suppose une session humaine, il n'y a ni intégration au déploiement, ni credentials éphémères, ni audit orienté machine. Les équipes finissent par en extraire les secrets pour les coller ailleurs, recréant le sprawl en aval. Ligne de partage à retenir : le gestionnaire de mots de passe sert les humains, le gestionnaire de secrets sert les machines.
Le secret partagé d'équipe. Compte « admin » commun, clé SSH d'équipe, jeton épinglé dans un canal de discussion. La pratique la plus répandue et la plus corrosive, parce qu'elle détruit l'imputabilité : dix personnes et quatre scripts derrière un acteur unique dans les journaux. La révocation devient un événement d'équipe, donc elle n'a pas lieu. Un secret partagé depuis dix-huit mois doit être présumé connu au-delà de l'équipe.
La rotation manuelle. Son échec est structurel, pas moral. Elle exige pour chaque secret un inventaire exhaustif des usages, une fenêtre de coordination, un recouvrement et un retour arrière. Coût certain, bénéfice invisible, échec spectaculaire. L'organisation rationnelle repousse, puis ne rotationne plus que sur incident, sous pression. La conclusion n'est pas « plus de discipline » mais la rotation doit être une propriété du système, pas une tâche humaine.
1.9 Le problème du secret zéro¶
Supposons le problème résolu : tous les secrets sont dans un système central et les applications viennent les y chercher. Pour cela, chaque application doit s'authentifier, donc présenter un secret. Ce secret initial est le secret zéro. Il ne peut pas être rangé dans le coffre qu'il sert à ouvrir. Ce n'est pas un défaut de produit mais une propriété logique de tout système d'authentification.
Ce qui distingue les bonnes solutions est le traitement de ce point de départ. Les mauvaises font semblant qu'il n'existe pas : un fichier en clair sur le serveur, sans rotation. Les bonnes appliquent quatre stratégies : réduire le secret zéro à un seul par consommateur ; le rendre éphémère et à usage limité ; le livrer par un canal contrôlé et traçable ; ou le supprimer en s'appuyant sur une identité que la plateforme fournit déjà, celle d'une machine cloud, d'un pod ou d'un pipeline.
Critère de jugement : face à toute solution, demandez ce qu'elle fait du secret zéro. Si elle n'en parle pas, elle a déplacé le problème sans le dire.
Exemple : l'état des lieux chez Astrea¶
Sept constats, relevés par un audit de deux jours avant tout projet Vault. Chacun renvoie à un mécanisme de ce chapitre. Ils serviront de référence : la partie VI les reprendra un par un.
- Le mot de passe du compte PostgreSQL
billinga été commité dans un.envd'exemple puis retiré trois semaines plus tard. Il reste lisible dans l'historique Git et n'a jamais été changé (section 1.3). - Le même mot de passe sert en production et en préproduction (section 1.6).
- Sur app-billing-01, il est fourni par une variable d'environnement systemd, lisible dans
/procpar tout processus du même compte (section 1.3). - La clé d'API du prestataire de paiement est un secret de dépôt GitHub Actions, mais un
echode débogage l'a imprimée dans les journaux d'une exécution il y a quatre mois. Le masquage n'a pas joué : la clé était insérée dans une URL (section 1.4). - La clé privée du certificat wildcard
*.astrea.labest posée sur un partage de fichiers interne (section 1.8, secret partagé). - L'équipe d'exploitation partage une unique clé SSH d'astreinte, transmise par messagerie (même section).
- La sauvegarde nocturne part chiffrée vers un stockage objet, mais la clé de chiffrement est dans le script de sauvegarde, lui-même versionné (section 1.1).
Aucun de ces choix n'a été fait par négligence. Chacun a été la solution la plus simple à un problème du moment. Sans architecture dédiée, la gestion des secrets converge vers cet état, et aucune charte de bonnes pratiques ne l'en empêche.
Sécurité : quatre incidents publics¶
Dans les compromissions documentées, le secret exposé est l'un des points de passage les plus fréquents. Le schéma est constant : l'attaquant obtient un premier accès limité, y découvre un secret stocké, et ce secret lui ouvre un système plus profond où il recommence.
Uber, 2022. Après avoir obtenu l'accès au compte d'un prestataire par ingénierie sociale, l'attaquant a trouvé un script PowerShell contenant en dur des identifiants d'administration de la plateforme de gestion des accès à privilèges, c'est-à-dire du coffre des autres secrets. L'ampleur ne vient pas de la défaillance périmétrique mais d'un secret à très haut pouvoir stocké en clair dans un fichier.
Codecov, 2021. Des attaquants ont extrait un credential d'une image Docker publique de l'éditeur, puis modifié un script que des milliers de clients exécutaient dans leurs pipelines. Le script exfiltrait les variables d'environnement des exécutions. Une fuite chez un fournisseur devient une collecte chez ses clients, et l'environnement d'un pipeline est une cible de premier ordre.
Toyota, 2022. Un sous-traitant avait publié sur un dépôt public du code contenant une clé d'accès à un serveur de données clients. La clé y est restée près de cinq ans. La fuite par le code n'est pas un événement ponctuel mais un état durable : sans détection active, la durée d'exposition se compte en années.
CircleCI, 2023. Un logiciel malveillant sur le poste d'un ingénieur a permis de détourner une session authentifiée et d'accéder aux secrets que les clients stockaient dans la plateforme. La recommandation officielle fut de considérer comme compromis tous les secrets confiés au service. Deux leçons : centraliser chez un tiers, c'est hériter de son modèle de sécurité ; et la question « combien de temps nous faut-il pour tout faire tourner ? » a reçu ce jour-là, dans beaucoup d'organisations, la réponse « des semaines ».
Erreurs fréquentes¶
Croire qu'un secret supprimé du dépôt a disparu. L'historique, les clones, les forks et les caches le conservent. Un secret entré dans Git se révoque, il ne s'efface pas (section 1.3).
Considérer base64 comme une protection. L'encodage se décode instantanément et sans clé (section 1.4).
Confondre chiffré et réglé. « Nos sauvegardes sont chiffrées » : et la clé, où est-elle, qui y accède, quand a-t-elle tourné ? Si la réponse est « dans le script », le chiffrement a déplacé le problème (section 1.1).
S'en remettre au réseau privé. Ce raisonnement suppose l'attaquant dehors, alors que les compromissions se jouent après le premier accès (chapitre 2, Zero Trust).
Ne faire tourner les secrets qu'au départ d'un collaborateur. C'est traiter la rotation comme un geste social. Si la rotation au départ d'une personne est difficile, la rotation tout court est impossible (section 1.8).
Compter sur le masquage des journaux de CI. Filet de dernier recours qui cède au premier encodage. La protection réelle est de ne pas faire transiter le secret, et de fournir des credentials éphémères (section 1.4, chapitre 39).
Employer le gestionnaire de mots de passe d'équipe pour des machines. Les secrets en sont extraits à la main : le coffre est propre et le sprawl prospère en aval (section 1.8).
Mise en pratique : inventorier avant d'outiller¶
Exercice sans composant Vault, à pratiquer exclusivement sur des systèmes qui vous appartiennent.
- L'historique d'un dépôt. [Démonstration]
# -p : affiche le contenu des modifications (patch) de chaque commit,
# ce qui fait ressortir les valeurs ajoutees puis retirees.
git log -p | grep -inE 'password|passwd|secret|api[_-]?key|token|BEGIN (RSA|EC|OPENSSH) PRIVATE KEY' | head -50
Pour un travail sérieux, utilisez un scanner dédié tel que gitleaks : gitleaks detect --source . -v. Notez chaque découverte avec sa date d'entrée dans l'historique : c'est votre durée d'exposition.
-
L'environnement des processus. [Démonstration] Choisissez un service qui tourne et examinez son environnement via
/proc/<pid>/environ. Demandez-vous quels autres processus et quels autres comptes peuvent faire cette lecture. -
La feuille d'inventaire. Pour cinq secrets réels, une par famille de la section 1.2, remplissez : source de vérité ; nombre de copies connues et leur emplacement ; qui peut lire chaque copie ; date du dernier changement ; ce qu'il faudrait faire pour la changer demain ; ce qu'il faudrait faire pour la révoquer dans l'heure. Les cases que vous ne savez pas remplir sont le résultat de l'exercice.
Questions de compréhension¶
- Donnez la définition opérationnelle d'un secret et tranchez : un identifiant de compte, une adresse IP interne, une clé publique.
- Expliquez, avec la mécanique des couches, pourquoi un fichier supprimé lors d'une étape ultérieure d'un build reste récupérable.
- Pourquoi la réponse correcte à un secret commité est-elle la révocation plutôt que la réécriture d'historique ? Donnez deux raisons indépendantes.
- En quoi le chiffrement d'un fichier de secrets déplace-t-il le problème ? Formulez la question qui permet de le vérifier.
- Citez les six étapes du cycle de vie et, pour chacune, une défaillance typique.
- Quelle différence de nature y a-t-il entre rotation et révocation, et pourquoi la seconde est-elle le vrai test ?
- Pourquoi l'échec de la rotation manuelle est-il structurel ? Déroulez le cercle vicieux du sprawl.
- Formulez le problème du secret zéro et citez deux stratégies, dont une qui ne distribue aucun secret.
Synthèse¶
Un secret est un porteur d'autorité : le connaître, c'est pouvoir agir, et le système ne distingue pas le voleur du propriétaire. Les secrets fuient par dépôt, pas par cryptanalyse : historique Git, environnements, configurations, pipelines, couches d'images, objets Kubernetes, journaux, sauvegardes, télémétrie. Chaque copie est une surface, les copies se multiplient par accumulation de décisions raisonnables, et ce sprawl verrouille la rotation. Le chiffrement concentre le problème sur une clé, et la question « qui protège cette clé ? » remonte jusqu'à une racine de confiance. Tout système central bute enfin sur le secret zéro et se juge à la façon dont il le traite.