integrer-dependency-track.md 10979 octets

Intégrer la CI et Dependency-Track

Ce document explique comment activer et configurer les deux fonctionnalités de qualité/sécurité de gitrust :

  1. La CI intégrée (Dagger) qui exécute les builds/tests/lints à chaque push.
  2. Le dependency tracker (Syft + Dependency-Track) qui scanne les composants du code à chaque push et détecte les vulnérabilités connues.

Ces deux systèmes sont indépendants : on peut activer l'un sans l'autre.


1. Architecture générale

flowchart TB
  subgraph Client
    Dev[Développeur]
  end
  subgraph Gitrust[Instance Gitrust]
    HTTP[:4000 HTTP/Git]
    SSH[:2222 SSH/Git]
    Worker[CiWorker<br/>tokio task]
    Sbom[SbomService<br/>tokio spawn]
    DB[(PostgreSQL)]
  end
  subgraph Builder[Serveur de build]
    Docker[Docker/Podman]
    Dagger[Dagger CLI]
    CiEngine[/opt/gitrust-ci/ci-engine/]
  end
  subgraph Security[Stack sécurité optionnelle]
    Syft[syft]
    Dtrack[Dependency-Track]
  end

  Dev -->|git push| HTTP
  Dev -->|git push| SSH
  HTTP --> Worker
  SSH --> Worker
  HTTP --> Sbom
  SSH --> Sbom
  Worker -->|SSH + rsync| Builder
  Builder -->|logs streamés| Worker
  Worker --> DB
  Sbom -->|scan workspace| Syft
  Sbom -->|PUT BOM| Dtrack
  Dtrack -->|findings| Sbom
  Sbom --> DB

Trois composants fonctionnent en parallèle :

  • CiWorker : tâche Tokio qui consomme des CiTask depuis un channel mpsc, limitée par un Semaphore à CI_MAX_CONCURRENT pipelines simultanés.
  • SbomService : exécuté dans un tokio::spawn après chaque push, totalement découplé du CI.
  • Serveur de build : machine distante (ou localhost) qui exécute Docker + Dagger. Gitrust y envoie le workspace par rsync et lance Dagger par SSH.

2. Mettre en place la CI

2.1 Pré-requis serveur de build

Le serveur de build peut être la même machine que Gitrust (CI_REMOTE_HOST=localhost) ou une machine dédiée. Il doit disposer de :

OutilRôle
Docker ou PodmanContainers Dagger
Dagger CLIMoteur d'exécution
SSH (accès sortant depuis Gitrust)Transport
rsyncCopie du workspace
git, tarExtraction du tree du commit

Installation automatique recommandée :

# Depuis la machine Gitrust (l'utilisateur doit pouvoir SSH vers le builder)
./deployment/setup-remote-ci.sh .env

Le script exécute :

  1. Vérification de la connectivité SSH
  2. Installation de Docker si absent
  3. Installation de Dagger CLI si absent
  4. Création du répertoire de travail distant
  5. Synchronisation du ci-engine
  6. Smoke test (versions)

2.2 Configuration Gitrust (fichier .env)

Ajouter au .env de Gitrust :

# Activer globalement le CI
CI_ENABLED=true

# Chemin du ci-engine sur le serveur de build
CI_ENGINE_PATH=/opt/gitrust-ci/ci-engine

# Limite de parallélisme
CI_MAX_CONCURRENT=4
CI_DEFAULT_TIMEOUT=3600
CI_WORKSPACE_PATH=/tmp/gitrust-ci

# Serveur de build (mettre localhost pour "même machine")
CI_REMOTE_HOST=builder.example.com
CI_REMOTE_USER=ci-runner
CI_REMOTE_PATH=/opt/gitrust-ci
CI_REMOTE_SSH_PORT=22
# CI_REMOTE_SSH_KEY=/home/gitrust/.ssh/id_ed25519   # si pas ssh-agent

Redémarrer Gitrust : systemctl restart gitrust (ou cargo run --release).

2.3 Activer la CI sur un dépôt

Dans l'interface web : aller sur le dépôt → SettingsCI.

  • Cocher CI enabled (requis — par défaut false)
  • Cocher Trigger on push (active l'exécution à chaque push)
  • Optionnel : Auto-cancel (annule les pipelines en cours quand un nouveau démarre)
  • Optionnel : Allowed branches (ex. main,develop — vide = toutes)

2.4 Choisir le mode : Easy ou Power

flowchart LR
  Push[Commit<br/>poussé] --> Tree{Arbre du<br/>commit contient ?}
  Tree -->|.dagger/| Power[Mode Power<br/>dagger call -m .dagger/ ci]
  Tree -->|.gitrust-ci.yml| Easy[Mode Easy<br/>dagger call -m ci-engine test-pr]
  Tree -->|rien| None[Pas de pipeline]
  Power --> Run[Exécution<br/>distante SSH]
  Easy --> Run

Mode Easy (recommandé pour commencer)

Créer .gitrust-ci.yml à la racine du dépôt :

# Raccourci : charge un profil pré-configuré (rust | python | node)
language: rust

build:
  command: "cargo build --release"

checks:
  lint: "cargo clippy -- -D warnings"
  format: "cargo fmt -- --check"

tests:
  command: "cargo test --release"

Les profils disponibles se trouvent dans deployment/ci-engine/profiles/ (rust.yaml, python.yaml, node.yaml) dans le dépôt source.

Mode Power

Pour les utilisateurs avancés, créer un module Dagger complet dans .dagger/ :

.dagger/
├── dagger.json
├── src/
│   └── main.py         # ou Go/TypeScript

La fonction ci du module est appelée directement :

dagger call -m .dagger/ ci

Avantage : accès au Daggerverse, composition, tests de pipeline. Voir la documentation Dagger.

2.5 Suivi d'un pipeline

Après un git push, une entrée apparaît dans l'onglet CI du dépôt :

stateDiagram-v2
  [*] --> Pending: create_pipeline
  Pending --> Running: worker picks CiTask
  Running --> Success: exit 0
  Running --> Failure: exit != 0
  Running --> Cancelled: timeout / auto_cancel / manuel
  Success --> [*]
  Failure --> [*]
  Cancelled --> [*]

Les logs stdout/stderr sont streamés ligne par ligne dans la table ci_logs et visibles en direct dans l'UI. En cas d'échec, une notification est envoyée au propriétaire du dépôt.


3. Mettre en place le Dependency Tracker

Cette partie est totalement indépendante de la CI. Elle scanne le code poussé et produit un SBOM CycloneDX, puis (optionnellement) l'envoie à Dependency-Track pour une analyse de vulnérabilités.

3.1 Installer Syft

Sur la machine Gitrust (le scan se fait localement, pas sur le builder) :

# Installation officielle
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh \
  | sh -s -- -b /usr/local/bin

# Vérification
syft --version

Dans .env :

CI_SBOM_ENABLED=true
CI_SYFT_BIN=/usr/local/bin/syft   # optionnel, défaut: syft dans PATH

À ce stade : à chaque push, un SBOM CycloneDX est généré et stocké (sans upload externe). Visible dans l'onglet Security du dépôt : nombre de composants, sha256 du BOM.

3.2 Déployer Dependency-Track

Dependency-Track est une application Java qui stocke les SBOM et corrèle avec les bases CVE/OSV/NVD. Déploiement Docker recommandé :

mkdir -p /opt/dtrack && cd /opt/dtrack
curl -L -o docker-compose.yml \
  https://dependencytrack.org/docker-compose.yml
docker compose up -d

L'API est disponible sur http://localhost:8081 et l'UI sur http://localhost:8080. Login initial : admin / admin (à changer immédiatement).

3.3 Créer une clé API

Dans Dependency-Track → AdministrationAccess ManagementTeams :

  1. Créer (ou réutiliser) une équipe gitrust.
  2. Lui attribuer les permissions :
    • BOM_UPLOAD
    • PROJECT_CREATION_UPLOAD
    • VIEW_PORTFOLIO
    • VIEW_VULNERABILITY
  3. Générer une API key et la copier.

3.4 Configurer Gitrust

Ajouter au .env :

CI_DTRACK_ENABLED=true
CI_DTRACK_URL=http://localhost:8081
CI_DTRACK_API_KEY=odt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Redémarrer Gitrust. À chaque push :

sequenceDiagram
  participant Push as post-receive
  participant Sbom as SbomService
  participant Git as git archive
  participant Syft
  participant Dtrack as Dependency-Track
  participant DB as sbom_reports

  Push->>Sbom: process_push(sha, ref)
  Sbom->>DB: upsert status=pending
  Sbom->>Git: archive sha | tar -x tmpdir
  Sbom->>Syft: scan dir:tmpdir -o cyclonedx-json
  Syft-->>Sbom: BOM bytes
  Sbom->>DB: update sha256
  Sbom->>Dtrack: PUT /api/v1/bom (base64)
  Dtrack-->>Sbom: token
  loop max 30s
    Sbom->>Dtrack: GET /api/v1/bom/token/{token}
    Dtrack-->>Sbom: processing ?
  end
  Sbom->>Dtrack: GET /api/v1/finding/project/{uuid}
  Dtrack-->>Sbom: findings[]
  Sbom->>DB: update status=success<br/>+ critical/high/medium/low

3.5 Lire les résultats

Onglet Security du dépôt → encart SBOM :

  • Nombre de composants détectés
  • Compteurs par sévérité : Critical / High / Medium / Low
  • Lien direct vers le projet dans Dependency-Track (si l'UUID est résolu)
  • Hash sha256 du BOM (traçabilité)

Si Dependency-Track met plus de 30s à analyser, le status reste processing — un sweeper ultérieur ira rechercher les findings.


4. Débogage

Problèmes CI courants

SymptômeCause probableVérifier
Pipeline reste pendingWorker non démarré, ou channel saturéLogs CI worker started, CI_MAX_CONCURRENT
Échec rsync vers le serveur de buildSSH bloqué, clé absentessh -p ${CI_REMOTE_SSH_PORT} ${CI_REMOTE_USER}@${CI_REMOTE_HOST} manuel
dagger: command not foundDagger non installé sur le builderRelancer setup-remote-ci.sh
Status Cancelled inattenduTimeout (CI_DEFAULT_TIMEOUT) ou auto-cancelAugmenter le timeout, vérifier pipelines concurrents

Problèmes SBOM courants

SymptômeCause probableVérifier
SBOM generation disabledCI_SBOM_ENABLED=false.env
syft spawn failedBinaire introuvablewhich syft, CI_SYFT_BIN
invalid commit shaSHA non hex 40 charsRare, signale un bug
Dtrack upload 401API key invalide ou permissions manquantesRégénérer, vérifier les 4 permissions
Status processing indéfinimentDtrack surchargé, analyse lenteAttendre, ou relancer un push

Logs utiles

# Logs Gitrust (systemd)
journalctl -u gitrust -f | grep -E "CI|SBOM|sbom|pipeline"

# Vérifier un pipeline en DB
psql $DATABASE_URL -c "SELECT id, status, commit_sha, created_at FROM ci_pipelines ORDER BY created_at DESC LIMIT 10;"

# Vérifier un SBOM
psql $DATABASE_URL -c "SELECT commit_sha, status, components_count, critical_count, high_count FROM sbom_reports ORDER BY created_at DESC LIMIT 10;"

5. Checklist récapitulative

CI :

  • Docker + Dagger installés sur le serveur de build (setup-remote-ci.sh)
  • CI_ENABLED=true et CI_REMOTE_* dans .env
  • Gitrust redémarré
  • CI activée dans Settings → CI pour chaque dépôt
  • Fichier .gitrust-ci.yml (Easy) ou .dagger/ (Power) commité
  • Push → pipeline visible dans l'onglet CI

Dependency Tracker :

  • Syft installé sur la machine Gitrust
  • CI_SBOM_ENABLED=true dans .env
  • (Optionnel) Dependency-Track déployé + API key créée avec les 4 permissions
  • (Optionnel) CI_DTRACK_ENABLED=true, CI_DTRACK_URL, CI_DTRACK_API_KEY dans .env
  • Gitrust redémarré
  • Push → SBOM visible dans l'onglet Security