Aller au contenu
Sécurité medium

Dependency-Track : centraliser la gestion des SBOM

33 min de lecture

dependency-track logo

Dependency-Track est une plateforme open-source qui centralise l'analyse des vulnérabilités de tous vos projets. Vous uploadez des SBOM (Software Bill of Materials), et Dependency-Track les corrèle automatiquement avec les bases de vulnérabilités (NVD, GitHub Advisories, OSS Index). Contrairement aux scanners ponctuels, il surveille en continu : une vulnérabilité découverte demain sur une dépendance présente dans 50 projets vous alertera automatiquement.

Ce guide couvre l'installation (Docker, Kubernetes), la configuration des sources de vulnérabilités, l'API REST, l'intégration CI/CD et les alertes (Slack, Teams, email).

Le parcours suit le trajet réel d'un SBOM : il est produit par un scanner comme Trivy ou Syft, transmis à Dependency-Track via l'API REST, puis corrélé en continu avec les bases de vulnérabilités. Les deux dernières étapes sont celles qui font la différence avec un scanner classique : les notifications, qui vous préviennent quand une CVE apparaît sur un composant déjà inventorié, et les politiques, qui transforment un constat en règle opposable.

  • Comprendre le rôle d'un SBOM et pourquoi centraliser leur analyse
  • Installer Dependency-Track avec Docker Compose ou Kubernetes
  • Configurer les sources de vulnérabilités (NVD, GitHub Advisories, OSS Index)
  • Uploader des SBOM via l'API REST et automatiser dans vos pipelines CI/CD
  • Créer des alertes pour être notifié des nouvelles vulnérabilités
  • Définir des politiques pour bloquer les composants non conformes

Vous utilisez peut-être déjà Trivy ou Grype pour scanner vos images. Ces outils sont excellents pour détecter les vulnérabilités à un instant T. Mais que se passe-t-il quand :

  • Une nouvelle CVE est publiée pour Log4j, et vous ne savez pas quels projets l'utilisent ?
  • Vous devez prouver à un auditeur que vous avez corrigé une vulnérabilité sur tous vos projets ?
  • Votre équipe sécurité veut un tableau de bord de toutes les vulnérabilités de l'entreprise ?

Dependency-Track résout ces problèmes en centralisant les SBOM de tous vos projets et en les corrélant en continu avec les bases de vulnérabilités.

ApprocheScanner ponctuel (Trivy, Grype)Dependency-Track
Quand ?À chaque build/scanEn continu (24/7)
Scope1 projet à la foisTous les projets
Nouvelles CVEDétectées au prochain scanAlertes immédiates
Vue d'ensembleNonTableau de bord global
HistoriqueNonOui, avec métriques dans le temps

Quatre notions conditionnent la qualité des résultats. Le SBOM décrit ce que contient votre application, le PURL identifie chaque composant de façon non ambiguë, les sources de vulnérabilités apportent les CVE connues, et les analyseurs font le rapprochement entre les deux. Un maillon faible dans cette chaîne se traduit toujours de la même manière : des composants réellement vulnérables qui n'apparaissent nulle part dans le tableau de bord.

Un SBOM est la liste complète des composants qui constituent votre logiciel. Comme la liste d'ingrédients sur un emballage alimentaire, il permet de savoir exactement ce que contient votre application.

{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"components": [
{
"name": "lodash",
"version": "4.17.21",
"purl": "pkg:npm/lodash@4.17.21"
},
{
"name": "express",
"version": "4.18.2",
"purl": "pkg:npm/express@4.18.2"
}
]
}

Formats supportés par Dependency-Track :

FormatDescriptionOutils générateurs
CycloneDXStandard OWASP, recommandéTrivy, Syft, cdxgen
SPDXStandard Linux FoundationSyft, tern

Le PURL (Package URL) est un identifiant universel pour les packages. Il permet à Dependency-Track de retrouver un composant dans les bases de vulnérabilités.

pkg:npm/lodash@4.17.21
pkg:maven/org.apache.logging.log4j/log4j-core@2.17.0
pkg:apk/alpine/openssl@3.0.8-r0
pkg:deb/debian/openssl@1.1.1n-0+deb10u3

Dependency-Track consulte plusieurs bases de données pour détecter les vulnérabilités :

SourceDescriptionConfiguration
NVDNational Vulnerability Database (NIST)Activée par défaut, API key recommandée
GitHub AdvisoriesVulnérabilités GitHubToken GitHub requis
OSS IndexSonatype, gratuitActivée par défaut
OSVOpen Source Vulnerabilities (Google)Optionnelle
SnykBase commercialeToken Snyk requis
VulnDBBase commerciale (Risk Based Security)Abonnement requis

En plus des bases de vulnérabilités, Dependency-Track utilise des analyseurs pour enrichir les données :

AnalyseurFonction
Internal AnalyzerCorrèle les composants avec la base interne
NPM AuditVulnérabilités npm spécifiques
OSS IndexAnalyse via API Sonatype
TrivyIntégration avec un serveur Trivy (v4.13+)
SnykAnalyse via API Snyk

Dependency-Track se déploie en deux composants distincts : un apiserver qui porte toute la logique et la base, et un frontend qui n'est qu'une application web statique interrogeant l'API. Les confondre est la cause la plus fréquente d'écran vide au premier démarrage, le frontend étant configuré avec une mauvaise API_BASE_URL. Comptez plusieurs minutes avant la première réponse de l'API, le temps de la migration de schéma.

La consommation mémoire vient surtout du miroir local des bases de vulnérabilités, que l'apiserver télécharge et indexe. C'est aussi ce qui rend PostgreSQL obligatoire en pratique : H2 ne tient pas la charge en écriture pendant la synchronisation NVD.

  • Docker et Docker Compose (méthode recommandée)
  • 4 Go de RAM minimum (8 Go recommandés pour la production)
  • PostgreSQL (H2 déprécié depuis v4.13)

Les mots de passe de cette pile sont volontairement triviaux pour l'essai local : la base contient l'inventaire complet de vos composants, information précieuse pour un attaquant qui cherche une cible vulnérable. Notez que l'API est publiée sur le port 8081 et l'interface sur le 8080, d'où le décalage dans les URL qui suivent.

  1. Créer le fichier docker-compose.yml

    services:
    dtrack-apiserver:
    image: dependencytrack/apiserver:4.13.6@sha256:74bb6e9d82a4370930085934b4a4089864fefc7c65fcd180b45b045f7671c3d6
    depends_on:
    - postgres
    environment:
    # Base de données PostgreSQL
    - ALPINE_DATABASE_MODE=external
    - ALPINE_DATABASE_URL=jdbc:postgresql://postgres:5432/dtrack
    - ALPINE_DATABASE_DRIVER=org.postgresql.Driver
    - ALPINE_DATABASE_USERNAME=dtrack
    - ALPINE_DATABASE_PASSWORD=dtrack
    # Synchronisation initiale (optionnel, améliore le démarrage)
    - ALPINE_DATABASE_POOL_ENABLED=true
    - ALPINE_DATABASE_POOL_MAX_SIZE=20
    volumes:
    - dtrack-data:/data
    ports:
    - "8081:8080"
    restart: unless-stopped
    dtrack-frontend:
    image: dependencytrack/frontend:4.13.6@sha256:b8e8d98568e6dd76976d46c78b5eaffc7eac9044df30f9daacc628faacab067f
    depends_on:
    - dtrack-apiserver
    environment:
    - API_BASE_URL=http://localhost:8081
    ports:
    - "8080:8080"
    restart: unless-stopped
    postgres:
    image: postgres:16-alpine@sha256:57c72fd2a128e416c7fcc499958864df5301e940bca0a56f58fddf30ffc07777
    environment:
    - POSTGRES_DB=dtrack
    - POSTGRES_USER=dtrack
    - POSTGRES_PASSWORD=dtrack
    volumes:
    - postgres-data:/var/lib/postgresql/data
    restart: unless-stopped
    volumes:
    dtrack-data:
    postgres-data:
  2. Démarrer les services

    Fenêtre de terminal
    docker compose up -d

    Sortie attendue :

    [+] Running 4/4
    ✔ Network dependency-track_default Created
    ✔ Container postgres Started
    ✔ Container dtrack-apiserver Started
    ✔ Container dtrack-frontend Started
  3. Vérifier le démarrage

    Fenêtre de terminal
    # Attendre que l'API soit prête (30-60 secondes)
    curl -s http://localhost:8081/api/version | jq .

    Sortie attendue :

    {
    "version": "4.13.6",
    "timestamp": "2025-11-17T08:44:22Z",
    "framework": {
    "name": "Alpine",
    "version": "3.4.0"
    },
    "database": {
    "productVersion": "16.11",
    "productName": "PostgreSQL"
    }
    }
  4. Accéder à l'interface

    Ouvrez http://localhost:8080 dans votre navigateur.

    • Identifiant : admin
    • Mot de passe : admin (à changer immédiatement)

Pour un déploiement Kubernetes, utilisez le chart Helm officiel :

Fenêtre de terminal
# Ajouter le repository
helm repo add dependencytrack https://dependencytrack.github.io/helm-charts
helm repo update
# Installer avec PostgreSQL externe
helm install dependency-track dependencytrack/dependency-track \
--namespace dependency-track \
--create-namespace \
--set apiserver.database.url=jdbc:postgresql://postgres:5432/dtrack \
--set apiserver.database.username=dtrack \
--set apiserver.database.password=dtrack \
--set frontend.env.API_BASE_URL=https://dtrack.example.com/api

Trois réglages conditionnent l'exploitabilité de l'installation : le compte admin, livré avec un mot de passe public, les sources de vulnérabilités, sans lesquelles l'outil inventorie sans jamais alerter, et l'API key que consommeront vos pipelines. Tant que la synchronisation NVD n'est pas terminée, un projet peut afficher zéro vulnérabilité tout en étant réellement affecté.

Dependency-Track impose le changement dès la première connexion et renvoie le marqueur FORCE_PASSWORD_CHANGE au lieu d'un token tant que l'opération n'a pas été faite.

  1. Se connecter à l'interface avec admin / admin

  2. Aller dans Administration → Access Management → Managed Users

  3. Cliquer sur admin puis Change Password

Ou via l'API :

Fenêtre de terminal
# Obtenir un token (vous serez forcé de changer le mot de passe)
curl -X POST "http://localhost:8081/api/v1/user/login" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'username=admin&password=admin'
# Réponse si changement requis
# FORCE_PASSWORD_CHANGE
# Changer le mot de passe
curl -X POST "http://localhost:8081/api/v1/user/forceChangePassword" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'username=admin&password=admin&newPassword=VotreNouveauMotDePasse123&confirmPassword=VotreNouveauMotDePasse123'

Par défaut, seules NVD et OSS Index sont activées. Pour de meilleurs résultats, configurez des sources supplémentaires.

La synchronisation NVD initiale prend plusieurs heures sans clé API. Avec une clé API gratuite, elle prend environ 30 minutes.

  1. Obtenir une clé API NVD : https://nvd.nist.gov/developers/request-an-api-key
  2. Configurer dans Administration → Analyzers → National Vulnerability Database
  3. Coller votre clé API
# Via variables d'environnement dans docker-compose.yml
environment:
- ALPINE_VULNERABILITY_SOURCE_NVD_API_KEY=votre-cle-api-nvd

Pour intégrer Dependency-Track dans vos pipelines CI/CD, vous avez besoin d'un API key avec les bonnes permissions.

  1. Créer une équipe

    Fenêtre de terminal
    # S'authentifier
    TOKEN=$(curl -s -X POST "http://localhost:8081/api/v1/user/login" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d 'username=admin&password=VotreMotDePasse' )
    # Créer l'équipe
    curl -s -X PUT "http://localhost:8081/api/v1/team" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"name":"CI-CD-Integration"}' | jq .

    Sortie :

    {
    "uuid": "ec9f8bc4-8953-4c57-beed-62fb189960ec",
    "name": "CI-CD-Integration",
    "apiKeys": [],
    "permissions": []
    }
  2. Ajouter les permissions

    Fenêtre de terminal
    TEAM_UUID="ec9f8bc4-8953-4c57-beed-62fb189960ec"
    # Permissions nécessaires pour le CI/CD
    for PERM in BOM_UPLOAD PROJECT_CREATION_UPLOAD VIEW_VULNERABILITY; do
    curl -s -X POST "http://localhost:8081/api/v1/permission/${PERM}/team/${TEAM_UUID}" \
    -H "Authorization: Bearer $TOKEN"
    done
  3. Générer un API key

    Fenêtre de terminal
    curl -s -X PUT "http://localhost:8081/api/v1/team/${TEAM_UUID}/key" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" | jq -r '.key'

    Sortie :

    odt_2d7FSPVR_wypkOzMckIbjsNkUcahyYA5XqrqhYPOr

Une équipe CI/CD n'a besoin que des trois premières entrées de ce tableau. Les quatre suivantes autorisent la modification des verdicts d'analyse et des politiques : accordées à un pipeline, elles permettraient à une clé compromise de marquer une vulnérabilité comme non applicable et de faire disparaître l'alerte au lieu de la corriger.

PermissionDescription
BOM_UPLOADUploader des SBOM
PROJECT_CREATION_UPLOADCréer des projets automatiquement lors de l'upload
VIEW_VULNERABILITYVoir les vulnérabilités
VULNERABILITY_ANALYSISModifier l'analyse des vulnérabilités
PORTFOLIO_MANAGEMENTGérer les projets et composants
POLICY_MANAGEMENTGérer les politiques
SYSTEM_CONFIGURATIONConfiguration système

Dependency-Track ne scanne rien lui-même : il consomme des SBOM produits ailleurs. La qualité de l'analyse dépend donc entièrement du générateur, et plus précisément des PURL qu'il inscrit. Un composant sans PURL exploitable reste listé dans l'inventaire mais ne sera jamais rapproché d'une CVE, ce qui produit un projet à zéro vulnérabilité en apparence rassurant.

Le scanner détecte les gestionnaires de paquets présents et en déduit les composants ; l'option --scanners vuln ajoute les vulnérabilités connues dans le document, information que Dependency-Track recalculera de son côté.

Fenêtre de terminal
# Scanner une image Docker
trivy image --format cyclonedx nginx:1.25 > nginx-sbom.json
# Scanner un projet local
trivy fs --format cyclonedx . > project-sbom.json
# Scanner avec les vulnérabilités incluses
trivy image --format cyclonedx --scanners vuln python:3.12 > python-sbom.json

Syft se concentre sur l'inventaire sans chercher les vulnérabilités, ce qui le rend plus rapide et généralement plus exhaustif sur les écosystèmes applicatifs que sur les seuls paquets système.

Fenêtre de terminal
# Scanner une image
syft nginx:1.25 -o cyclonedx-json > nginx-sbom.json
# Scanner un répertoire
syft dir:. -o cyclonedx-json > project-sbom.json

Le champ autoCreate est le réglage qui décide du reste : à true, le couple projectName et projectVersion crée le projet s'il n'existe pas, ce qui permet à un pipeline de fonctionner sans préparation manuelle. Corollaire, une faute de frappe sur le nom crée un projet parallèle au lieu d'échouer, et l'historique du projet d'origine s'arrête sans avertissement.

Fenêtre de terminal
API_KEY="odt_votre_api_key"
BOM_BASE64=$(base64 -w 0 nginx-sbom.json)
curl -X PUT "http://localhost:8081/api/v1/bom" \
-H "X-Api-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"projectName\": \"nginx\",
\"projectVersion\": \"1.25\",
\"autoCreate\": true,
\"bom\": \"$BOM_BASE64\"
}"

Sortie :

{
"token": "9f4c18b6-e20c-44e6-8710-f332a53a6275"
}

L'upload est asynchrone. Utilisez le token pour vérifier le statut :

Fenêtre de terminal
curl -s "http://localhost:8081/api/v1/bom/token/9f4c18b6-e20c-44e6-8710-f332a53a6275" \
-H "X-Api-Key: $API_KEY" | jq .

Sortie pendant le traitement :

{
"processing": true
}

Sortie après traitement :

{
"processing": false
}

Les compteurs exposés par l'API proviennent d'un calcul de métriques asynchrone, distinct du traitement du SBOM. Juste après un upload, il est normal de voir des composants inventoriés et des compteurs de vulnérabilités encore à zéro. Ces mêmes endpoints alimentent les tableaux de bord et se prêtent bien à l'export vers un outil de suivi.

Le bloc metrics renvoie l'état du dernier calcul, pas une évaluation en temps réel : c'est la valeur affichée dans l'interface.

Fenêtre de terminal
curl -s "http://localhost:8081/api/v1/project" \
-H "X-Api-Key: $API_KEY" | jq '.[] | {name, version, metrics}'

Sortie :

{
"name": "nginx",
"version": "1.25",
"metrics": {
"critical": 2,
"high": 5,
"medium": 12,
"low": 3,
"components": 45,
"vulnerableComponents": 8
}
}

L'endpoint attend l'UUID du projet, pas son nom : récupérez-le d'abord via la liste des projets. Le champ source indique quelle base a produit le verdict, information utile quand deux sources divergent sur la sévérité.

Fenêtre de terminal
PROJECT_UUID="fe281b4c-347c-45ed-9911-b2bc26245fc1"
curl -s "http://localhost:8081/api/v1/vulnerability/project/${PROJECT_UUID}" \
-H "X-Api-Key: $API_KEY" | jq '.[] | {vulnId, severity, source, cvssV3BaseScore}'

Sortie :

{
"vulnId": "CVE-2024-12345",
"severity": "CRITICAL",
"source": "NVD",
"cvssV3BaseScore": 9.8
}

Cet endpoint agrège l'ensemble des projets et fournit l'indicateur le plus parlant pour un pilotage : le rapport entre projects et vulnerableProjects, qui se suit dans le temps beaucoup mieux qu'un total brut de CVE.

Fenêtre de terminal
curl -s "http://localhost:8081/api/v1/metrics/portfolio/current" \
-H "X-Api-Key: $API_KEY" | jq '{projects, vulnerableProjects, critical, high, medium, low}'

Sortie :

{
"projects": 15,
"vulnerableProjects": 8,
"critical": 12,
"high": 45,
"medium": 128,
"low": 67
}

Les trois pipelines ci-dessous appliquent le même schéma : générer le SBOM pendant le build, puis le pousser vers Dependency-Track avec une API key stockée en secret, jamais en clair dans le fichier. Point important, ces exemples n'échouent pas sur la présence de vulnérabilités : l'upload est asynchrone et le job se termine avant la fin de l'analyse. Bloquer une release suppose d'interroger ensuite les métriques du projet ou de s'appuyer sur les politiques.

La projectVersion alimentée par CI_COMMIT_REF_NAME crée un projet distinct par branche, ce qui permet de comparer une branche de fonctionnalité à main mais multiplie les entrées si les branches ne sont jamais nettoyées.

.gitlab-ci.yml
stages:
- build
- security
variables:
DTRACK_URL: "https://dependency-track.example.com"
DTRACK_API_KEY: $DTRACK_API_KEY # Secret CI/CD
generate_sbom:
stage: build
image: aquasec/trivy:0.72.0@sha256:cffe3f5161a47a6823fbd23d985795b3ed72a4c806da4c4df16266c02accdd6f
script:
- trivy fs --format cyclonedx --output sbom.json .
artifacts:
paths:
- sbom.json
expire_in: 1 week
upload_sbom:
stage: security
image: curlimages/curl:8.21.0@sha256:7c12af72ceb38b7432ab85e1a265cff6ae58e06f95539d539b654f2cfa64bb13
needs:
- generate_sbom
script:
- |
BOM_BASE64=$(base64 -w 0 sbom.json)
curl -X PUT "${DTRACK_URL}/api/v1/bom" \
-H "X-Api-Key: ${DTRACK_API_KEY}" \
-H "Content-Type: application/json" \
-d "{
\"projectName\": \"${CI_PROJECT_NAME}\",
\"projectVersion\": \"${CI_COMMIT_REF_NAME}\",
\"autoCreate\": true,
\"bom\": \"${BOM_BASE64}\"
}"

Ce workflow s'exécute aussi sur les pull requests, y compris celles venant d'un dépôt forké : vérifiez que vos secrets ne leur sont pas exposés, faute de quoi l'API key partirait vers un contexte non maîtrisé. Les actions gagnent par ailleurs à être épinglées par SHA plutôt que par tag.

.github/workflows/sbom.yml
name: SBOM Upload
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
sbom:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Generate SBOM
uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0
with:
format: cyclonedx-json
output-file: sbom.json
- name: Upload to Dependency-Track
run: |
BOM_BASE64=$(base64 -w 0 sbom.json)
curl -X PUT "${{ secrets.DTRACK_URL }}/api/v1/bom" \
-H "X-Api-Key: ${{ secrets.DTRACK_API_KEY }}" \
-H "Content-Type: application/json" \
-d "{
\"projectName\": \"${{ github.repository }}\",
\"projectVersion\": \"${{ github.ref_name }}\",
\"autoCreate\": true,
\"bom\": \"${BOM_BASE64}\"
}"

Le credentials() injecte la clé dans l'environnement du job ; Jenkins masque sa valeur dans les journaux, mais pas dans un fichier que le script écrirait lui-même. Ici la version du projet suit le BUILD_NUMBER, ce qui crée une entrée par build et rend l'historique très verbeux.

// Jenkinsfile
pipeline {
agent any
environment {
DTRACK_URL = 'https://dependency-track.example.com'
DTRACK_API_KEY = credentials('dtrack-api-key')
}
stages {
stage('Generate SBOM') {
steps {
sh 'docker run --rm -v $(pwd):/app aquasec/trivy fs --format cyclonedx /app > sbom.json'
}
}
stage('Upload SBOM') {
steps {
sh '''
BOM_BASE64=$(base64 -w 0 sbom.json)
curl -X PUT "${DTRACK_URL}/api/v1/bom" \
-H "X-Api-Key: ${DTRACK_API_KEY}" \
-H "Content-Type: application/json" \
-d "{
\\"projectName\\": \\"${JOB_NAME}\\",
\\"projectVersion\\": \\"${BUILD_NUMBER}\\",
\\"autoCreate\\": true,
\\"bom\\": \\"${BOM_BASE64}\\"
}"
'''
}
}
}
}

C'est la fonction qui justifie à elle seule la centralisation : une CVE publiée demain sur un composant présent dans plusieurs projets déclenche une alerte sans qu'aucun build ne soit rejoué. Le piège est inverse de celui des scanners classiques : mal filtrées, ces notifications produisent un volume tel qu'elles finissent ignorées. D'où l'intérêt des résumés programmés apparus en v4.13, et d'un filtrage par sévérité dès la première règle.

Dependency-Track peut vous alerter via plusieurs canaux. Depuis v4.13, les notifications programmées (résumé quotidien/hebdomadaire) sont disponibles.

  1. Aller dans Administration → Notifications → Alerts

  2. Créer un nouveau publisher (Slack, Teams, Email, Webhook...)

  3. Créer une règle de notification :

    • Sélectionner les événements (nouvelles vulnérabilités, violations de politique...)
    • Assigner le publisher
    • Optionnel : filtrer par projet ou sévérité

Deux événements sont à distinguer soigneusement. NEW_VULNERABILITY signale une CVE nouvellement publiée sur un composant que vous aviez déjà, sans qu'aucun build n'ait eu lieu ; NEW_VULNERABLE_DEPENDENCY signale au contraire un composant vulnérable que vous venez d'introduire. Le premier est un signal de veille, le second un défaut de développement.

ÉvénementDescription
NEW_VULNERABILITYNouvelle vulnérabilité détectée
NEW_VULNERABLE_DEPENDENCYNouveau composant vulnérable ajouté
ANALYSIS_DECISION_CHANGEChangement de statut d'analyse
POLICY_VIOLATIONViolation d'une politique
BOM_CONSUMEDSBOM uploadé avec succès
BOM_PROCESSING_FAILEDÉchec de traitement d'un SBOM
VEX_CONSUMEDVEX importé

Les nouveaux types de notifications en mode résumé permettent de recevoir une synthèse plutôt qu'une alerte par vulnérabilité :

TypeDescription
NEW_VULNERABILITIES_SUMMARYRésumé des nouvelles vulnérabilités
NEW_POLICY_VIOLATIONS_SUMMARYRésumé des violations de politique

Configuration via expression cron dans l'interface ou l'API.

Le champ template est un gabarit dans lequel Dependency-Track substitue les variables ${...} au moment de l'envoi ; c'est là que vous décidez du niveau de détail transmis. La destination est une URL de webhook, donc un secret à part entière : quiconque la détient peut publier dans le canal.

{
"name": "Slack Alerts",
"publisherClass": "org.dependencytrack.notification.publisher.SlackPublisher",
"templateMimeType": "application/json",
"template": "{\"text\": \"Nouvelle vulnérabilité ${vulnerability.vulnId} (${vulnerability.severity}) détectée dans ${project.name}\"}",
"destination": "https://hooks.slack.com/services/XXX/YYY/ZZZ"
}

Les politiques permettent de définir des règles automatiques pour détecter les composants non conformes.

La condition License mérite une attention particulière : c'est la seule qui ne traite pas de sécurité mais de conformité juridique, et le seul moyen d'attraper automatiquement l'arrivée d'une dépendance sous licence incompatible avec votre distribution. Component Age sert d'indicateur indirect d'abandon, un composant sans publication depuis des années étant rarement corrigé rapidement.

ConditionDescription
SeverityNiveau de sévérité (CRITICAL, HIGH, MEDIUM, LOW)
LicenseLicences interdites (GPL, AGPL...)
Component AgeÂge du composant
CoordinatesPackage spécifique (name, version, purl)
SWID Tag IDIdentifiant SWID
CWECatégorie de faiblesse (CWE-79, CWE-89...)

Le niveau Fail n'interrompt aucun build par lui-même : Dependency-Track marque la violation et émet un événement POLICY_VIOLATION, à charge pour votre pipeline d'interroger l'API et de décider. La différence entre les trois niveaux est donc surtout une question de priorisation, pas de blocage automatique.

  1. Aller dans Policies → Create Policy

  2. Définir les conditions :

    SujetOpérateurValeur
    SeverityISCRITICAL
  3. Assigner aux projets (tous ou sélection)

  4. Choisir le niveau de violation :

    • Fail : Bloquant (affichage rouge)
    • Warn : Avertissement (affichage orange)
    • Info : Information (affichage bleu)

La condition COORDINATES vise un composant précis par son groupe, son nom et un intervalle de version, indépendamment de ce que disent les bases de CVE. C'est le seul moyen d'interdire durablement une version dont vous savez qu'elle pose problème dans votre contexte, y compris avant publication d'un identifiant officiel.

Fenêtre de terminal
curl -X PUT "http://localhost:8081/api/v1/policy" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Block Log4j < 2.17.1",
"violationState": "FAIL",
"policyConditions": [
{
"subject": "COORDINATES",
"operator": "MATCHES",
"value": "{\"group\":\"org.apache.logging.log4j\",\"name\":\"log4j-core\",\"version\":\"<2.17.1\"}"
}
]
}'

Les Collection Projects permettent d'organiser vos projets de manière hiérarchique.

Sans regroupement, une application découpée en quinze microservices apparaît comme quinze projets sans lien, et personne ne sait répondre à la question de sa posture globale. La collection résout ce point en agrégeant les métriques des projets enfants ; elle ne duplique pas les composants et ne change rien à l'analyse individuelle.

  • Regrouper les microservices d'une même application
  • Créer une vue "équipe" avec tous les projets d'une équipe
  • Agréger les métriques de plusieurs projets

Une collection est un projet ordinaire dont le champ collectionLogic a été positionné : c'est ce seul champ qui bascule le comportement. Les projets enfants doivent ensuite lui être rattachés par la relation parent, l'agrégation ne se déduit pas des noms.

Fenêtre de terminal
curl -X PUT "http://localhost:8081/api/v1/project" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Platform E-Commerce",
"version": "1.0",
"collectionLogic": "AGGREGATE_DIRECT_CHILDREN"
}'

Logiques de collection :

LogiqueDescription
NONEProjet standard (défaut)
AGGREGATE_DIRECT_CHILDRENAgrège les enfants directs
AGGREGATE_ALL_CHILDRENAgrège tous les descendants

La panne la plus dangereuse ici n'en est pas une visuellement : un projet qui affiche zéro vulnérabilité. Ce résultat peut vouloir dire que tout va bien, que les bases ne sont pas encore synchronisées, ou que les composants du SBOM n'ont pas de PURL exploitable. Avant de conclure, vérifiez toujours le nombre de composants inventoriés et l'état de la synchronisation.

Les défaillances de démarrage viennent presque toujours de l'ordre d'apparition des services : l'apiserver tente sa migration de schéma avant que PostgreSQL n'accepte les connexions.

SymptômeCause probableSolution
API ne répond pasContainer non démarrédocker compose logs dtrack-apiserver
Erreur databasePostgreSQL non prêtAttendre ou vérifier docker compose logs postgres
Frontend erreur APIURL API incorrecteVérifier API_BASE_URL dans la config frontend
Synchronisation lentePas de clé API NVDObtenir une clé gratuite sur nvd.nist.gov

Un 403 se distingue d'un 401 : la clé est valide mais l'équipe à laquelle elle appartient n'a pas la permission demandée. C'est le cas typique d'une équipe créée sans PROJECT_CREATION_UPLOAD, qui réussit à envoyer un SBOM vers un projet existant et échoue dès qu'autoCreate doit intervenir.

SymptômeCause probableSolution
401 UnauthorizedAPI key invalideVérifier l'API key, régénérer si nécessaire
403 ForbiddenPermissions manquantesAjouter BOM_UPLOAD et PROJECT_CREATION_UPLOAD
Processing=true indéfinimentServeur surchargéVérifier les ressources (RAM, CPU)
0 vulnérabilitésBases non synchroniséesAttendre la sync NVD (plusieurs heures)

L'endpoint /api/version répond sans authentification et confirme d'un coup trois choses : l'apiserver est démarré, la base répond, et le frontend vise la bonne adresse si vous obtenez le même résultat depuis le navigateur.

Fenêtre de terminal
# Vérifier l'état des services
docker compose ps
# Logs de l'API server
docker compose logs -f dtrack-apiserver
# Vérifier la version
curl -s http://localhost:8081/api/version | jq .
# Vérifier la santé
curl -s http://localhost:8081/api/v1/health | jq .
# Statistiques de la base
curl -s "http://localhost:8081/api/v1/metrics/portfolio/current" \
-H "X-Api-Key: $API_KEY" | jq .

Un point domine tous les autres : Dependency-Track ne vous protège que des vulnérabilités portant sur des composants effectivement inventoriés et correctement identifiés par leur PURL. Ce qui n'apparaît pas dans le SBOM n'existe pas pour l'outil, et un tableau de bord vert reflète alors la qualité de vos SBOM avant de refléter votre sécurité.

  1. Dependency-Track centralise l'analyse des SBOM de tous vos projets et corrèle en continu avec les bases de vulnérabilités
  2. Utilisez PostgreSQL (H2 déprécié depuis v4.13) et obtenez une clé API NVD gratuite pour accélérer la synchronisation
  3. Les API keys sont hachées depuis v4.13 : sauvegardez-les immédiatement après génération
  4. L'upload est asynchrone : utilisez le token retourné pour vérifier le statut de traitement
  5. Configurez des notifications pour être alerté des nouvelles vulnérabilités critiques
  6. Créez des politiques pour détecter automatiquement les composants non conformes
  7. Collection Projects (v4.13+) permet d'organiser et d'agréger les métriques de plusieurs projets
  8. Intégrez dans votre CI/CD : générez les SBOM avec Trivy/Syft et uploadez automatiquement

Deux directions prolongent utilement cette mise en place. En amont, améliorer la qualité des SBOM produits par Trivy ou Grype, puisque c'est elle qui borne tout ce que l'outil peut détecter. En aval, réduire le flux d'alertes à la source avec Renovate, qui met à jour les dépendances avant que les CVE ne remontent dans le tableau de bord.

La documentation officielle fait référence sur deux sujets que ce guide ne couvre pas en détail : la liste exhaustive des endpoints REST, indispensable dès que vous automatisez au-delà de l'upload, et les notes de version, qui signalent les changements de comportement entre deux versions mineures.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn