Pourquoi vos règles d'infrastructure doivent être écrites sous forme de code

Votre équipe a une politique : aucun groupe de sécurité ne doit jamais ouvrir le port SSH (22) à l'ensemble d'Internet. Tout le monde est d'accord. C'est dans la documentation. Quelqu'un a même imprimé la règle et l'a affichée au mur.

Puis, un vendredi après-midi, un développeur crée un nouveau groupe de sécurité pour un test rapide. Il définit le bloc CIDR sur 0.0.0.0/0 sur le port 22, juste pour tester quelque chose rapidement. La modification passe. Personne ne s'en aperçoit jusqu'au lundi matin, quand l'équipe de sécurité envoie une alerte concernant un port SSH exposé.

Ce scénario se répète chaque semaine dans de nombreuses équipes. Non pas parce que les gens sont négligents, mais parce que l'application manuelle des politiques ne passe pas à l'échelle. Lorsque les changements d'infrastructure se produisent plusieurs fois par jour, se fier à la mémoire humaine ou à des règles basées sur des documents est une recette pour les failles.

Le problème des politiques basées sur des documents

La plupart des équipes commencent avec des politiques stockées dans des documents. Un Google Doc, une page Confluence ou un PDF qui vit sur un disque partagé. Ces documents décrivent ce qui devrait et ne devrait pas arriver : « Tous les buckets S3 doivent être chiffrés », « Seules les AMI approuvées peuvent être utilisées », « Chaque ressource doit avoir un tag de centre de coût ».

Le problème, c'est que les documents n'appliquent rien. Ils décrivent l'intention, mais ils n'exécutent pas. Lorsque quelqu'un fait un changement qui viole une politique, le document ne l'arrête pas. Il reste là, attendant silencieusement que quelqu'un se souvienne de le vérifier.

Les documents dérivent aussi. Quelqu'un met à jour la politique, mais l'ancienne version reste dans les favoris de quelqu'un d'autre. Ou l'équipe grandit, et les nouveaux membres ne savent pas que le document existe. Avec le temps, l'écart entre ce qui est documenté et ce qui est réellement déployé se creuse.

Ce que signifie écrire une politique sous forme de code

Le Policy as Code consiste à prendre ces règles et à les écrire dans un format que les machines peuvent lire et exécuter. Au lieu d'un document qui dit « n'ouvrez pas SSH au monde entier », vous écrivez une règle qui vérifie automatiquement chaque changement d'infrastructure par rapport à cette contrainte.

La politique vit dans un fichier, tout comme votre code applicatif. Elle passe par le contrôle de version. Elle est relue dans les pull requests. Elle peut être testée, mise à jour et annulée. Lorsque quelqu'un propose un changement qui viole la politique, le pipeline l'intercepte avant que la ressource ne soit créée.

Ce passage du document au code change la façon dont les équipes interagissent avec les règles. Les politiques deviennent partie intégrante du flux de travail d'ingénierie, et non une réflexion après coup que quelqu'un vérifie lors d'un audit.

Un exemple concret avec Open Policy Agent

Rendons cela concret. Open Policy Agent (OPA) est un outil populaire pour écrire des politiques sous forme de code. Il utilise un langage appelé Rego. Voici à quoi ressemble une politique simple qui bloque l'accès SSH depuis n'importe où :

deny if {
    input.resource.type == "aws_security_group_rule"
    "0.0.0.0/0" in input.resource.cidr_blocks
    input.resource.port == 22
}

Cette règle dit : si quelqu'un essaie de créer une règle de groupe de sécurité qui ouvre le port 22 à toutes les adresses IP, marquez-la comme refusée. Le fichier de politique se trouve dans votre dépôt. Lorsqu'une pull request est soumise pour ajouter une règle de groupe de sécurité, le pipeline CI exécute OPA sur les modifications proposées. Si la règle correspond, le pipeline échoue et le développeur reçoit un retour immédiat.

Vous pouvez également écrire l'inverse : une règle qui n'autorise que des blocs CIDR spécifiques pour l'accès SSH :

allow if {
    input.resource.type == "aws_security_group_rule"
    input.resource.cidr_blocks[_] != "0.0.0.0/0"
}

La syntaxe exacte dépend de votre outil et de votre langage de politique, mais le modèle est le même : les règles sont du code, et le code s'exécute automatiquement.

Une autre approche : Sentinel pour les utilisateurs de Terraform

Si votre équipe utilise Terraform de manière intensive, Sentinel de HashiCorp offre une intégration plus étroite. Les politiques Sentinel sont écrites spécifiquement pour le contexte d'exécution de Terraform. Voici la même restriction SSH dans Sentinel :

import "tfplan"

allowed_cidrs = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]

main = rule {
    all tfplan.resource_changes as _, change {
        change.type is "aws_security_group_rule" implies
        change.change.after.cidr_blocks all allowed_cidrs
    }
}

Cette politique vérifie que chaque règle de groupe de sécurité n'utilise que des plages IP privées. Si quelqu'un essaie d'utiliser un bloc CIDR public, la politique bloque le changement.

La différence entre OPA et Sentinel concerne principalement l'écosystème. OPA est polyvalent et fonctionne avec de nombreux outils au-delà de Terraform. Sentinel est profondément intégré aux produits HashiCorp, ce qui simplifie la configuration si vous êtes déjà dans cet écosystème. Mais l'idée centrale est identique : les politiques sont du code qui s'exécute dans votre pipeline.

Où stocker vos fichiers de politique

Vous avez deux options principales pour l'emplacement des fichiers de politique :

Dans le même dépôt que votre code d'infrastructure. Cela maintient les politiques proches des ressources qu'elles régissent. Lorsque quelqu'un modifie l'infrastructure, il voit les politiques pertinentes dans la même pull request. Cela fonctionne bien pour les politiques spécifiques à une équipe.

Dans un dépôt de politique dédié. Cela centralise toutes les politiques de l'organisation. Une équipe plateforme maintient le dépôt, et plusieurs dépôts d'infrastructure tirent les politiques de celui-ci. Cela fonctionne mieux pour les règles de conformité à l'échelle de l'organisation qui ne doivent pas varier entre les équipes.

Les deux approches sont valables. Commencez par l'approche du même dépôt si vous débutez avec le Policy as Code. Passez à un dépôt dédié lorsque vous devez appliquer des politiques de manière cohérente entre plusieurs équipes.

Liste de contrôle pratique pour commencer

Avant de vous lancer dans la rédaction de politiques, parcourez cette liste de contrôle rapide :

  • Identifiez vos trois politiques les plus violées. N'essayez pas de tout codifier à la fois. Choisissez les règles qui causent le plus de douleur ou de risque.
  • Choisissez un outil. Commencez avec OPA si vous voulez de la flexibilité entre les outils. Commencez avec Sentinel si vous êtes fortement investi dans Terraform.
  • Écrivez une politique et testez-la manuellement. Exécutez-la contre une violation connue pour confirmer qu'elle détecte le problème.
  • Ajoutez la vérification de politique à votre pipeline CI. Faites en sorte qu'elle bloque la build, pas seulement qu'elle avertisse. Les avertissements sont ignorés.
  • Révisez et itérez. Après une semaine, vérifiez si la politique a détecté quelque chose d'inattendu. Ajustez les faux positifs.

La vraie valeur réside dans le workflow

L'outil que vous choisissez importe moins que le workflow que vous adoptez. Lorsque les politiques sont du code, elles bénéficient du même traitement que le code applicatif. Elles sont relues, testées, versionnées et améliorées au fil du temps. Lorsqu'une politique provoque un faux positif, quelqu'un ouvre une pull request pour la corriger. Lorsqu'une nouvelle exigence de conformité arrive, quelqu'un écrit une nouvelle règle et la livre via le même pipeline.

Ce workflow élimine l'écart entre l'intention de la politique et son application réelle. La règle qui dit « pas de SSH vers le monde entier » n'est plus un document que quelqu'un pourrait oublier de vérifier. C'est une ligne de code qui s'exécute à chaque fois que l'infrastructure change. C'est la différence entre espérer que votre équipe suit les règles et savoir qu'elle le fait.