L’intégration de la sécurité directement dans la configuration des chaînes CI/CD, notamment par la pratique de DevSecOps, permet le développement d’applications sécurisées tout en augmentant la fréquence de livraison. Ceci permet de décharger les équipes de sécurité qui peuvent être un des facteurs limitant la fréquence de mise en production.
Cependant, il est complexe de mettre en place une chaine CI/CD pertinente et ou on-premise qui demandent également un investissement des équipes d’infrastructure. Les solutions Cloud (PaaS) apparaissent alors comme un bon intermédiaire entre customisation de la chaine CI/CD et simplicité de mise en place. Les solutions cloud permettent également de provisionner des ressources sur demande de façon à s’adapter au mieux aux besoins métier.
Il existe un grand nombre de solutions CI/CD dans le cloud permettant potentiellement de satisfaire les besoins à la fois de sécurité et d’efficacité d’une chaine de développement. Nous proposons ici de présenter notre vision des solutions d’Amazon Web Services (AWS) qui reste un des leader du marché.
Qu’est-ce que les services CI/CD AWS peuvent offrir en termes de fonctionnalités ? Quelle est leur valeur ajoutée ?
Si vous ne connaissez pas AWS CodeCommit, CodePipeline, CodeBuild ou CodeDeploy, nous proposons une entrée en matière pour mieux comprendre le fonctionnement de l’environnement DevSecOps AWS. Afin de présenter un aperçu des outils proposé par AWS, nous décrivons dans les paragraphes suivants le fonctionnement des différents services.
Reprenons depuis le début : du DevOps au DevSecOps
Le DevOps constitue un élément clé du cycle de vie du développement logiciel des entreprises. Le DevOps s’appuie sur un outillage de type CI/CD. C’est une chaîne sur laquelle repose l’évolution du code source en une application livrée en production. La CI/CD accélère les phases de construction, de test et de déploiement afin d’augmenter la fréquence de livraison des applications. Cette accélération est notamment rendue possible par l’automatisation d’un grand nombre de tâches au sein d’un « pipeline CI/CD », comprenez une succession d’actions menant au déploiement en production.
Le DevSecOps rajoute les aspects sécurité au DevOps et s’appuie sur certains outils internes à la CI/CD. Ces outils s’intègrent à tout niveau de la chaîne CI/CD afin de scanner le code source (SAST), les dépendances (SCA) etc. L’objectif est d’intégrer la sécurité au plus tôt, comme présenté dans notre article précédent.
La chaine CI/CD se positionne comme un composant d’intérêt majeur afin d’assurer la sécurité des développements. On peut aller jusqu’à dire que la chaîne CI/CD joue un rôle aussi important dans le développement sécurisé que celui qu’occupe l’AD dans la gestion des identités et des accès (IAM).
La CI/CD dans AWS
AWS offre une multitude de services permettant, en plus des services d’infrastructure classiques, de mettre en place des chaînes de développement continue (du code source à son déploiement) tout en assurant la bonne réalisation des tests de sécurité.
L’orchestrateur CodePipeline permet d’organiser et de lier les différentes étapes de la CI/CD. C’est cet outil qui coordonne la progression au sein du pipeline CI/CD en fonction des résultats des autres outils et services. Si un des outils renvoi un code d’échec, le pipeline peut être bloqué si nécessaire. Les raisons d’un échec du pipeline peuvent être nombreuses : score de sécurité du code insuffisant, échec du déploiement d’un outil…
La gestion du code : SCM et AWS CodeCommit
Les gestionnaires de versions de code (ou SCM : Source Code Manager) sont des outils indispensables dans le développement et sont le point de départ des chaînes d’intégration continue. Ces outils sont essentiels afin d’éditer du code de manière collaborative.
A date, seuls 3 SCM disposent d’une intégration native : GitHub, BitBucket et leur solution propriétaire AWS CodeCommit. Pour toute autre intégration avec un SCM non supporté nativement, il est possible de créer une routine à base de fonctions serverless Lambda et de webhook (notification HTTP) de façon à télécharger le code source dans AWS S3 à chaque commit d’un développeur.
AWS CodeCommit est le service SCM proposé par AWS. C’est un service d’hébergement de code permettant le contrôle de versions et la collaboration supportant les commandes Git, au même titre que GitHub ou GitLab. Ce service a l’avantage d’être pleinement intégré à l’environnement AWS ce qui facilite l’interconnexion avec les autres services AWS. L’utilisation d’AWS CodeCommit permet aussi d’utiliser la solution AWS IAM de gestion des identités et des accès ce qui évite la duplication d’un référentiel d’identité et la gestion des rôles au sein d’un SCM tiers.
Néanmoins, AWS CodeCommit offre des fonctionnalités relativement limitées par rapport à GitHub (ex : UI et expérience utilisateur) et dispose d’une communauté bien plus faible que GitHub ou GitLab.
Tout ceci fait d’AWS CodeCommit une solution convenable dans le cas d’une utilisation au sein d’un environnement entièrement AWS en raison de son intégration étroite à d’autres services AWS tel que AWS CodeBuild ou CodePipeline. En revanche, lorsque la chaîne CI/CD comprend plusieurs solutions externes à AWS, une autre solution telle que GitHub ou GitLab offrira plus de flexibilité.
La phase de build : AWS CodeBuild
Une fois le développement terminé, AWS CodeBuild prend le relais. Cet outil permet aussi bien de compiler/construire une application qu’exécuter des tests via des runners CI. Le service exécute les instructions qui lui sont passées en entrée dans un fichier buildspec.yml. C’est un outil polyvalent et similaire à un outil CI classique tel que GitLab CI ou GitHub Actions.
AWS CodeBuild permet également d’exécuter les tests de sécurité (SAST, SCA…) en installant et utilisant des applications sur ses runners. Prenons l’exemple de SonarQube, un outil de qualité de code avec un module SAST permettant de scanner du code source pour en ressortir les vulnérabilités. L’exécution fonctionne de la façon suivante :
- Lorsque le code source est modifié, une notification webhook (requête HTTP POST du SCM) est transmise à AWS (en pratique, cet évènement est géré par AWS EventBridge ou AWS CodePipeline) qui déclenche le test.
- Le code source est dupliqué sur le runner CI qui effectue un scan de celui-ci et produit un rapport.
- Ce rapport est ensuite envoyé à un serveur SonarQube (on-premise ou sur une EC2).
- Après analyse SonarQube produit un rapport final indiquant le niveau de sécurité du code.
- Ces résultats sont envoyés à CodeBuild qui interprète, selon les conditions présentes dans le fichier yml, si le test est réussi ou non.
Encore une fois, l’intérêt de CodeBuild réside essentiellement dans son intégration à l’environnement et permet une collaboration étroite avec les autres services AWS. Il sera par exemple plus aisé d’attribuer des rôles particuliers aux projets CodeBuild, d’utiliser AWS Secrets Manager (pour la gestion des secrets) ou de permettre le déploiement avec AWS CodeDeploy.
Le déploiement : AWS CodeDeploy
Le déploiement d’une application constitue la fin de son cycle de développement. Au sein d’AWS, le déploiement s’effectue via AWS CodeDeploy. Son rôle est de récupérer les et fichiers de configuration nécessaires dans les buckets S3 dédiés pour ensuite les déployer sur le serveur choisi (EC2…). Il diffère d’AWS Elastic Beanstalk qui permet de déployer une application uniquement grâce à son code (ne supporte généralement pas les langages compilés tel que le C/C++).
Le fonctionnement de CodeDeploy permet de déployer du code sur n’importe quel type de serveur, qu’il soit hébergé par AWS ou non. Son fonctionnement est simple : il suffit d’installer un agent (CodeDeploy agent) sur le serveur cible. C’est cet agent qui est chargé de télécharger les artéfacts, de les installer et de lancer l’application.
Il est nécessaire de définir en amont les instances concernées par le déploiement et leur appliquer un tag AWS arbitraire permettant de les identifier. L’ensemble de ces instances constitue alors un « groupe de déploiement ». Lorsque le déploiement est déclenché, CodeDeploy sélectionne les instances concernées et publie ses instructions. La communication est néanmoins initiée par l’instance cible, c’est bien l’agent CodeDeploy qui contacte (toutes les secondes par défaut) le service CodeDeploy en scrutant pour de nouvelles instructions (polling mode). Ce mode de communication évite toute ouverture de port amenuisant la posture sécurité de l’instance.
AWS CodeDeploy est un outil efficace qui permet le déploiement sur n’importe quel type d’infrastructure. Néanmoins, il nécessite l’installation d’un agent managé par AWS sur l’instance où est déployée le code, ce qui n’est pas toujours souhaitable en fonction du contexte client. On peut imaginer que le polling des instances EC2 peut impacter les performances d’une application critique ou être détecté comme malveillant par un EDR ou NDR (Network Detection & Response).
Sécurisation de la CI/CD AWS
Au vu du rôle essentiel de la chaîne CI/CD dans le développement d’applications, il est essentiel de sécuriser cette infrastructure (sécurisation de l’outillage, intégration, configuration de la chaine…). Ci-dessous nous récapitulons quelques axes d’études à ne pas négliger lors de la mise en place d’une chaine CI/CD AWS. Ces grands principes peuvent être maitrisés via la création de politiques AWS de façon à alerter ou à imposer leur application.
Gestion des flux
Par défaut, les flux vers les services managés AWS (CodeBuild, CodeDeploy…) transitent sur internet avant de revenir vers l’instance cliente de la ressource. Afin d’éviter de faire transiter l’ensemble des flux vers les services AWS par internet, nous recommandons de mettre en place des interfaces VPC endpoints. Ces points d’accès réseaux permettent aux instances au sein d’un VPC de contacter les services AWS comme s’ils étaient déployés au sein du VPC.
Gestion des secrets
Les secrets permettant d’accéder aux services ou à d’autres APIs ne peuvent être stockés en clair dans les SCM ou dans les fichiers de configuration de la chaine. On souhaite éviter toute fuite d’information confidentielle lors d’un accès – légitime ou non – à ces répertoires.
Nous recommandons la mise en place d’un coffre-fort AWS Secret Manager chargé de stocker les secrets (ex : clés API SonarQube…) et de les distribuer aux services uniquement lorsque nécessaire. La récupération d’un secret se fait alors par un appel API à ce coffre-fort avec vérification des privilèges.
Supervision / monitoring
Tout comme n’importe quelle infrastructure, la chaine CI/CD nécessite d’être supervisée. Les solutions AWS natives pour la supervision de services sont AWS CloudWatch pour le recueil de logs, AWS EventBridge pour la création d’alertes et AWS SNS / SQS permettent l’envoie de notification à des groupes prédéfinis (mail, SMS, push notification…). La supervision de la chaine CI/CD permettrait d’alerter des mises en production dangereuses par exemple dans le cas où un projet souhaiterai contourner les politiques de sécurité mises en œuvre.
Identity and Access Management
La gestion des privilèges au sein d’AWS est traité selon le modèle Rôle Based Access Control (RBAC). Chaque action utilisateur requiert une permission spécifique. Par exemple, si un utilisateur souhaite accéder à un bucket S3, il doit d’abord obtenir la permission en lecture associée à la ressource correspondante au S3. On rappellera l’importance du principe du moindre privilège qui consiste à attribuer aux clients (utilisateurs & services) uniquement les droits dont ils ont besoin.
Les droits AWS permettent une configuration totale des accès de chaque client à chaque service / ressource. Cette flexibilité permet de définir précisément le périmètre d’autorisation de chaque acteur de l’environnement AWS. Néanmoins, la finesse des droits peut être fastidieuse à configurer dans une infrastructure CI/CD de grande ampleur.
AWS propose des rôles prédéterminés qui permettent d’appliquer rapidement un ensemble de permissions. Néanmoins, ces rôles prédéfinis ne permettent souvent pas de respecter le principe du moindre privilège. Il est donc important de créer des rôles permettant d’appliquer le principe du moindre privilège sans rentrer dans une micro-gestion des droits.
Nos convictions sur la CI/CD AWS
Les solutions CI/CD présentes dans le Cloud AWS sont intéressantes et nativement intégrées avec les autres services AWS. L’intégration native est particulièrement appréciable notamment dans le cas d’un pipeline entièrement hébergé par AWS. L’appartenance de l’ensemble des outils au même environnement Cloud permet une grande flexibilité, une supervision ainsi que la gestion des droits et identités de manière centralisée. Cependant, le nombre d’options de configurations engendre aussi de la complexité rendant sa maintenance potentiellement fastidieuse au sein d’infrastructures conséquentes.
AWS est un bon choix lorsqu’une entreprise a déjà migré la majeure partie de ses infrastructures chez AWS. Il est possible de tirer avantage des interconnexions entre services et notamment des puissantes solutions de gestion des accès et de monitoring avec peu de configuration additionnelle. En revanche, dans le cadre d’une utilisation simple et isolée, on ne privilégiera pas AWS CodeCommit ou AWS CodeBuild. Des solutions telles que GitHub / GitLab proposent des solutions plus complètes, une meilleure intégration avec d’autres éditeurs et une interface utilisateur plus accessible. Idem côté sécurité, AWS n’offre pas nativement les services de sécurité CI/CD pour attester du code déployé (SAST, DAST…). AWS ne propose pas d’intégration native mais des services tiers peuvent toujours être intégrées relativement simplement.
* « Exemple d’intégration BitBucket dans AWS CodeBuild » – Source