Dependency-Track : rendre visible le risque cache dans nos dependances
Quand on parle de securite applicative, on pense souvent au code que l'on ecrit nous-memes. Pourtant, une grande partie d'une application moderne vient de l'exterieur : librairies open source, frameworks, images de conteneurs, packages transitoires, outils embarques, services tiers. Ce patrimoine logiciel evolue en permanence, et une dependance saine aujourd'hui peut devenir vulnerable demain.
Dependency-Track repond a ce probleme avec une approche simple : inventorier ce que nous livrons, l'analyser en continu, puis alerter les bonnes personnes quand un risque apparait.
Dependency-Track : rendre visible le risque caché dans nos dependances
Dependency-Track : rendre visible le risque caché dans nos dependances
Quand on parle de sécurité applicative, on pense souvent au code que l'on écrit nous-mêmes. Pourtant, une grande partie d'une application moderne vient de l'extérieur : librairies open source, frameworks, images de conteneurs, packages transitoires, outils embarqués, services tiers. Ce patrimoine logiciel évolue en permanence, et une dépendance saine aujourd'hui peut devenir vulnérable demain.
Dependency-Track répond à ce problème avec une approche simple : inventorier ce que nous livrons, l'analyser en continu, puis alerter les bonnes personnes quand un risque apparaît.
Dependency-Track, à quoi ca sert ?
Dependency-Track est une plateforme open source de l'OWASP dédiée à l'analyse des SBOM, les Software Bills of Materials. Un SBOM est une nomenclature logicielle : il liste les composants présents dans une application, leurs versions, leurs relations, leurs licences et leurs identifiants techniques.
L'objectif n'est pas seulement de produire un rapport de plus. L'intérêt est de conserver une vision vivante du parc applicatif :
- quelles dépendances sont utilisées par telle application ;
- quelles versions sont déployées ou livrées ;
- quels composants sont vulnérables ;
- quelles failles touchent plusieurs projets ;
- quelles licences posent question ;
- quelles corrections doivent être priorisées.
En pratique, Dependency-Track devient un référentiel de risque logiciel. Les équipes n'ont plus besoin d'attendre le prochain scan manuel pour savoir qu'une CVE critique concerne une dépendance déjà embarquée. Une fois le SBOM importé, Dependency-Track continue de réanalyser le projet quand de nouvelles vulnérabilités sont publiées.
Pourquoi l'intégrer dans une démarche DevSecOps ?
La sécurité des dépendances pose trois difficultés récurrentes.
D'abord, le volume. Une application de taille moyenne peut embarquer des centaines de dépendances directes et transitives. Les suivre à la main est impossible.
Ensuite, le temps. Une version peut être acceptable au moment du build, puis devenir vulnérable quelques jours plus tard. Un scan ponctuel dans la CI ne suffit donc pas toujours.
Enfin, la priorisation. Toutes les vulnérabilités ne se valent pas. Il faut pouvoir croiser la sévérité, l'exploitabilité, les projets touchés, l'exposition de l'application et les décisions déjà prises par l'équipe sécurité.
Dependency-Track aide justement à passer d'une logique "scan puis oubli" à une logique de surveillance continue :
- chaque pipeline publie un SBOM ;
- Dependency-Track garde l'historique par projet et par version ;
- les composants sont comparés à plusieurs sources de vulnérabilités ;
- les alertes sont routées vers les canaux utilisés par les équipes ;
- les faux positifs et décisions de triage sont historisés.
Intégration dans notre plateforme Kubernetes
Dans notre socle technique, Dependency-Track est déployé comme un service de plateforme sur Kubernetes. Son cycle de vie suit la même logique que les autres composants transverses : configuration versionnée, déploiement GitOps, exposition contrôlée et supervision par la plateforme.
L'architecture sépare deux usages :
- une interface web pour consulter le portefeuille applicatif, les vulnérabilités, les composants et les décisions d'audit ;
- une API dédiée aux automatisations, principalement les pipelines CI/CD qui publient les SBOM.
Le service s'appuie sur une base de données persistante afin de conserver l'historique des projets, des versions, des analyses et des décisions de triage. L'accès utilisateur passe par l'authentification centralisée de l'entreprise, ce qui évite de multiplier les comptes locaux et facilite la gestion des droits.
Nous avons aussi prévu une logique de rétention des anciennes versions. Les branches restent visibles pour le suivi courant, les versions livrées les plus récentes sont conservées, et les versions plus anciennes peuvent être archivées. Cela permet de garder un portefeuille lisible malgré le rythme des livraisons applicatives.
Le flux cible
Le principe d'intégration est le suivant :
Développeur
|
v
Pipeline CI/CD
|
| 1. Build / tests / packaging
| 2. Génération du SBOM CycloneDX
| 3. Upload du SBOM vers Dependency-Track
v
Dependency-Track
|
| 4. Analyse vulnérabilités, licences, politiques
| 5. Réévaluation continue
v
Alertes Mail / Teams / WebhookLa CI/CD reste responsable de produire l'inventaire au bon moment. Dependency-Track devient responsable de l'analyser, de le conserver et de le surveiller dans le temps.
Intégration dans les CI/CD
Dependency-Track consomme nativement des SBOM CycloneDX. L'intégration type dans un pipeline consiste donc à :
- générer un fichier SBOM ;
- l'associer à un nom de projet et à une version ;
- l'envoyer à l'API Dependency-Track ;
- laisser Dependency-Track créer le projet si nécessaire ;
- consulter ou exploiter le résultat d'analyse.
Dans notre cas, l'intégration est découpée en trois blocs :
- génération d'un SBOM de dépendances depuis le dépôt avec Trivy ;
- génération d'un SBOM de l'image conteneur avec Syft ;
- publication des fichiers CycloneDX vers Dependency-Track avec un scanner dédié.
Exemple simplifié avec GitLab CI :
.dtrack-rules: &dtrack-rules
rules:
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "schedule"
dtrack:sbom:deps:
stage: scan
image:
name: $TRIVY_IMAGE
entrypoint: [""]
allow_failure: true
variables:
TRIVY_NO_PROGRESS: "true"
DTRACK_PROJECT_DIR: ""
DTRACK_SBOM_FILENAME: "deps.cyclonedx.json"
DTRACK_SKIP_DIRS: ""
script:
- |
[ -n "$DTRACK_PROJECT_DIR" ] && cd "$DTRACK_PROJECT_DIR"
SKIP_ARGS=""
[ -n "$DTRACK_SKIP_DIRS" ] && SKIP_ARGS="--skip-dirs ${DTRACK_SKIP_DIRS}"
trivy fs --exit-code 0 --format cyclonedx $SKIP_ARGS \
--output "${CI_PROJECT_DIR}/${DTRACK_SBOM_FILENAME}" .
- trivy sbom --severity HIGH,CRITICAL --exit-code 1 \
--no-progress "${CI_PROJECT_DIR}/${DTRACK_SBOM_FILENAME}"
artifacts:
when: always
paths:
- "*.cyclonedx.json"
expire_in: 30 min
<<: *dtrack-rules
dtrack:sbom:image:
stage: container-scan
image: $SYFT_IMAGE
allow_failure: true
variables:
FULL_IMAGE_NAME: ""
DTRACK_IMAGE_SBOM: "image.cyclonedx.json"
DTRACK_SYFT_CATALOGERS: "binary"
DTRACK_SYFT_EXCLUDE: ""
script:
- |
CATALOGERS_ARGS=""
[ -n "$DTRACK_SYFT_CATALOGERS" ] && \
CATALOGERS_ARGS="--override-default-catalogers ${DTRACK_SYFT_CATALOGERS}"
EXCLUDE_ARGS=""
[ -n "$DTRACK_SYFT_EXCLUDE" ] && EXCLUDE_ARGS="--exclude ${DTRACK_SYFT_EXCLUDE}"
syft scan "registry:${FULL_IMAGE_NAME}" $CATALOGERS_ARGS $EXCLUDE_ARGS \
-o cyclonedx-json="${CI_PROJECT_DIR}/${DTRACK_IMAGE_SBOM}"
artifacts:
paths:
- "*.cyclonedx.json"
expire_in: 30 min
<<: *dtrack-rules
dtrack:upload:
stage: security
image:
name: $DTRACK_SBOM_SCANNER_IMAGE
entrypoint: [""]
allow_failure: true
variables:
DEPTRACK_PROJECT_PATH: "${CI_PROJECT_PATH_SLUG}-{file_prefix}@${CI_COMMIT_REF_NAME}"
DEPTRACK_SBOM_PATTERNS: "**/*.cyclonedx.json **/*.cyclonedx.xml"
DEPTRACK_SHOW_FINDINGS: "false"
DEPTRACK_RISK_SCORE_THRESHOLD: "-1"
script:
- sbom-scanner
<<: *dtrack-rulesLes jobs ne tournent pas sur chaque commit de branche de travail : ils sont limités aux tags, à la branche par défaut et aux exécutions planifiées. Cela donne une vision régulière du risque sans alourdir inutilement tous les pipelines.
Le job Trivy produit un SBOM CycloneDX depuis le système de fichiers du projet. Il relit ensuite ce SBOM pour remonter un avertissement si des vulnérabilités HIGH ou CRITICAL sont détectées. Le job reste en allow_failure afin de ne pas bloquer brutalement les développeurs pendant la phase de mise en place.
Le job Syft produit un SBOM de l'image conteneur. C'est complémentaire au scan du dépôt : le premier voit les dépendances applicatives, le second voit ce qui est réellement embarqué dans l'image finale.
Le job d'upload cherche les fichiers *.cyclonedx.json et *.cyclonedx.xml, puis les publie dans Dependency-Track. Le nom de projet intègre le projet Git, le préfixe du fichier SBOM et la référence Git. Cela permet de différencier, par exemple, un SBOM applicatif et un SBOM image pour un même service.
Les variables sensibles, comme l'URL de l'API et la clé d'accès Dependency-Track, sont stockées comme variables protégées de CI. Le seuil DEPTRACK_RISK_SCORE_THRESHOLD peut rester désactivé au départ, puis être activé plus tard quand les équipes sont prêtes à introduire du blocage.
Quelques exemples courants :
Écosystème | Génération SBOM possible Java / Maven | plugin CycloneDX Maven Java / Gradle | plugin CycloneDX Gradle Node.js | outil CycloneDX npm Python | outil CycloneDX Python Conteneur | Syft ou outil compatible CycloneDX
Pour une application conteneurisée, on peut produire un SBOM à partir du code source, de l'image finale, ou des deux. Le SBOM source donne une bonne vision des dépendances applicatives. Le SBOM image ajoute les paquets système présents dans l'image livrée.
Branches, tags et versions
La qualité du nommage est importante. Si chaque pipeline pousse un projet différent, Dependency-Track devient vite difficile à lire.
Une convention simple fonctionne bien :
- projectName : chemin applicatif stable, par exemple groupe/produit/service ;
- projectVersion pour une branche : develop, main, feature/xxx ;
- projectVersion pour une livraison : tag applicatif, par exemple v1.8.3.
Les branches donnent une vision continue du risque pendant le développement. Les tags représentent les versions livrées ou candidates à la livraison. Ce découpage permet ensuite de filtrer les alertes : toutes les vulnérabilités d'une branche de travail ne méritent pas la même urgence qu'une vulnérabilité sur une version en production.
Faut-il faire échouer le pipeline ?
Dependency-Track peut s'intégrer à une politique de qualité, mais il faut éviter de bloquer brutalement toutes les équipes au premier signal.
Une trajectoire progressive est souvent plus efficace :
- publication du SBOM sans blocage ;
- alertes Teams ou mail sur les nouveaux risques critiques ;
- revue régulière des projets les plus exposés ;
- politiques de blocage sur les vulnérabilités critiques connues, non acceptées et corrigeables ;
- exceptions documentées via les décisions d'audit.
Cette approche évite le "mur rouge" permanent. Elle installe d'abord la visibilité, puis ajoute de la gouvernance là où elle apporte vraiment de la valeur.
Intégration Mail et Microsoft Teams
Dependency-Track dispose d'un système de notifications configurable. Les alertes peuvent porter sur des événements techniques ou sur le portefeuille applicatif : nouvelle vulnérabilité, dépendance vulnérable ajoutée à un projet, échec de traitement d'un SBOM, violation de politique, changement d'analyse, synthèse planifiée, etc.
Les canaux utiles pour nous sont principalement :
- Email : pratique pour les synthèses, les notifications formelles et les destinataires stables ;
- Microsoft Teams : adapté aux alertes opérationnelles proches du temps réel ;
- Webhook sortant : utile pour raccorder un outil interne, un bus d'événements ou une automatisation spécifique.
Pour Teams, le principe est de créer un webhook entrant côté canal Teams, puis de le déclarer dans Dependency-Track comme destination de notification. Pour l'email, la destination est une liste d'adresses séparées par des virgules.
Une configuration pragmatique :
Alerte | Canal | Cible BOM_PROCESSING_FAILED | Teams | Canal plateforme BOM_VALIDATION_FAILED | Teams | Équipe projet concernée NEW_VULNERABLE_DEPENDENCY | Teams | Équipe projet NEW_VULNERABILITIES_SUMMARY | Email | Référents tech + sécurité POLICY_VIOLATION | Teams ou Email | Selon criticité
Pour limiter le bruit, les notifications doivent être restreintes par projet, par tag ou par groupe de projets quand c'est possible. Une alerte globale sur tout le portefeuille peut être utile au départ, mais elle devient vite trop bavarde.
Exploitation au quotidien
Une fois l'intégration en place, l'exploitation se concentre sur quelques gestes simples.
Les équipes projet consultent leurs projets dans Dependency-Track pour identifier les composants vulnérables, comprendre les versions touchées et suivre les corrections.
Les référents sécurité ou plateforme surveillent les tendances : applications les plus exposées, vulnérabilités récurrentes, projets sans SBOM récent, échecs d'import, dette de triage.
Les décisions d'audit permettent de documenter le traitement d'un finding :
- exploitable ;
- non exploitable ;
- faux positif ;
- risque accepté temporairement ;
- correction planifiée.
L'intérêt est de garder la décision au même endroit que le constat technique. Quand une vulnérabilité réapparaît ou touche plusieurs projets, l'historique évite de refaire la même analyse depuis zéro.
Bonnes pratiques
Quelques règles rendent l'outil beaucoup plus efficace :
- publier un SBOM à chaque pipeline significatif ;
- utiliser un nom de projet stable ;
- distinguer branches et tags ;
- protéger la clé API Dependency-Track dans le coffre de secrets CI/CD ;
- éviter de partager une clé API trop privilégiée entre toutes les applications ;
- surveiller les échecs d'import de SBOM ;
- définir une politique de rétention des anciennes versions ;
- limiter les notifications pour éviter la fatigue d'alerte ;
- documenter les décisions d'audit importantes.
Limites à garder en tête
Dependency-Track n'est pas un outil magique qui corrige les dépendances à notre place. Il dépend de la qualité du SBOM fourni, de la fraîcheur des sources de vulnérabilités et de la capacité des équipes à traiter les alertes.
Il ne remplace pas non plus les autres contrôles de sécurité : SAST, DAST, scan d'image, durcissement Kubernetes, revue de code, gestion des secrets. Sa force est ailleurs : donner une vision continue de la composition logicielle et du risque associé.
Conclusion
Dependency-Track apporte une brique essentielle à une chaîne DevSecOps mature : la connaissance de ce que nous livrons. En automatisant la publication des SBOM depuis les pipelines CI/CD, puis en routant les alertes vers Mail, Teams ou des webhooks, on transforme un inventaire technique en dispositif opérationnel.
Le gain principal n'est pas seulement de trouver des CVE. C'est de savoir rapidement quels projets sont concernés, qui doit agir, quelles décisions ont déjà été prises, et quelles versions doivent être corrigées en priorité.