Sécuriser les secrets et permissions CI/CD
- Accueil
- Développement, applications & chaîne logicielle
- Sécuriser les secrets et permissions CI/CD
Sécuriser les secrets et permissions CI/CD
Section intitulée « Sécuriser les secrets et permissions CI/CD »Une pipeline CI/CD (Continuous Integration and Continuous Delivery, intégration et livraison continues) est un compte d’administration qui exécute du code fourni par un dépôt. La traiter comme un simple outil de build revient à laisser les clés du datacenter dans une boîte aux lettres, avec un autocollant « DevOps ».
Une chaîne automatique de livraison ressemble à un atelier qui reçoit des plans, fabrique un objet puis l’envoie sans pause. Si quelqu’un peut modifier les plans ou ouvrir l’atelier, il peut aussi faire fabriquer n’importe quoi. Les contrôles servent à empêcher qu’une seule personne ou erreur décide de tout.
→ Lire l’explication complète de la marmotte
Compromis entre vitesse de livraison et rayon d’explosion
Section intitulée « Compromis entre vitesse de livraison et rayon d’explosion »Le compromis central est brutal : réduire les validations accélère les changements, mais agrandit le rayon d’explosion d’un compte compromis, d’une dépendance malveillante ou d’une erreur de configuration. La recommandation est de payer le coût de contrôles ciblés sur les frontières irréversibles : fusion vers une branche protégée, émission d’un jeton de déploiement, promotion en production et modification de la politique de pipeline.
Une revue à quatre yeux ne doit pas s’appliquer à chaque modification de documentation. Elle doit s’appliquer aux changements qui modifient du code exécutable, l’infrastructure, les identités, les dépendances, les secrets ou les règles de contrôle. Sinon, la règle devient un tampon administratif, puis un bouton vert pressé entre deux cafés. La sécurité adore les rites qui n’empêchent rien.
Avant de durcir la pipeline, il faut disposer de :
- branches protégées avec interdiction de pousser directement ;
- identité individuelle fédérée au forge, avec authentification multifacteur ;
- exécuteurs isolés par niveau de confiance ;
- registre d’artefacts séparé du dépôt source ;
- journaux d’audit exportés hors de la plateforme CI/CD ;
- procédure de révocation d’urgence des accès et secrets ;
- inventaire des environnements, propriétaires et comptes de service.
Une pipeline ne garantit pas l’absence de défaut dans le code qu’elle compile. Elle ne garantit pas non plus qu’un approbateur comprend réellement un changement. Elle garantit seulement qu’une politique technique bloque certaines transitions. La revue humaine doit donc s’appuyer sur des tests, une analyse de dépendances et une lecture ciblée des changements à risque. Les fondations Git restent décrites dans la section architecture cybersécurité, mais la sécurité de pipeline commence là où le dépôt devient une autorité de déploiement.
Secrets CI/CD : supprimer les jetons permanents
Section intitulée « Secrets CI/CD : supprimer les jetons permanents »Un secret permanent stocké dans le forge est acceptable uniquement lorsqu’aucune fédération d’identité n’est disponible. Dans tous les autres cas, il faut préférer un jeton éphémère obtenu à l’exécution via OIDC (OpenID Connect). La plateforme CI/CD émet alors une preuve d’identité signée, et le fournisseur cible échange cette preuve contre des droits limités dans le temps.
Cette architecture réduit deux risques distincts. D’abord, l’exfiltration d’un secret de dépôt ne donne plus un accès durable. Ensuite, chaque autorisation peut être liée au dépôt, à la branche, au workflow et à l’environnement ciblé. Un jeton valide pour main ne doit pas pouvoir déployer depuis une branche de fonctionnalité. Sans cette contrainte, OIDC devient un mot de passe long avec une moustache cryptographique.
Les secrets qui restent nécessaires doivent être classés selon leur portée :
| Catégorie | Stockage | Durée | Contrôle |
|---|---|---|---|
| Clé de signature de release | HSM (Hardware Security Module) ou service de clés | Persistante | Opération de signature autorisée, export interdit |
| Jeton de déploiement cloud | Aucun stockage statique | Minutes | Fédération OIDC et conditions de revendications |
| Mot de passe d’un système ancien | Coffre de secrets | Rotation planifiée | Injection au job autorisé uniquement |
| Clé privée de chiffrement | HSM ou coffre avec contrôle matériel | Persistante | Double contrôle et journal d’usage |
Les variables masquées ne sont pas un coffre-fort. Elles empêchent surtout l’affichage accidentel dans les journaux. Un script peut les exfiltrer par requête réseau, les encoder, les écrire dans un artefact ou les transmettre par une erreur de build. Masquer une valeur ne transforme pas un exécuteur compromis en machine vertueuse.
Chaque secret doit avoir un propriétaire, une finalité, une date de rotation, une procédure de révocation et une alerte sur son usage. Pour les clés cryptographiques, la gestion doit suivre les principes détaillés dans la rubrique cryptographie. Une sauvegarde chiffrée sans test de restauration n’est pas une reprise, c’est une croyance avec chiffrement.
Permissions minimales et isolation des exécuteurs
Section intitulée « Permissions minimales et isolation des exécuteurs »Le compte de pipeline doit recevoir des permissions explicites, jamais un rôle global de type administrateur de projet ou propriétaire de cloud. Le principe est celui du moindre privilège : chaque job reçoit seulement les droits nécessaires à son action, pendant la durée nécessaire.
La séparation doit porter sur trois plans :
- Permissions du forge : lecture du code, écriture de statut, publication de paquet ou création de release sont des droits distincts.
- Permissions de l’environnement cible : un job de test ne peut pas obtenir un jeton de production, même s’il exécute le même dépôt.
- Isolation d’exécution : un runner partagé ne doit pas traiter un dépôt non fiable puis un déploiement sensible dans le même contexte persistant.
Un runner auto-hébergé est une cible de persistance évidente. Un contributeur qui obtient l’exécution de code peut déposer un binaire dans le cache, modifier un outil présent dans l’image ou lire les fichiers laissés par un job précédent. Les runners éphémères, recréés pour chaque exécution, constituent la position par défaut pour les charges sensibles. Le cache doit être traité comme une entrée non fiable : clé de cache liée au verrouillage de dépendances, lecture seule lorsque possible, absence de cache partagé entre projets de niveaux différents.
Les actions, plugins et images de conteneur constituent une autre frontière. Référencer une action par un tag mutable, par exemple v4, délègue la sécurité à une valeur qui peut changer sans modification du dépôt. Il faut épingler les dépendances par empreinte immuable, vérifier leur provenance et maintenir un processus de mise à jour. Le manifeste de dépendances est du code privilégié déguisé en plomberie.
L’IAM (Identity and Access Management, gestion des identités et des accès) doit aussi refuser les chemins indirects. Un job incapable d’assumer un rôle de production ne doit pas pouvoir modifier une politique qui lui permettrait de le faire. La persistance dans les permissions cloud mérite une surveillance dédiée, notamment pour les ressources créées hors pipeline, comme détaillé dans la section cloud.
Revue à quatre yeux et branches protégées
Section intitulée « Revue à quatre yeux et branches protégées »La revue à quatre yeux signifie qu’une personne différente de l’auteur valide le changement avant fusion ou déploiement. Cette séparation échoue si l’auteur peut modifier les règles de branche, ignorer les validations, approuver sa propre demande ou pousser directement sur la branche protégée.
Les règles minimales sont les suivantes :
- exiger au moins une approbation indépendante pour les branches de livraison ;
- invalider les approbations lors d’un nouveau commit ;
- interdire l’approbation par l’auteur ;
- exiger la réussite des jobs de sécurité non contournables ;
- limiter la modification des règles de protection à un groupe séparé ;
- exiger une approbation d’environnement avant un déploiement de production ;
- journaliser approbations, refus, contournements et modifications de règles.
Le contrôle doit porter sur la configuration CI/CD elle-même. Une demande de fusion qui réduit permissions, modifie une relation de confiance OIDC ou ajoute un secret doit déclencher des réviseurs désignés. Sans cela, la revue protège le code applicatif pendant que le vrai levier d’administration passe derrière le rideau avec une cape noire.
La séparation des rôles doit survivre aux absences. Un unique approbateur de production crée une dépendance opérationnelle, pas une sécurité. Prévoir au moins deux personnes habilitées, tout en empêchant la validation croisée automatique entre comptes techniques. L’identité humaine, l’identité de pipeline et l’identité d’urgence doivent rester distinctes.
Exemple de workflow avec jeton éphémère
Section intitulée « Exemple de workflow avec jeton éphémère »L’exemple suivant limite les permissions GitHub Actions, exige un environnement protégé et autorise l’émission d’un jeton OIDC uniquement pour le job de déploiement. La relation de confiance côté fournisseur cloud doit ensuite vérifier le dépôt, la branche et l’environnement annoncés dans le jeton.
name: deploy-production
on: push: branches: [main] # La branche doit être protégée côté forge.
permissions: contents: read # Lecture du dépôt, rien de plus par défaut.
jobs: deploy: environment: production # Déclenche les approbations d'environnement configurées. runs-on: ubuntu-latest permissions: contents: read id-token: write # Autorise seulement l'émission d'un jeton OIDC éphémère.
steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # Empreinte immuable, pas un tag mutable.
- name: Obtenir une identité temporaire run: | # Le fournisseur cloud échange le jeton OIDC contre des droits temporaires. # La commande réelle dépend du fournisseur et de sa politique de confiance. test -n "$ACTIONS_ID_TOKEN_REQUEST_URL"Ce fichier ne sécurise pas le déploiement à lui seul. La politique distante doit refuser les jetons émis pour une autre branche, un autre dépôt ou un autre environnement. Elle doit également limiter les actions autorisées, par exemple écrire une image dans un registre précis plutôt qu’administrer tout l’abonnement cloud.
Supervision, rotation et reprise après compromission
Section intitulée « Supervision, rotation et reprise après compromission »Les événements à surveiller sont concrets : création ou lecture de secret, modification des permissions, changement de branche protégée, ajout d’un runner, approbation d’environnement, émission de jeton fédéré, publication d’artefact et contournement de contrôle. Les journaux doivent inclure l’identité source, le dépôt, le commit, le workflow, l’environnement et le résultat.
Une alerte sans procédure de réponse est un réveil posé dans une pièce vide. Pour chaque événement critique, documenter l’action : désactiver le workflow, révoquer la relation de confiance, retirer le runner, bloquer la promotion, faire tourner le secret, reconstruire l’artefact depuis une source connue.
La reprise après compromission commence par supposer que tous les jetons accessibles par le runner ont été volés. Il faut donc révoquer les sessions actives, invalider les jetons persistants, vérifier les politiques IAM, rechercher les modifications de pipeline et reconstruire les runners depuis une image de référence. Les artefacts produits pendant la période douteuse ne doivent pas être promus sur la seule foi d’un statut vert.
🐝 Ce qui arrive si on s’en passe
Section intitulée « 🐝 Ce qui arrive si on s’en passe »Sans ces gardes à la porte, la ruche reçoit tout ce qui se présente. Un jeton permanent partagé entre plusieurs jobs ne peut plus être révoqué sans interrompre toutes les livraisons qui en dépendent, ce qui transforme la rotation en décision politique plutôt qu’en geste technique. Un exécuteur partagé fait converger toutes les actions vers une seule identité de service : l’audit ne distingue plus quel dépôt, quel commit ni quel contributeur a déclenché un accès, et le périmètre d’un incident s’étend par défaut à l’ensemble des exécutions. Sans épinglage par empreinte, rejouer une construction passée ne restitue pas le code réellement exécuté, donc la question “qu’est-ce qui est entré” reste sans réponse vérifiable. Les consommateurs en aval héritent alors d’artefacts dont la provenance ne peut plus être démontrée, seulement affirmée.
🦫 Explication de la marmotte 🍫
Section intitulée « 🦫 Explication de la marmotte 🍫 »Une chaîne de livraison automatique récupère le code enregistré dans un dépôt, lance des vérifications, fabrique un programme puis peut l’envoyer vers un serveur. Comme elle exécute du code et peut modifier des systèmes, elle possède parfois des accès très puissants.
La protection commence par empêcher une personne seule de modifier le code puis de le faire partir directement. Les branches de livraison sont verrouillées : une autre personne doit vérifier le changement, et cette validation disparaît si le code change encore. Les règles qui protègent ces branches sont elles-mêmes réservées à un petit groupe distinct.
La chaîne reçoit seulement les autorisations nécessaires à chaque tâche. Un travail de test ne reçoit pas le droit de modifier la production. Pour accéder à un service externe, elle demande un accès temporaire lié au dépôt, à la branche et à l’environnement visé. Cet accès expire rapidement. Un mot de passe permanent stocké dans la chaîne reste plus dangereux, car une fuite peut donner un accès durable.
Les machines qui exécutent les tâches doivent être séparées et recréées régulièrement. Sinon, un programme malveillant peut laisser des fichiers ou voler des accès pour les tâches suivantes. Enfin, les journaux enregistrent qui a lancé quoi, avec quel code et quels droits. En cas d’incident, il faut couper les accès, remplacer les secrets, vérifier les règles et reconstruire les éléments suspects.
À lire aussi
- Sécuriser un monorepo avec des permissions finesConcevoir des permissions à grain fin, des contrôles de fusion et une exploitation résiliente pour un monorepo partagé par plusieurs équipes.
- Comptes de service Git à révoquer réellementLes comptes de service Git accumulent des identités et jetons persistants qui échappent souvent à la révocation, à l'inventaire et à la supervision.
- Sécuriser les identifiants CI/CD avec OIDCGuide pas-à-pas pour remplacer les secrets statiques d’un pipeline CI/CD par une authentification fédérée OIDC, isoler les jobs et limiter les droits par environnement.
- Protéger les branches Git et permissions entrepriseGestion des branches et des permissions Git en entreprise comme surface de sécurité, protection de la branche principale et revue obligatoire avant fusion.
Pages voisines
La citent
- Intégration continue avec Git : automatiser vos workflows
- Écrire des scripts Bash système fiables et sûrs en production
- Python pour l'automatisation défensive, usages et garde-fous
- Attaque par désérialisation YAML non sécurisée
- L'attaque de la chaîne d'approvisionnement logicielle en une page
- OIDC pour sécuriser les identifiants CI/CD
- Slopsquatting, paquets inventés par les assistants de code IA
- Tester, auditer, répondre et migrer
Sécuriser les secrets et permissions CI/CD
Elle cite
: les deux pages se citent l’une l’autre.
