Justification des choix d'outils — grille Foyer¶
Hiérarchie de veto (lexicographique, pas un score) : altérité → réversibilité
→ érosion → coût. Un outil n'est comparé sur le coût que s'il a passé les
trois filtres précédents. Voir ../../skills/arbitrage-hybride.md §5 pour la
grille, et ADR-outillage.md pour la liste consolidée qui en résulte.
Épinglage — pourquoi aucun tag mobile dans ces templates¶
Toutes les actions sont référencées par SHA de commit, avec le tag en
commentaire de lisibilité ; toutes les images par version explicite.
Aucun @main, aucun :latest.
Ce n'est pas du zèle : un tag mobile est un trou de réversibilité. Un
pipeline qui référence @main ne peut pas rejouer un build passé à
l'identique, et la nomenclature qu'il produit ne décrit pas ce qui a
réellement tourné — ce qui vide le gate SBOM de sa fonction. Un dossier dont
la doctrine repose sur la reproductibilité ne peut pas dépendre d'une
référence que quelqu'un d'autre peut redéfinir sans préavis.
Une exception, assumée et unique : dtolnay/rust-toolchain@stable. Chez
cette action, la ref n'est pas un numéro de version mais le sélecteur de
toolchain (stable / beta / nightly) — l'épingler par SHA ne
l'immobiliserait pas, ça lui ferait perdre son sens. L'exception est
commentée à chacune de ses occurrences dans github/workflows/rust.yml.example.
Corollaire d'entretien : des SHA épinglés se périment. Leur mise à jour
relève du cercle de réexamen décrit dans ADR-outillage.md — au même titre
que les quatre signaux d'érosion, et pas plus souvent.
Secrets — Gitleaks (pre-commit) + TruffleHog (CI)¶
- Gitleaks : MIT, binaire Go unique, aucun appel réseau, fonctionne hors-ligne. Sortie SARIF native. Choix par défaut pour le poste de développeur — rapide (< 1s), ne fuite rien vers un tiers pour détecter un pattern.
- TruffleHog : AGPL-3.0. La clause réseau de l'AGPL ne s'applique pas ici
— l'outil scanne, il n'est pas modifié puis republié comme service. Utilisé
uniquement en CI, en mode
--results=verified, pour confirmer qu'un secret détecté est réellement actif (appel à l'API du fournisseur du secret, pas à un tiers extérieur à la relation). - Écarté : GitGuardian. SaaS propriétaire — le code ou ses empreintes transitent par un tiers commercial. Veto altérité. À reconsidérer uniquement si un besoin de dashboard de gouvernance à grande échelle apparaît, et alors comme complément, jamais comme gate bloquant.
SBOM — générateurs CycloneDX par écosystème + Syft¶
Pas d'outil unique multi-langage mature à ce jour ; l'écosystème CycloneDX est volontairement distribué par écosystème (cdxgen existe en alternative multi-langage si un seul outil est préféré, avec analyse de reachability, mais introduit une dépendance à un projet moins établi que les plugins officiels par écosystème).
| Écosystème | Outil | Licence |
|---|---|---|
| Next.js / npm | @cyclonedx/cyclonedx-npm |
Apache-2.0 |
| Java / Maven | cyclonedx-maven-plugin |
Apache-2.0 |
| Python | cyclonedx-bom (cyclonedx-py) |
Apache-2.0 |
| Image Docker | Syft (Anchore) → format CycloneDX | Apache-2.0 |
Tous produisent du CycloneDX 1.6+, réversible par construction : format ouvert, consommable par n'importe quel agrégateur, y compris Dependency-Track (voir annexe « Agrégateur » en fin de document).
Vulnérabilités conteneur — Trivy en gate, Docker Scout en option non bloquante¶
- Trivy (Aqua Security, Apache-2.0) : fonctionne hors-ligne après téléchargement de la base, ne nécessite aucune authentification, couvre image, filesystem, IaC, secrets et licences en un seul binaire. Choisi comme gate bloquant parce qu'il ne dépend d'aucun compte tiers pour fonctionner — altérité et réversibilité au maximum.
- Docker Scout : outil propriétaire de Docker Inc., nécessite une connectivité API et une authentification pour l'usage complet. Base de vulnérabilités différente de Trivy — capte parfois des CVE que Trivy rate (ex. CVE applicatives sur l'interpréteur Python) et inversement. Recommandé en usage complémentaire, jamais en gate unique : dépendance à un compte et une plateforme d'un éditeur unique (risque d'érosion), et échange avec un service tiers à documenter si des images contiennent du code non public.
- Pratique recommandée : faire tourner les deux en CI, Trivy bloquant, Docker Scout en rapport informatif — deux bases de données différentes couvrent plus qu'une seule.
SAST — Opengrep plutôt que Semgrep CE¶
Semgrep a restreint en décembre 2024 la licence de ses règles proposées à la communauté (Semgrep Rules License) tout en gardant le moteur en LGPL — un cas concret d'érosion au sens Foyer. Opengrep, fork gouverné par un consortium de plus de dix éditeurs, restaure les fonctionnalités retirées de la Community Edition, reste compatible avec le format de règles Semgrep et produit du SARIF nativement — aucune réécriture de pipeline nécessaire pour migrer.
Limite honnête à documenter : la couverture Java/Spring d'Opengrep est bonne sur les patterns OWASP standards, mais n'atteint pas la profondeur d'analyse inter-framework des règles Pro propriétaires de Semgrep. Complété ici par SpotBugs (LGPL) pour les défauts structurels Java, sans dépendre d'un éditeur unique.
SBOM — Rust¶
cargo-cyclonedx (projet OWASP CycloneDX, Apache-2.0) source à la fois
Cargo.lock et cargo metadata, ce qui permet de produire un SBOM par
crate ou par binaire et de respecter la combinaison de features activée à
la compilation — un simple parseur de lockfile ne le permet pas. Retenu
plutôt que cargo-sbom (moins établi) ou cargo-auditable (embarque les
dépendances dans le binaire compilé — complémentaire, pas substituable,
utile en particulier pour du code embarqué où le binaire circule sans son
dépôt source).
cargo-audit vs Trivy pour Rust : la couverture de l'écosystème Cargo
par Trivy est plus tardive que celle de RustSec, la base spécifique à
l'écosystème Rust sur laquelle s'appuie cargo-audit. D'où le maintien de
cargo-audit en guidance complémentaire au gate conteneur Trivy, plutôt
qu'un remplacement.
Migrations PostgreSQL — vérification de réversibilité plutôt qu'un outil de migration imposé¶
Aucun outil de migration n'est imposé (node-pg-migrate, sqlx, diesel,
Flyway, Sqitch — au choix de l'équipe), en cohérence avec le principe de
ne jamais imposer d'outil au-delà du contrat de gate. Le gate porte sur une
convention de nommage (*.up.sql / *.down.sql) transposable à la
plupart de ces outils, pas sur un outil particulier.
Ce gate a un statut particulier dans ce dossier : c'est le seul qui ne
protège pas un artefact logiciel (secret, dépendance, image) mais un état
de base de données. Il est néanmoins bloquant parce qu'il satisfait
exactement le même critère que les trois gates de code — objectivable
(le fichier existe ou non) et irréversible (une migration sans retour,
jouée en production, ne se défait pas). Le dry-run réel sur instance
éphémère (sqlfluff, application effective up/down) reste en guidance :
un échec y est coûteux à corriger avant merge, mais rien n'est perdu si on
ne bloque pas dessus — à la différence de l'absence du fichier de retour
lui-même.
SBOM — PHP (Symfony, Drupal)¶
cyclonedx/cyclonedx-php-composer (Apache-2.0), plugin Composer officiel du
projet CycloneDX. Fonctionne identiquement pour Symfony et Drupal puisque
les deux s'appuient sur Composer — seule la couche de guidance diffère
(standard de code, vérification de dépréciation).
composer audit vs Symfony Security Checker : composer audit est natif
depuis Composer 2.4, s'appuie sur FriendsOfPHP/security-advisories, et
retourne un code de sortie non nul en cas de vulnérabilité — l'ancien
Symfony Security Checker (dépendant d'un service tiers désormais retiré) et
local-php-security-checker sont obsolètes. Retenu en guidance et non en
gate, pour la même raison que cargo-audit : une dépendance listée n'est
pas nécessairement atteinte par le code exécuté.
Cas Drupal : le standard de code officiel (drupal/coder, GPL-2.0,
paquet Composer maintenu par la Drupal Association) et drupal-check
(dépréciations d'API core/contrib) sont ajoutés en guidance additionnelle,
actifs uniquement si composer.json référence drupal/core — un projet
Symfony pur ne déclenche pas ces jobs.
PowerShell — un stack sans écosystème SBOM établi, à documenter honnêtement¶
Aucun générateur CycloneDX dédié au PowerShell Gallery n'est aujourd'hui suffisamment mature ou adopté pour être recommandé comme gate — à la différence de npm, Maven, pip, Cargo, Composer ou NuGet. Plutôt que de produire un SBOM de façade (un fichier techniquement présent mais sans valeur informative), ce dossier :
- traite le gate SBOM et le gate conteneur comme conditionnels à la
présence d'un
Dockerfiledans le dépôt — beaucoup de dépôts PowerShell (scripts d'administration, modules exécutés directement sur un hôte) n'en ont pas, et le sujet ne se pose alors pas ; - retient PSScriptAnalyzer (Microsoft, MIT) comme guidance principale
— c'est l'analyseur statique officiel de l'écosystème, et plusieurs de
ses règles (
PSAvoidUsingConvertToSecureStringWithPlainText,PSAvoidUsingPlainTextForPassword,PSAvoidUsingInvokeExpression) couvrent des patterns de sécurité directement pertinents.
Point ouvert, à trancher en atelier si le volume de scripts PowerShell le
justifie : documenter manuellement les modules requis (RequiredModules
d'un fichier .psd1) comme inventaire minimal, à défaut d'outillage
automatisé.
SBOM — C# / .NET¶
dotnet-CycloneDX (outil global .NET, projet CycloneDX, NuGet), officiel
et maintenu par la même organisation OWASP CycloneDX que les générateurs
npm/Maven/Python déjà retenus.
dotnet list package --vulnerable est une commande native du SDK
.NET (depuis 5.0.200), sans installation supplémentaire, appuyée sur la
GitHub Advisory Database. Limite documentée de l'outil : elle ne retourne
pas de code de sortie non nul en cas de vulnérabilité trouvée — elle
liste, elle ne bloque pas par elle-même. Ce dossier la garde donc en
guidance pure (rapport informatif), cohérent avec le traitement des autres
audits de dépendances (cargo-audit, composer audit), plutôt que
d'ajouter une logique de parsing fragile pour forcer un comportement
bloquant que l'outil n'a pas été conçu pour offrir nativement.
Agrégation — DefectDojo + Dependency-Track¶
C'est le seul choix de cette liste qui mérite une analyse de veto complète avant sélection définitive : voir l'annexe dédiée en fin de document — c'est le seul système de référence irréversible parmi tous les outils listés ici.
Provenance IA¶
Aucun outil de pipeline générique ne peut aujourd'hui vérifier automatiquement qu'un système d'IA respecte une dérogation article 6§3 ou n'effectue pas de profilage — c'est un jugement sur la finalité et l'accès aux données, pas un fait détectable dans un diff. La gate correspondante est donc une checklist de mise en service, pas un job CI.
Elle relève donc du registre « exigence de jalon », pas du plancher
mécanique (cf. ../../skills/gates.md). Le point mérite d'être dit
explicitement, parce que l'irréversibilité de la provenance IA est réelle —
une inférence passée ne se journalise pas rétroactivement — et pousse
naturellement à vouloir la faire bloquer. Mais le plancher exige deux
propriétés, pas une : irréversible et objectivable. Celle-ci échoue sur
la seconde. Un gate qui prétendrait la vérifier ne contrôlerait qu'un
substitut (la présence d'un fichier, d'un label), et le substitut passerait
au vert pendant que l'exigence resterait non tenue — ce qui est pire que
l'absence de gate, puisque ça produit une assurance fausse.
Contenu de la checklist :
- version de modèle et endpoint appelé consignés dans la configuration versionnée ;
- juridiction d'hébergement du modèle documentée ;
- accès au journal d'interactions restreint et sa finalité déclarée par écrit ;
- évaluation art. 6§3 documentée si la fonction touche l'annexe III.
À intégrer comme point de contrôle en revue de code / merge request pour
toute PR touchant un chemin **/ai/** ou **/llm/** — un exemple de
configuration de label obligatoire est fourni dans github/workflows/ et
gitlab/.
Annexe — l'agrégateur, pourquoi c'est le seul choix qui mérite un atelier dédié¶
Tous les autres outils de ce document sont substituables sans dommage : leur contrat de sortie (SARIF, CycloneDX) garantit qu'un remplacement ne coûte qu'une ligne de configuration. L'agrégateur ne partage pas cette propriété — c'est structurel, pas un défaut d'implémentation.
Pourquoi l'agrégateur casse la réversibilité par défaut¶
Un agrégateur (DefectDojo, Dependency-Track, ou tout ASPM commercial) accumule trois choses qu'aucun format d'échange standard ne capture entièrement :
- L'historique de triage — chaque finding marqué faux positif, accepté comme risque, ou lié à un ticket porte un raisonnement humain. CycloneDX et SARIF décrivent l'état d'un scan, pas la décision prise dessus.
- La déduplication apprise — un agrégateur mature fusionne les doublons entre scanners différents (le même CVE remonté par Trivy et par un SCA applicatif) selon des règles qui s'affinent avec l'usage. Ce savoir ne s'exporte pas proprement.
- Le graphe produit ↔ composant ↔ vulnérabilité dans le temps — la valeur d'un ASPM est cumulative, pas instantanée.
Changer d'agrégateur après plusieurs mois d'usage ne se fait donc pas en remplaçant une ligne de pipeline : ça se fait en acceptant de perdre l'historique de triage, ou en migrant les données à la main. C'est exactement la définition Foyer d'un choix irréversible — d'où le veto complet, quand tous les autres outils de ce document en sont dispensés.
La grille appliquée à l'agrégateur lui-même¶
| Axe | Question posée | Ce qu'elle élimine |
|---|---|---|
| Altérité | Les findings (souvent liés à du code propriétaire) transitent-ils vers un tiers ? | Tout SaaS d'agrégation hébergé par l'éditeur — sauf si le code scanné est déjà public. |
| Réversibilité | Les données peuvent-elles être exportées dans un format réutilisable ailleurs ? | Les plateformes qui ne proposent qu'un export propriétaire ou une API fermée. |
| Érosion | Qui peut, seul, changer les conditions d'accès demain ? | Un éditeur unique à capital-risque, sans gouvernance partagée. |
| Coût | Seulement une fois les trois filtres précédents passés. | — |
Pourquoi DefectDojo et Dependency-Track passent les trois premiers filtres¶
- DefectDojo — licence BSD-3-Clause, projet phare de l'OWASP (pas un projet personnel ni une startup), auto-hébergeable, agrège plus de 200 formats de scanners en entrée. Le code source complet reste sous contrôle de qui l'héberge : pas d'altérité si déployé en interne.
- Dependency-Track — également OWASP, spécialisé SBOM/VEX plutôt que findings génériques, consomme nativement le CycloneDX déjà produit par tous les gates de ce document. Auto-hébergeable de la même façon.
Aucun des deux n'est présenté ici comme le choix — seulement comme les candidats qui survivent aux trois premiers filtres, ce qui justifie de leur consacrer l'atelier de sélection que les autres outils n'ont pas besoin de recevoir. Le choix définitif (lequel des deux, ou les deux en tandem — DefectDojo pour les findings de code, Dependency-Track pour la supply chain) reste une décision à documenter séparément, avec les personnes qui en répondront une fois déployé.
Ce que ça change concrètement dans l'usage des gates¶
Tant que l'agrégateur n'est pas choisi, chaque rapport produit par les gates de ce document (SARIF, CycloneDX) reste un artefact CI isolé, consultable mais non centralisé. Ce n'est pas bloquant pour démarrer — les gates fonctionnent et protègent dès leur activation, indépendamment de l'agrégation. C'est seulement la vision transversale (« quel produit est le plus exposé, cette semaine, tous scanners confondus ») qui manque tant que ce choix n'est pas tranché.