DevOps et supervision

Corriger les secrets vides dans les pull requests de forks GitHub Actions

GitHub Actions masque intentionnellement les secrets des pull requests issues de forks. Découvrez des modèles sûrs comme workflow_run pour gérer les identifiants sans compromettre la sécurité.

Illustration des étapes de pipeline CI sécurisées et non sécurisées
Illustration créée pour cet article

Traduit automatiquement depuis l’original en anglais.

Lorsqu'un pipeline d'intégration continue réussit sur les branches internes mais échoue immédiatement à la réception d'une contribution issue d'un fork externe, la cause profonde n'est souvent pas une erreur de configuration. GitHub Actions bloque intentionnellement l'accès aux secrets du dépôt lors de ces événements spécifiques afin de prévenir le vol d'identifiants. Comprendre cette frontière de sécurité est essentiel pour maintenir des pipelines robustes dans des environnements open-source ou collaboratifs, sans exposer des données sensibles à du code non fiable.

Ce qui s'est passé

Le problème central survient lorsqu'un job qui fonctionne correctement sur les branches standard rencontre des identifiants vides lors d'une pull request déclenchée par un dépôt forké. Ce comportement n'est ni un bug ni une mauvaise configuration, mais une fonctionnalité de sécurité délibérée. GitHub Actions limite le token par défaut à des permissions en lecture seule et masque complètement les secrets définis par l'utilisateur lors de ces exécutions. Le système ne propose aucun paramètre permettant de contourner cette restriction, car cela créerait une vulnérabilité critique.

L'échec se manifeste de manière subtile. Au lieu d'un message d'erreur explicite indiquant que les secrets sont manquants, la variable de secret est interpolée sous forme de chaîne vide. Les outils en aval échouent alors avec leurs propres codes d'erreur génériques, tels que HTTP 401 Unauthorized ou des plaintes concernant des entrées requises manquantes. Cette ambiguïté conduit souvent les ingénieurs à perdre du temps à déboguer la connectivité réseau ou les versions des outils, plutôt qu'à reconnaître le modèle de permissions en jeu. Une étape de diagnostic simple peut confirmer le problème en vérifiant si la source de l'événement est un fork et si la valeur du secret est non vide, offrant ainsi une clarté immédiate.

Cette conception existe parce que le code exécuté dans une pull request de fork est contrôlé par le contributeur, et non par le propriétaire du dépôt. Si les secrets étaient disponibles, un acteur malveillant pourrait modifier un script de build ou un fichier de test pour exfiltrer des clés de déploiement et des tokens API en un seul commit. En traçant la frontière de confiance au point d'exécution du code, GitHub garantit que le code non fiable n'accède jamais aux variables d'environnement sensibles. Les seuls déclencheurs qui transportent des secrets complets sont ceux qui s'exécutent dans le contexte du dépôt de base, tels que certains événements cibles ou les exécutions de workflows ultérieures.

Détails clés

  • GitHub Actions masque tous les secrets du dépôt pour les événements pull_request provenant de forks.
  • Le GITHUB_TOKEN est automatiquement limité à des permissions en lecture seule pour ces événements.
  • Les échecs apparaissent comme des erreurs d'authentification génériques ou des avertissements d'entrées manquantes, plutôt que comme des problèmes explicites de secrets.
  • Le déclencheur pull_request_target fournit des secrets mais vérifie par défaut le code de la branche de base, nécessitant une manipulation prudente pour éviter l'exécution de code PR non fiable.
  • Les pull requests Dependabot n'ont également pas accès aux secrets standards du dépôt, nécessitant une configuration séparée dans le magasin de secrets Dependabot.
  • L'utilisation de workflow_run permet à un second workflow, fiable, d'accéder aux secrets après la fin d'un build initial non fiable.

Contexte

Pour comprendre pourquoi cette restriction existe, il faut reconnaître la différence entre les contextes de code fiable et non fiable. Lors d'un push standard sur une branche, le code appartient aux collaborateurs du dépôt qui ont déjà accès aux ressources du projet. Dans une pull request de fork, le code provient d'un utilisateur externe qui peut ne pas avoir d'accès en écriture. Si le système CI exécutait ce code externe avec des privilèges administratifs complets, il accorderait effectivement à chaque contributeur la capacité de voler des identifiants.

La solution consiste à séparer le processus de build des phases de déploiement ou de tests d'intégration. La phase initiale exécute le code non fiable dans un environnement sandboxé sans secrets. Une fois que cette phase produit des artefacts, tels que des binaires compilés ou des rapports de tests, une seconde phase peut consommer ces artefacts dans un contexte fiable. Cette séparation garantit que, bien que le code soit testé, il n'interagit jamais directement avec les identifiants d'infrastructure sensibles sauf approbation explicite et isolation.

Pourquoi c'est important

Pour les équipes gérant des projets open-source ou acceptant des contributions externes, ignorer ce modèle de sécurité peut entraîner de graves violations. Tenter de contourner la restriction en utilisant des déclencheurs dangereux comme pull_request_target avec une vérification (checkout) de la tête de la pull request crée un scénario de « pwn request ». Dans cette situation, le runner CI exécute du code arbitraire du contributeur avec un accès complet à tous les secrets du dépôt. Ce risque est particulièrement élevé dans les dépôts publics populaires où les attaquants scannent activement ces mauvaises configurations pour récolter des identifiants cloud.

Inversement, ne pas gérer cela correctement entraîne une expérience dégradée pour les contributeurs. Lorsque des développeurs externes soumettent des pull requests qui échouent en raison d'identifiants manquants, ils peuvent supposer que le projet est mal maintenu ou cassé. Cette friction décourage la participation communautaire et augmente la charge de maintenance pour les membres de l'équipe principale, qui doivent expliquer manuellement l'échec. Mettre en œuvre une logique de saut claire ou des workflows fiables séparés garantit que les contributeurs reçoivent des retours précis tout en maintenant la sécurité de l'environnement de production.

De plus, beaucoup d'équipes négligent le fait que certains tests d'intégration n'exigent pas réellement de secrets actifs. En remplaçant les appels aux services externes par des stubs locaux ou des conteneurs de service, les équipes peuvent exécuter des tests plus complets dans le contexte de fork non fiable. Cette approche réduit le besoin de configurations complexes multi-workflows et accélère les boucles de retour pour les contributeurs. Elle déplace le focus de la gestion de l'accès aux secrets vers l'amélioration de l'isolation et de la fiabilité des tests.

Que pouvez-vous faire

  • Auditez vos fichiers de workflow pour identifier les étapes qui nécessitent réellement des secrets versus celles qui peuvent utiliser des stubs locaux ou des conteneurs de service.
  • Implémentez une conditionnelle dans vos jobs pour sauter les étapes dépendantes des secrets lors de l'exécution sur des pull requests de forks, en utilisant une notification visible pour expliquer le saut.
  • Utilisez l'événement workflow_run pour déclencher un second workflow qui télécharge les artefacts du build initial et effectue les tâches dépendantes des secrets dans un contexte fiable.
  • Si vous utilisez pull_request_target, assurez-vous de ne jamais vérifier (checkout) le SHA de la tête de la pull request ; restez toujours sur le code de la branche de base pour prévenir l'injection de code.
  • Configurez des secrets séparés pour Dependabot si vos mises à jour automatiques de dépendances échouent, car ils ne partagent pas le magasin de secrets principal du dépôt.
  • Publiez manuellement les statuts de commit depuis des workflows fiables pour garantir que les contributeurs voient les résultats des vérifications dépendantes des secrets sur leurs pull requests.

Autres actualités

Toutes les actualités