Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English
Read in English

Pourquoi les secrets statiques posent problème

Par mis à jour le

Améliorer cette page

Un secret statique est un identifiant créé une fois, stocké quelque part et réutilisé pendant des mois : mot de passe de base de données, clé d'API, jeton d'accès cloud. Cette leçon s'adresse au DevOps qui hérite de dizaines de ces secrets et veut comprendre pourquoi ils posent problème avant de choisir une alternative. Le défaut n'est pas cryptographique : c'est la durée de vie, la copie et l'absence d'identité qui coûtent cher.

Un exemple mesuré le montre. Un jeton GitHub ghp_ commité puis retiré au commit suivant est invisible pour gitleaks 8.30.1 en mode dir, et trouvé en mode git dans l'historique, avec un code de sortie 1. Le fichier a disparu, le secret non : tant qu'il n'est pas révoqué, il reste utilisable.

  • Définir un secret statique et ses cinq propriétés d'usage
  • Expliquer pourquoi la durée de vie, la copie et le partage créent le risque
  • Reconnaître six symptômes d'une gestion immature dans votre organisation
  • Mesurer qu'un secret retiré d'un fichier survit dans l'historique Git
  • Choisir une trajectoire : coffre-fort, secrets dynamiques, puis identité de workload
  • Situer cette démarche dans l'exigence SOCLE-SEC-ROT-2, qui privilégie les identités courtes

Un secret statique est une valeur fixe qui existe avant d'être utilisée, reste valide longtemps et ne change que lorsqu'un humain décide de la changer. Le terme s'oppose au secret dynamique, généré à la demande avec une expiration courte, et à l'identité de workload, qui supprime le secret partagé. Le tableau résume les cinq propriétés qui le caractérisent ; chacune est inoffensive seule, c'est leur cumul qui crée le risque.

CaractéristiqueDescription
PréexistenceLe secret existe avant d'être utilisé
Stockage persistantIl est stocké quelque part (fichier, variable, coffre-fort)
Partage fréquentSouvent réutilisé par plusieurs composants
Longue durée de vieValide pendant des mois ou des années
Rotation manuelleChangé rarement, souvent à la main

Trois formes reviennent dans presque toutes les équipes. Les valeurs ci-dessous sont des exemples : celles d'AWS sont les clés d'illustration publiées par la documentation officielle, qui ne donnent accès à rien.

Mot de passe de base de données :

Fenêtre de terminal
# Défini une fois dans un fichier de configuration
DB_PASSWORD="SuperSecretPassword123!"

Ce mot de passe est créé lors de l'installation, stocké dans un .env ou un coffre-fort, et réutilisé pendant toute la vie de l'application. Il est parfois partagé entre plusieurs applications qui accèdent à la même base.

Clé d'API de service externe :

Fenêtre de terminal
# Générée sur le portail du fournisseur
STRIPE_API_KEY="sk_live_abc123xyz789..."

Cette clé d'API est générée une fois, stockée dans les secrets CI/CD ou le coffre-fort, et utilisée par tous les environnements qui appellent le fournisseur. Beaucoup de fournisseurs n'offrent aucune alternative à ce modèle.

Clés d'accès cloud :

Fenêtre de terminal
# Access keys AWS créées manuellement (valeurs d'exemple de la doc AWS)
AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

Ces clés d'accès sont créées dans la console IAM, stockées dans le pipeline et utilisées pendant des mois. La documentation AWS les qualifie elle-même de risque pour le compte et recommande des identifiants temporaires (rôles IAM) à la place. Elle limite aussi un utilisateur à deux clés d'accès simultanées, ce qui borne la rotation sans coupure.

Un mot de passe long et aléatoire reste cryptographiquement solide pendant des années. Ce sont ses propriétés d'usage qui posent problème : sa durée de vie, sa tendance à se dupliquer et le fait qu'il ne porte aucune identité. Les six angles qui suivent vont du plus visible au plus structurel.

Plus un secret existe longtemps, plus il a d'occasions de fuir. Il est découvert par un attaquant, copié dans un endroit non protégé, partagé avec des personnes qui n'en ont plus besoin, ou oublié dans un ancien système. Chaque mois de validité ajoute une fenêtre d'exploitation.

La conséquence est mécanique : un secret volé il y a six mois est peut-être toujours actif aujourd'hui. Un jeton qui expire en une heure, à l'inverse, ne vaut presque rien une heure après le vol. La durée de vie est donc le premier levier, avant même la qualité du stockage.

Un secret statique a tendance à se propager. Le schéma suit un parcours fréquent : la valeur part du coffre-fort, est recopiée dans un Secret Kubernetes, injectée comme variable d'environnement, puis fuit dans les journaux de démarrage ou un dump de débogage. Les deux dernières copies sont en rouge : personne ne les a décidées.

Propagation d'un secret statique : le secret d'origine, dans un coffre, est copié dans un Secret Kubernetes, injecté comme variable d'environnement, puis fuit dans les logs de démarrage et est capturé dans un dump de débogage.copieinjectionfuitecaptureSecret d'origine(coffre)SecretKubernetesVariabled'environnementLogs dedémarrageDump dedébogage
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

Chaque copie est une surface d'attaque supplémentaire, et surtout un endroit de plus à nettoyer le jour d'une révocation. Le coffre-fort protège l'original ; il ne protège aucune des copies qui en descendent.

Quand un secret statique est compromis, la révocation suppose quatre gestes qui doivent tous réussir. Le premier est le plus difficile, parce qu'il exige un inventaire à jour des consommateurs que la plupart des équipes n'ont pas.

  1. Identifier tous les endroits où le secret est utilisé
  2. Générer un nouveau secret
  3. Déployer ce nouveau secret partout
  4. Vérifier que l'ancien ne fonctionne plus

En pratique, l'opération est rarement complète. Il reste un vieux script, un job cron oublié ou une copie dans une sauvegarde qui continue d'utiliser l'ancienne valeur. Et la révocation dépend du fournisseur : un mot de passe changé dans un fichier ne l'est pas forcément dans la base de données.

Supprimer la ligne qui contenait le secret ne le fait pas disparaître : Git conserve chaque version de chaque fichier. La mesure suivante rejoue le cas avec gitleaks 8.30.1, le détecteur de secrets que la leçon Détecter les secrets exposés dans votre code enseigne dans le module « Détecter une fuite, et y répondre ». Un jeton GitHub ghp_ est commité dans deploy.env, puis le fichier est supprimé au commit suivant.

Fenêtre de terminal
$ gitleaks dir /r --no-banner
INF no leaks found
$ gitleaks git /r --no-banner --redact -v
Finding: REDACTED
Secret: REDACTED
RuleID: github-pat
Entropy: 5.121928
File: deploy.env
Line: 1
Commit: d400395794befbc7039f5fdad842ea1aa9f0f197
...
INF 1 commits scanned.
WRN leaks found: 1
$ echo $?
1

Le mode dir ne lit que les fichiers présents et ne voit rien ; le mode git parcourt l'historique et trouve le jeton, avec un code de sortie 1 qui suffit à faire échouer un job. Quiconque clone le dépôt peut faire de même avec git log -p. La seule protection réelle est la révocation du jeton, détaillée dans la leçon Réagir à un secret compromis.

Mauvaise adaptation aux environnements éphémères

Section intitulée « Mauvaise adaptation aux environnements éphémères »

Un secret statique suppose un environnement stable : l'application démarre une fois et tourne longtemps, le secret est configuré au déploiement, la rotation se fait lors des maintenances planifiées. Ce modèle tient sur un serveur qui vit trois ans.

Il casse quand des dizaines de pods Kubernetes sont créés par minute, quand chaque fonction serverless a besoin d'un accès, ou quand l'infrastructure est reconstruite chaque jour. Distribuer à la main une valeur fixe à des charges qui vivent quelques minutes revient à donner à chacune une clé permanente pour un usage temporaire.

Quand plusieurs services partagent le même identifiant, les journaux de la base ne voient qu'un seul utilisateur. Le schéma montre trois services qui se connectent tous en app_user : si une requête suspecte apparaît, rien ne dit lequel l'a envoyée. Le service C, en rouge, peut être compromis sans que la base le sache.

Trois services A, B et C se connectent à la même base de données avec le même utilisateur app_user ; face à une requête suspecte, la base ne peut pas dire quel service l'a émise.user: app_useruser: app_useruser: app_userService AService BService CBase de donnéesQuel service a faitcette requête ?
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

L'OWASP le formule dans sa fiche Secrets Management Cheat Sheet : des services qui partagent les mêmes secrets rendent l'identification de la source d'une compromission difficile. Un identifiant par service rétablit l'attribution, et permet de révoquer un seul service sans couper les deux autres.

Les six situations suivantes se rencontrent dans la plupart des organisations qui débutent. Chacune se reconnaît à un extrait de configuration et se corrige par une mesure précise. Les valeurs montrées sont des contre-exemples volontaires.

Symptôme 1 : mot de passe de base partagé entre applications

Section intitulée « Symptôme 1 : mot de passe de base partagé entre applications »

Le même mot de passe est recopié dans deux manifestes : côté base de données, rien ne distingue plus les deux applications, et la compromission de l'une vaut compromission de l'autre.

# ❌ Application 1
env:
- name: DB_PASSWORD
value: "shared-password-123"
# ❌ Application 2 (même secret)
env:
- name: DB_PASSWORD
value: "shared-password-123"

La correction est un identifiant distinct par application, idéalement dynamique : un moteur comme Vault ou OpenBao peut créer un utilisateur de base à la demande, avec une durée de vie bornée.

Symptôme 2 : jeton d'administration utilisé « par facilité »

Section intitulée « Symptôme 2 : jeton d'administration utilisé « par facilité » »

Un jeton d'administration se retrouve dans un script de déploiement parce que créer un jeton restreint demandait quelques minutes de plus. Le script dispose alors de tous les droits du compte qui l'a créé.

Fenêtre de terminal
# ❌ Script de déploiement
export GITHUB_TOKEN="ghp_AdminTokenWithFullAccess..."

La correction est un jeton à permissions minimales, comme un fine-grained PAT GitHub limité à un dépôt et à une durée, en lecture seule si possible. Dans un pipeline, l'OIDC supprime même ce jeton, comme le montre Sécuriser les secrets dans vos pipelines CI/CD.

Symptôme 3 : secret copié entre Kubernetes et les postes

Section intitulée « Symptôme 3 : secret copié entre Kubernetes et les postes »

Le même mot de passe vit à deux endroits qui n'ont ni le même cycle de vie ni le même niveau de protection : un objet du cluster et un fichier .env sur un poste de travail.

Fenêtre de terminal
# Le secret est dans Kubernetes
kubectl get secret db-creds -o jsonpath='{.data.password}' | base64 -d
# ❌ Mais aussi dans un .env pour le développement local
cat .env
DB_PASSWORD=same-password-here

La correction est une source unique de vérité (le coffre-fort) et une injection au démarrage du processus, avec des identifiants distincts pour le développement local.

La rotation est traitée comme une tâche de fond, sans échéance contraignante ni automatisation. Elle est donc systématiquement repoussée par les urgences, et le ticket finit par changer de trimestre.

Ticket : "Rotation des secrets annuelle"
Assigné : Équipe Ops
Priorité : Basse
Statut : Reporté (3e fois)

Une rotation pénible ne sera pas faite. La correction passe par la rotation automatisée, ou mieux par des secrets dynamiques qui expirent seuls et rendent la rotation planifiée inutile.

Symptôme 5 : ancien secret jamais révoqué après un incident

Section intitulée « Symptôme 5 : ancien secret jamais révoqué après un incident »

L'incident a bien déclenché la création d'un nouveau secret, mais l'ancien n'a jamais été révoqué côté fournisseur. Il reste utilisable, et personne ne le surveille plus puisque l'incident est clos.

Historique :
- Janvier : fuite suspectée du jeton d'API
- Janvier : nouveau jeton généré
- Mars : ancien jeton toujours actif (oublié)
- Juin : ancien jeton utilisé par un attaquant

La correction est une procédure de révocation écrite, qui se termine par une vérification : tenter d'utiliser l'ancien secret et constater l'échec. Sans ce test, la révocation n'est qu'une intention.

Symptôme 6 : même identifiant en développement et en production

Section intitulée « Symptôme 6 : même identifiant en développement et en production »

Le même identifiant traverse les trois environnements, ce qui aligne le niveau de sécurité de la production sur celui du poste de développement le moins protégé.

Fenêtre de terminal
# ❌ .env.dev
DB_PASSWORD="password123"
# ❌ .env.staging
DB_PASSWORD="password123"
# ❌ .env.prod
DB_PASSWORD="password123"

La correction est un secret distinct par environnement, généré automatiquement, avec des droits d'accès séparés : un développeur n'a aucune raison de pouvoir lire le secret de production.

Les trois enchaînements décrits ici sont courants, pas extrêmes. Ils partagent le même point de bascule : le dommage ne vient pas du vol initial, il vient du fait que le secret dérobé est encore valide au moment où l'attaquant décide de s'en servir.

Un développeur commite une clé d'API pour tester, puis la retire dans le commit suivant. Comme mesuré plus haut avec gitleaks, l'historique Git conserve la valeur. Un an plus tard, un attaquant qui scanne les dépôts publics la retrouve.

L'impact tient en une phrase : la clé est toujours active, parce que personne ne l'a révoquée ni remplacée. Le retrait du fichier a donné une impression de correction sans rien changer à la validité du secret.

Trois microservices utilisent le même mot de passe PostgreSQL. Une vulnérabilité dans le service le moins critique permet à un attaquant de lire les variables d'environnement du processus.

L'attaquant a maintenant accès à la base de données partagée par les trois services, y compris aux données des deux autres. Le service le plus faible fixe le niveau de sécurité de toute la base.

Une équipe veut renouveler un mot de passe critique, utilisé par cinq applications en production, deux jobs cron, trois scripts de maintenance et une intégration tierce. Coordonner le changement simultané de onze consommateurs paraît trop risqué, et la rotation est reportée.

Le secret reste inchangé pendant trois ans. Ce n'est pas un manque de volonté : c'est le couplage entre un secret et ses consommateurs qui rend la rotation dangereuse. Les secrets dynamiques suppriment ce couplage, puisque chaque consommateur reçoit sa propre valeur.

Aucune organisation ne supprime ses secrets statiques d'un coup : certaines intégrations tierces n'acceptent qu'une clé de longue durée. La progression se fait en trois temps, en réduisant d'abord le risque porté par les secrets existants avant de changer de modèle. La leçon suivante, Inventorier et classer ses secrets, outille le préalable de la première étape : savoir où se trouvent les secrets. Les modules suivants détaillent ensuite chaque étape : le coffre dans « Un coffre, et des accès scopés », les secrets dynamiques dans « Des secrets qui expirent d'eux-mêmes », l'identité de workload dans « Supprimer le secret partagé ».

Même sans pouvoir éliminer les secrets statiques, cinq gestes réduisent fortement le risque. Le premier, la centralisation, conditionne les quatre autres : on ne trace ni ne renouvelle un secret dont on ignore l'emplacement.

  1. Centraliser dans un coffre-fort (OpenBao, Vault, Infisical)
  2. Séparer par environnement (développement, recette, production)
  3. Limiter les permissions au strict nécessaire
  4. Tracer tous les accès
  5. Planifier des rotations régulières, automatisées si possible

Les secrets les plus critiques peuvent devenir dynamiques : générés à la demande, propres à chaque consommateur et expirés automatiquement. Trois formes sont courantes : des identifiants de base de données créés par un moteur de secrets, des jetons cloud à durée de vie courte, et des certificats renouvelés automatiquement.

Le gain est double. La rotation disparaît comme tâche, puisque chaque valeur expire seule, et l'attribution revient, puisque chaque consommateur a sa propre valeur. La leçon Cycle de vie d'un secret montre comment le TTL (durée de vie) remplace la rotation planifiée.

Pour les échanges entre machines, l'étape suivante supprime le secret partagé au profit d'une identité de workload (l'identité propre d'un programme qui tourne). Trois familles existent : SPIFFE/SPIRE pour des identités cryptographiques internes, la fédération OIDC des clouds (GCP, AWS, Azure) pour les accès aux API cloud, et le mTLS entre services.

Ce passage pose une question préalable, celle du secret zéro : qui donne à l'application le premier secret qui ouvre le coffre ? Deux leçons du module « Supprimer le secret partagé » y répondent : Le problème du secret zéro et Identité machine et workload identity. Elles montrent pourquoi l'attestation par la plateforme casse la boucle.

Ces six questions mesurent votre maturité actuelle. Une réponse éloignée de la colonne de droite désigne le symptôme à traiter en premier ; la révocation testée est celle que les équipes cochent le moins souvent.

QuestionRéponse idéale
Combien de temps vos secrets restent-ils valides ?Heures ou jours, pas mois
Un secret est-il partagé entre plusieurs services ?Non, un par service
Pouvez-vous renouveler un secret en moins d'une heure ?Oui, de façon automatisée
Savez-vous quels services utilisent chaque secret ?Oui, avec certitude
Les environnements ont-ils des secrets distincts ?Oui, toujours
La révocation d'un secret est-elle testée régulièrement ?Oui, en exercice
  • Un secret statique est cryptographiquement solide ; ce sont sa durée de vie, ses copies et son partage qui créent le risque.
  • Chaque copie (Secret Kubernetes, variable d'environnement, logs, dump) est un endroit de plus à nettoyer le jour d'une révocation.
  • Un secret retiré du code reste dans l'historique Git : gitleaks 8.30.1 le trouve en mode git, pas en mode dir.
  • Un identifiant partagé entre services rend l'attribution impossible et empêche de révoquer un seul consommateur.
  • Une rotation manuelle et pénible ne sera pas faite : automatisation ou secrets dynamiques.
  • La trajectoire va du coffre-fort aux secrets dynamiques, puis à l'identité de workload.
  • La preuve attendue par SOCLE-SEC-ROT-2 est l'usage d'identités courtes ou éphémères (OIDC) privilégié sur les secrets de longue durée.

Vérifiez que l'essentiel de cette leçon est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn