Sécuriser les providers et state Terraform
- Accueil
- Cloud, plateformes & exploitation
- Sécuriser les providers et state Terraform
Sécuriser les providers et state Terraform
Section intitulée « Sécuriser les providers et state Terraform »L’Infrastructure as Code (IaC) transforme des fichiers versionnés en appels capables de créer, modifier ou détruire une infrastructure. Terraform, Pulumi et leurs providers ne sont donc pas de simples outils d’automatisation : ils exécutent des décisions d’administration avec les droits de l’identité du pipeline.
Un système d’orchestration ressemble à un service chargé d’exécuter les travaux d’un chantier à partir de plans. Il fait gagner du temps et évite les oublis, mais une personne qui modifie les plans ou prend le contrôle du chef de chantier peut aussi faire construire une porte cachée dans chaque bâtiment.
→ Lire l’explication complète de la marmotte
Providers Terraform : du code tiers avec des droits d’administration
Section intitulée « Providers Terraform : du code tiers avec des droits d’administration »Un provider Terraform est un programme chargé de traduire une ressource déclarée en appels vers une interface de programmation applicative, ou API (Application Programming Interface), d’un fournisseur cloud, d’un équipement réseau ou d’un logiciel SaaS (Software as a Service). Lors d’un terraform apply, le binaire du provider s’exécute localement ou dans le runner du pipeline. Il reçoit indirectement les identifiants, les variables et le contexte réseau nécessaires à l’opération.
Le point à retenir est brutal : un provider compromis possède, en pratique, les droits de l’identité qui lance Terraform. Il peut appeler des services cloud hors du périmètre déclaré, lire des variables d’environnement, exfiltrer des jetons d’accès, modifier le state ou introduire des ressources non prévues. La syntaxe HCL (HashiCorp Configuration Language) n’encadre pas le comportement du binaire. Elle lui demande seulement de travailler. Nuance assez pénible quand le binaire décide de travailler pour quelqu’un d’autre.
Un provider tiers doit donc être traité comme une dépendance exécutable à privilèges, au même niveau qu’une action CI/CD (Continuous Integration/Continuous Delivery) non maîtrisée ou qu’un plugin d’agent d’administration. Le registre officiel réduit le risque de typosquatting, pas celui d’un défaut, d’une compromission de mainteneur ou d’une mise à jour hostile. Une signature de paquet atteste surtout l’origine annoncée du paquet, pas l’innocence éternelle de son contenu.
Avant adoption, l’audit doit couvrir au minimum :
- la gouvernance du dépôt, l’identité des mainteneurs, la fréquence des publications et le processus de revue ;
- le code source publié et la reproductibilité, ou au moins la cohérence, des binaires distribués ;
- les permissions réellement requises par les ressources utilisées ;
- les appels réseau effectués par le provider et ses dépendances ;
- les correctifs de vulnérabilités, les avis de sécurité et la capacité à revenir à une version antérieure ;
- le verrouillage de version dans
.terraform.lock.hcl, commité et contrôlé en revue.
Un provider sans code source auditable, sans version figée et sans mainteneur identifiable ne doit pas entrer dans un pipeline de production. Le compromis central est là : l’IaC gagne en vitesse, en homogénéité et en traçabilité déclarative ; il paie cette vitesse en concentrant des privilèges massifs dans un exécutable et dans son pipeline. La recommandation est de refuser les providers communautaires pour les plans de contrôle de production, sauf audit explicite et identité d’exécution strictement limitée. Le catalogue infini de plugins est une fête foraine, pas un modèle de sécurité.
Les permissions doivent aussi être séparées par environnement. Une identité de recette ne doit pas pouvoir atteindre les abonnements, comptes ou projets de production. Une identité de production ne doit pas disposer de droits d’administration globaux si le code ne gère que le réseau d’un périmètre donné. L’IAM (Identity and Access Management) reste le garde-fou primaire : la segmentation des identités cloud vaut davantage qu’un rapport de scan oublié dans un ticket.
State Terraform : secret, inventaire et cible de premier rang
Section intitulée « State Terraform : secret, inventaire et cible de premier rang »Le state Terraform associe les déclarations du code aux identifiants réels des ressources. Il mémorise les attributs observés afin de calculer les écarts et les changements à appliquer. Cette fonction exige souvent de conserver des données qui ne doivent pas circuler librement : mots de passe générés, clés privées, jetons, chaînes de connexion, adresses internes, identifiants de ressources et topologie complète.
Marquer une variable sensitive masque généralement son affichage dans la sortie de commande. Cela ne garantit pas son absence du state. Une valeur secrète peut y rester en clair selon la ressource et le provider. Ce marquage protège les yeux sur la console, pas le contenu du stockage. C’est un rideau devant une baie vitrée.
Un state volé offre deux avantages à un attaquant. D’abord, il peut contenir un secret directement exploitable. Ensuite, même expurgé de secrets, il cartographie les réseaux, les comptes de service, les règles de sécurité, les noms de ressources et les dépendances. Cette cartographie réduit fortement le coût d’une attaque ultérieure. Un bucket de state en lecture large revient à publier l’inventaire de la forteresse et quelques doubles de clés dans le même dossier.
Le backend distant doit respecter quatre propriétés :
- Chiffrement au repos : utiliser une clé gérée par un service de gestion de clés, ou KMS (Key Management Service), avec une clé dédiée au state lorsque la plateforme le permet. Le chiffrement fourni par défaut par un stockage objet est insuffisant si les opérateurs du service ou trop d’identités peuvent déchiffrer sans séparation.
- Contrôle d’accès minimal : autoriser la lecture et l’écriture au seul rôle du pipeline concerné, séparer les droits de lecture pour l’audit, interdire l’accès public et éviter les droits d’administration généraux sur le dépôt de state.
- Verrouillage : empêcher deux exécutions concurrentes de modifier le même state. Sans verrouillage, deux plans calculés sur un état identique peuvent appliquer des changements incompatibles et laisser l’infrastructure dans une réalité que le code ne décrit plus.
- Historique récupérable : activer le versioning du stockage et protéger la suppression. Le versioning ne remplace pas une sauvegarde indépendante, mais il limite les dégâts d’un
applyerroné, d’un state tronqué ou d’une suppression accidentelle.
Le verrouillage ne protège pas contre un acteur disposant d’un droit d’écriture malveillant. Il protège contre la concurrence normale et les erreurs d’exploitation. Ce n’est pas une frontière de sécurité, c’est un mécanisme de cohérence. Confondre les deux produit des architectures où un verrou est présenté comme un coffre-fort, ce qui est une ambition un peu haute pour un fichier de verrouillage.
La sauvegarde doit inclure le state et les clés nécessaires à son déchiffrement. Une sauvegarde chiffrée dont la KEK (Key Encryption Key), clé qui chiffre une autre clé, a disparu n’est pas une stratégie de reprise : c’est une capsule temporelle pour archéologues. La rotation de la clé du backend exige de vérifier la capacité de relire les versions historiques, de restaurer dans un environnement isolé et de documenter les autorisations nécessaires.
Backend chiffré et plan revu : exemple Terraform reproductible
Section intitulée « Backend chiffré et plan revu : exemple Terraform reproductible »L’exemple suivant configure un backend Amazon S3 (Simple Storage Service) chiffré par une clé de chiffrement gérée, active le verrouillage natif du backend et produit un plan immuable avant application. Le bucket, la clé et les politiques d’accès doivent exister avant terraform init. L’identité d’exécution doit disposer uniquement des actions requises sur ce préfixe de state et sur cette clé.
terraform { backend "s3" { bucket = "tt-iac-state-production" key = "reseau/production/terraform.tfstate" region = "eu-west-3"
# Chiffrement côté stockage avec une clé dédiée au state. encrypt = true kms_key_id = "arn:aws:kms:eu-west-3:123456789012:key/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
# Terraform crée un fichier de verrouillage pendant les écritures. use_lockfile = true }}# Télécharge les versions verrouillées dans .terraform.lock.hcl.terraform init -lockfile=readonly
# Produit un artefact de changement, à conserver avec la revue.terraform plan -out=production.tfplan
# Affiche le plan stocké, sans recalculer contre un état devenu différent.terraform show production.tfplan
# N'appliquer qu'après revue humaine du plan exact.terraform apply production.tfplanLe fichier production.tfplan est aussi sensible : il peut contenir des valeurs secrètes et décrit des modifications ciblées. Il ne doit ni être joint à un commentaire public, ni vivre indéfiniment dans les artefacts du pipeline. Sa durée de conservation doit être courte, son accès restreint, et son hash doit être associé à la validation. Un plan recalculé après approbation n’est plus le plan approuvé.
Pour les équipes utilisant Pulumi, la mécanique diffère mais la règle reste identique : les plugins exécutent du code avec les privilèges du runner, et le backend de state contient des données d’infrastructure sensibles. Changer de langage ne change pas la frontière de confiance. Le TypeScript ne distribue pas soudainement des permis de sécurité.
Revue du plan et chaîne d’exécution CI/CD
Section intitulée « Revue du plan et chaîne d’exécution CI/CD »L’automatisation sans revue est acceptable pour des changements strictement bornés, produits par un générateur contrôlé et exécutés avec des permissions étroites. Elle ne l’est pas pour un changement de production qui peut modifier les identités, les routes, les règles réseau, les journaux ou les clés. Le apply automatique sur chaque fusion est une décision de gouvernance, pas une propriété magique de l’IaC.
La revue doit examiner le plan, pas seulement le diff Git. Un changement de code anodin peut produire une destruction et une recréation à cause d’une modification de provider, d’un attribut immuable ou d’une dérive de l’état distant. À l’inverse, un plan vide peut signaler que le code ne couvre pas la ressource attendue. Le code exprime une intention ; le plan expose l’effet réel contre l’infrastructure connue.
Le pipeline doit séparer au moins quatre rôles :
- l’identité qui valide le code ;
- l’identité qui produit le plan ;
- l’identité qui applique en production ;
- l’identité humaine ou de service qui autorise l’application.
Cette séparation réduit l’impact d’un jeton compromis et améliore l’attribution. L’accès fédéré avec des jetons courts est préférable à une clé d’accès cloud statique injectée dans les variables CI/CD. La durée de vie doit couvrir l’exécution, pas la semaine entière par confort. Les secrets du pipeline relèvent des mêmes exigences que les autres identités : gestion des identités et journalisation des actions d’administration.
Les journaux doivent conserver l’identité ayant exécuté le plan et l’application, les versions de Terraform et des providers, le hash du commit, le hash du plan et les appels cloud associés. Sans cette chaîne, une ressource créée hors attente devient un débat métaphysique entre le dépôt, le state et la console. Le cloud, lui, ne participe pas au débat.
Limites de l’IaC et contrôles complémentaires
Section intitulée « Limites de l’IaC et contrôles complémentaires »L’IaC ne garantit pas que la configuration déclarée est sûre. Il garantit seulement qu’un outil tente de converger vers cette configuration avec les droits fournis. Une règle de pare-feu ouverte au monde, correctement déclarée et correctement appliquée, reste une règle de pare-feu ouverte au monde. L’automatisation rend l’erreur reproductible, ce qui est une qualité opérationnelle assez peu consolante.
Les contrôles complémentaires doivent couvrir :
- l’analyse statique des configurations avant plan, avec des règles portant sur les expositions réseau, le chiffrement, les journaux et les identités ;
- les politiques d’admission ou de gouvernance côté cloud, capables de refuser une ressource interdite même si Terraform demande sa création ;
- la détection de dérive entre le state et l’infrastructure réelle ;
- la journalisation centralisée des appels d’API, corrélée aux exécutions du pipeline ;
- les alertes sur lecture inhabituelle du backend, désactivation du chiffrement, suppression de version ou modification des politiques de clé.
La détection de dérive ne remplace pas le contrôle préventif. Elle constate après coup qu’une configuration a changé. Pour les ressources critiques, une politique cloud doit empêcher l’état interdit, puis l’IaC doit le déclarer, puis la supervision doit signaler toute exception. Trois couches peuvent sembler redondantes jusqu’au jour où l’une tombe en panne avec une régularité de métronome.
🐝 Ce qui arrive si on s’en passe
Section intitulée « 🐝 Ce qui arrive si on s’en passe »Sans lock file commité ni lecture seule à l’initialisation, terraform init résout la version la plus récente autorisée par la contrainte : une publication hostile d’un provider entre alors dans le runner sans aucun diff Git, donc sans passer par la revue de code. Sans restriction d’écriture sur le backend, une identité capable de modifier le state peut retirer l’entrée d’une ressource ajoutée hors pipeline. Terraform ignore alors cette ressource : elle n’apparaît plus dans le plan, n’est pas détruite au prochain apply et échappe à la détection de dérive, qui compare le state à l’infrastructure réelle et non l’inventaire complet du compte. À l’inverse, une entrée falsifiée peut pousser le prochain plan à supprimer ou recréer une ressource légitime, avec un changement qui semble provenir du pipeline lui-même.
🦫 Explication de la marmotte 🍫
Section intitulée « 🦫 Explication de la marmotte 🍫 »Les outils d’infrastructure permettent de décrire dans des fichiers ce qui doit exister dans un service cloud : réseaux, machines, comptes, droits ou bases de données. Lorsqu’une commande est lancée, l’outil compare les fichiers avec ce qui existe déjà, prépare une liste de changements, puis demande au fournisseur cloud de les réaliser.
Pour communiquer avec le fournisseur, l’outil utilise des programmes additionnels. Ces programmes ont accès aux autorisations de la personne ou du robot qui lance le travail. Si l’un de ces programmes est malveillant ou compromis, il peut lire des secrets, modifier des ressources ou envoyer des informations ailleurs. Il faut donc vérifier son origine, figer sa version et limiter les droits donnés au robot d’exécution.
L’outil conserve aussi un fichier d’état. Ce fichier indique ce qui a été créé et contient parfois des mots de passe, des clés et la liste détaillée des ressources. Il doit être chiffré, accessible à très peu d’identités et protégé contre deux écritures en même temps. Sinon, deux opérations concurrentes peuvent produire un résultat incohérent.
Avant toute modification en production, une liste précise des changements doit être générée puis relue. Si cette liste montre une suppression inattendue, un accès trop large ou une modification de droits, l’application doit être bloquée. L’automatisation exécute vite ; elle ne juge pas si la décision est mauvaise.
À lire aussi
- Quotas cloud contre le déni de service par coûtGérer les quotas et limites de ressources cloud pour réduire le risque de déni de service par abus de facturation.
- Comment gouverner les coûts cloud contre un compte compromisLa gouvernance des coûts cloud limite l'impact financier d'un compte compromis en complétant la détection, les identités et la réponse à incident.
- Comment auditer la responsabilité partagée cloudLe modèle de responsabilité partagée du cloud répartit les contrôles entre fournisseur et client, mais ses zones grises concentrent les expositions de données et les erreurs d’accès.
- Sécuriser les systèmes de recommandation contre l’empoisonnementLes systèmes de recommandation et de personnalisation exposent une surface d’attaque où la manipulation de profils et l’empoisonnement des signaux comportementaux modifient directement les décisions automatisées.
Pages voisines
La citent
Sécuriser les providers et state Terraform
Elle cite
: les deux pages se citent l’une l’autre.
