Aller au contenu principal

Analyse IaC

L’analyse IaC est une vérification à part entière, fremforge/iac-scan, avec ses propres paramètres et son propre onglet de résultats. Sur chaque pull request, et à chaque push vers la branche par défaut ou une branche de version protégée, fremforge exécute trivy config sur le dépôt avec tous les contrôles de mauvaise configuration intégrés de Trivy :

  • Dockerfiles et Containerfiles
  • Fichiers Docker Compose
  • Manifestes Kubernetes
  • Charts Helm
  • Terraform et OpenTofu, fichiers .tf comme .tofu, avec vérification de leurs modules distants : les modules de votre organisation sur frem.sh et des miroirs de fremforge, ainsi que les modules de registre et les sources github.com ou gitlab.com à une étiquette ou à un commit, via le cache de modules. Toute autre source distante n’est pas récupérée, et elle est listée comme telle
  • Modèles AWS CloudFormation, YAML et JSON
  • Modèles Azure Resource Manager (ARM), JSON
  • Fichiers Bicep, compilés d’abord en ARM ; voir Bicep
  • Playbooks et tâches Ansible, pour les ressources cloud que créent leurs modules (par exemple amazon.aws.s3_bucket) ; tous les modules ne sont pas couverts

Chacun de ces formats a été éprouvé le 19 octobre 2026 avec une pull request qui ajoute une mauvaise configuration connue (elle a fait échouer la vérification) et une autre avec la version sécurisée (elle l’a passée).

Jusqu’au 17 octobre 2026, ces contrôles s’exécutaient dans l’analyse des images et leurs résultats étaient des résultats d’images. La vérification des images, fremforge/image-scan, ne les porte plus.

La vérification de pull request

fremforge/iac-scan échoue lorsque la pull request ajoute une mauvaise configuration à votre seuil ou au-dessus. Une mauvaise configuration que la branche cible possède déjà ne la bloque pas : la vérification compare avec la dernière analyse de cette branche, la branche par défaut ou une branche de version protégée. Un résultat est le même résultat lorsqu’il s’agit du même contrôle dans le même fichier ; une deuxième occurrence d’un contrôle dans un fichier est nouvelle.

Lorsqu’il n’existe encore aucune analyse de cette branche, chaque résultat au seuil ou au-dessus bloque, et une analyse de la branche est demandée, de sorte que l’exécution suivante de la vérification est comparée.

Le statut indique ce qu’il a trouvé, par exemple 1 new high/critical misconfiguration(s); merge blocked; 2 already on main, et renvoie vers Sécurité › Résultats › IaC.

Quand c’est une vérification requise

fremforge/iac-scan publie son statut sur chaque pull request. Le fait qu’un échec bloque la fusion dépend de son statut de vérification requise de protection de branche dans votre organisation :

  • Les organisations créées le 19 octobre 2026 ou après l’ont comme vérification requise dès leur premier dépôt.
  • Les organisations plus anciennes la reçoivent organisation par organisation, pour qu’aucune pull request ouverte avant l’existence de la vérification ne l’attende. D’ici là, elle affiche le résultat sans bloquer la fusion à elle seule.
  • Le mode Désactivé la retire des vérifications requises ; Audit la garde requise mais ne la fait jamais échouer.

Sécurité › Politiques › Analyseurs › IaC indique ce qui s’applique à votre organisation : Une vérification requise dans cette organisation, ou Pas encore une vérification requise dans cette organisation. Vous pouvez l’ajouter vous-même à vos vérifications requises à tout moment ; voir Protection de branche.

Paramètres

Sous Sécurité › Politiques › Analyseurs › IaC :

ParamètreValeursPar défaut
ModeAppliquer (bloquer la fusion), Audit (signaler, ne jamais bloquer), Désactivé (ne pas analyser)Appliquer
La vérification échoue à partir detoute sévérité, moyenne ou plus, haute ou critique, critique uniquementhaute ou critique

Ces mêmes paramètres constituent l’entrée iac_scan de la politique d’analyse de l’organisation ; vous pouvez donc les définir via l’API et par dépôt :

PUT /_app/api/v1/orgs/{org}/policy
{ "scan_policy": { "iac_scan": { "mode": "enforce", "block_severity": "critical" } } }

Une valeur par dépôt l’emporte sur celle de l’organisation :

PUT /_app/api/v1/orgs/{org}/repos/{repo}/policy
{ "scan_policy": { "iac_scan": { "mode": "audit" } } }

Avec Terraform ou OpenTofu, utilisez fremforge_scan_policy avec scanner = "iac_scan" (provider 0.4.0 et versions ultérieures) :

resource "fremforge_scan_policy" "iac" {
  org            = "acme"
  scanner        = "iac_scan"
  mode           = "enforce"
  block_severity = "high"
}

Modules Terraform distants

La vérification lit les modules qu’appelle votre configuration, si bien qu’une mauvaise configuration à l’intérieur d’un module est aussi détectée :

  • Via le cache de modules. Un module de registre (terraform-aws-modules/vpc/aws, avec ou sans version) et une source github.com ou gitlab.com à une étiquette ou à un commit sont lus via le cache de modules du proxy de dépendances : la version la plus récente qui satisfait votre contrainte version, épinglée lors de sa première récupération. Seuls les fichiers .tf et .tf.json du module, et les modules locaux qu’ils appellent, sont vérifiés ; ses exemples et ses tests ne le sont pas. Votre dépôt n’est jamais modifié : l’analyseur travaille sur une copie privée.

  • Depuis frem.sh. Les modules de votre propre organisation, et ceux des miroirs de dépôts publics de fremforge, sont lus depuis frem.sh.

  • Depuis votre propre hôte git, avec votre identifiant. Un module sur un autre hôte git en https (git::https://git.example.com/infra/modules.git?ref=v1.2.0, ou https://git.example.com/infra/modules.git) est lu lorsque votre organisation détient un identifiant kind: git en lecture seule pour exactement cet hôte. Un propriétaire l’enregistre sous Sécurité › Accès › Identifiants de registre en choisissant Hôte de modules git, ou via l’API des identifiants de registre ; la fonctionnalité est désactivée tant qu’un propriétaire ne l’active pas. L’analyse récupère le module via le proxy de dépendances, qui ajoute votre identifiant :

    • lecture seule : un git fetch, jamais un push ;
    • votre identifiant est envoyé à cet hôte et nulle part ailleurs, et toute redirection est refusée ;
    • rien n’est mis en cache, si bien que supprimer l’identifiant ne laisse aucune copie derrière.

    Un hôte pour lequel vous ne détenez aucun identifiant n’est pas récupéré, comme auparavant.

  • Rien d’autre n’est récupéré. Un autre hôte sans identifiant, une source github.com ou gitlab.com sans étiquette (une branche), une URL d’archive ou une source SSH ne sont jamais récupérés par l’analyseur. Ils sont listés sous Non vérifié dans Sécurité › Résultats › IaC, avec leur source, et le statut de la vérification indique combien de modules n’ont pas été récupérés ; les ressources qu’ils définissent ne sont pas vérifiées.

Les résultats à l’intérieur d’un module sont listés à part, sous Dans les modules, regroupés par module avec la version lue par l’analyse et l’endroit d’où il est appelé. Ils ne bloquent jamais une pull request, n’ont pas de date limite de correction et n’envoient aucune alerte, car la correction se trouve dans votre appel (une entrée, ou une version du module qui corrige le problème), pas dans vos fichiers. Un rejet est conservé d’une version du module à l’autre : il est indexé sur le module, le fichier qu’il contient et le contrôle, pas sur la version.

Bicep

Trivy ne dispose d’aucun contrôle Bicep, mais il contrôle ARM. fremforge compile donc chaque fichier .bicep du dépôt en ARM avec la CLI Bicep et vérifie le résultat avec les mêmes contrôles, le même seuil et les mêmes rejets que le reste du dépôt. Un résultat est affiché sur le fichier .bicep, à la ligne de la propriété signalée lorsqu’elle peut être retrouvée, sinon sur la déclaration de la ressource, et il indique que la ligne a été déduite de l’ARM compilé.

  • Hors ligne. Bicep s’exécute sans accès réseau et sans restaurer les modules. Un module provenant d’un registre (br:) ou d’une spécification de modèle (ts:) ne peut pas être récupéré ; un fichier qui en utilise un n’est donc pas compilé et il est listé comme tel. Les modules locaux (module x './y.bicep') fonctionnent.
  • Chaque fichier séparément. Chaque fichier .bicep, modules compris, est compilé et vérifié isolément ; une ressource d’un module est donc vérifiée dans le fichier du module.
  • Votre bicepconfig.json n’est pas lu. Les alias de modules, extensions, fonctionnalités expérimentales et paramètres de l’analyseur qu’il contient n’ont aucun effet sur l’analyse. Un fichier qui a besoin d’une fonctionnalité expérimentale pour compiler est listé comme non compilé.
  • Jamais de réussite silencieuse. Un fichier qui n’a pas pu être compilé (une erreur, un module de registre, plus de 60 secondes, ou le dépassement de la limite de 200 fichiers ou de 2 Mio par dépôt) ne bloque pas la fusion, car ce n’est pas une mauvaise configuration, mais le statut de la vérification indique combien de fichiers n’ont pas été vérifiés, et Sécurité › Résultats › IaC les liste sous Non vérifié avec la raison.

Vos propres contrôles

Une organisation peut ajouter ses propres contrôles, écrits en Rego sous forme de contrôles personnalisés Trivy. fremforge/iac-scan les exécute avec les contrôles intégrés sur chaque dépôt de l’organisation, avec le même mode et le même seuil, et seul ce qu’une pull request ajoute la bloque.

Ajoutez-les sous Sécurité › Politiques › Contrôles IaC, ou via l’API (ci-dessous). Un contrôle doit :

  • se trouver dans un paquet sous custom., par exemple package custom.acme.no_root ;
  • porter un bloc # METADATA avec un title, un custom.id (ses résultats sont affichés sous la forme custom/<id>) et une custom.severity (LOW, MEDIUM, HIGH ou CRITICAL) ; custom.input.selector désigne les types de fichiers qu’il lit, comme dans Trivy ;
  • ne lire que le fichier analysé (input) : pas de import data ni aucune référence à data ;
  • n’utiliser aucune fonction intégrée réseau ou d’exécution : http.send, net.lookup_ip_addr, opa.runtime, rego.parse_module, trace, numbers.range et numbers.range_step sont refusées.

Au plus 25 contrôles par organisation, de 32 Kio chacun. La console propose un exemple complet comme point de départ.

Un contrôle enregistré est En vérification jusqu’à ce que l’analyseur l’ait validé avec OPA, dans le même environnement cloisonné que celui qui exécute les analyses de vos pull requests, puis Actif ou Rejeté, avec la raison. Seul un contrôle actif qui n’est pas désactivé s’exécute. Modifier la source d’un contrôle le fait vérifier de nouveau ; d’ici là, le verdict précédent ne s’applique plus et le contrôle ne s’exécute pas. Vous pouvez désactiver un contrôle sans le supprimer.

Les résultats de vos contrôles apparaissent avec ceux des contrôles intégrés, dans la vérification de pull request et sous Sécurité › Résultats › IaC, marqués Personnalisé avec le nom du contrôle.

API

GET    /_app/api/v1/orgs/{org}/code-security/iac/policies
POST   /_app/api/v1/orgs/{org}/code-security/iac/policies          { "name": "No root", "source": "<rego>", "enabled": true }
PUT    /_app/api/v1/orgs/{org}/code-security/iac/policies/{id}
DELETE /_app/api/v1/orgs/{org}/code-security/iac/policies/{id}

Avec Terraform ou OpenTofu, chaque contrôle est une ressource fremforge_iac_custom_check (provider 0.4.0 et versions ultérieures) : name, source et enabled, avec status, status_reason, check_id, title et severity relus depuis le verdict de l’analyseur.

resource "fremforge_iac_custom_check" "no_root" {
  org    = "acme"
  name   = "No root"
  source = file("checks/no_root.rego")
}

Le listage nécessite findings:read ou policy:read ; les modifications nécessitent policy:write. Un contrôle nouveau ou modifié revient avec le status pending ; le verdict de l’analyseur le passe à valid ou invalid, avec status_reason. Un contrôle que l’API peut refuser avant que l’analyseur ne le voie (trop volumineux, pas de paquet custom., pas de METADATA) reçoit la réponse 400 avec la raison ; le 26e contrôle reçoit 409. Chaque modification figure dans le journal d’audit.

Résultats

Sécurité › Résultats › IaC liste les mauvaises configurations ouvertes : le contrôle (par exemple KSV-0014), son titre, le dépôt et le fichier, avec la sévérité et la date limite de correction. Filtrez par sévérité, ouvrez le fichier au commit analysé, et rejetez un ou plusieurs résultats avec une raison, comme dans les autres onglets de résultats. Un rejet est conservé pour le même contrôle dans le même fichier d’une analyse à l’autre.

Pour quelques contrôles où une propriété n’a qu’une seule valeur sûre, comme le blocage de l’accès public S3 et les paramètres HTTPS uniquement et TLS minimal du stockage Azure, Ouvrir une demande de correctif dans la colonne Correctif ouvre une pull request qui la définit, sans IA. Voir Correctifs fondés sur des règles.

Ils apparaissent aussi dans Sécurité › Résultats › Tous avec le type IaC, sur la vue d’ensemble Sécurité sous forme de ligne propre, dans le rapport de conformité et via l’API des résultats (type=iac).

Référentiels et NIS2

Le rapport de conformité regroupe les résultats IaC ouverts par les contrôles de référentiel que testent leurs vérifications (CIS Docker, CIS Kubernetes, RKE2 et EKS, le guide de durcissement Kubernetes de la NSA, les Pod Security Standards, CIS AWS), à partir des correspondances de conformité que publie Trivy, et par domaine de l’article 21(2) de NIS2. Le regroupement NIS2 est propre à fremforge ; ce n’est pas une correspondance officielle et il n’atteste la conformité à aucune mesure.

Pour ignorer un contrôle dans un dépôt, utilisez un fichier d’exclusion Trivy ; voir Fichiers d’exclusion Trivy.

Non couvert

Ces contrôles détectent des mauvaises configurations. Ils ne confrontent pas les versions aux avis de vulnérabilité :

  • Les modules Terraform ne sont pas vérifiés pour des versions vulnérables. Les providers Terraform et OpenTofu le sont, par l’analyse des dépendances ; voir Providers Terraform et OpenTofu.
  • Les charts Helm ne sont pas vérifiés pour des versions de chart vulnérables. Les images de conteneurs qu’un chart déploie le sont, par l’analyse des images ; voir Images déployées par vos charts Helm.
  • Pulumi et l’AWS CDK ne sont pas analysés : leurs ressources n’existent que lorsque votre programme s’exécute, et fremforge n’exécute pas votre code.
  • La couverture au sein d’un format est celle de Trivy. Par exemple, les règles des groupes de sécurité réseau dans les modèles ARM (et donc dans Bicep) ne sont pas évaluées, et une tâche Ansible n’est vérifiée que lorsque Trivy connaît son module : lors de notre essai, une tâche amazon.aws.s3_bucket a été vérifiée et une tâche amazon.aws.ec2_security_group ne l’a pas été.
  • Les versions des actions CI sont vérifiées, par l’analyse des dépendances plutôt que par cette vérification : une action présentant une vulnérabilité connue est un résultat de dépendance ; voir Versions des actions CI. Leur épinglage à un commit est vérifié séparément ; voir Épinglage des workflows.

Voir Écosystèmes pris en charge.