Intégrer la CI et Dependency-Track
Ce document explique comment activer et configurer les deux fonctionnalités de qualité/sécurité de gitrust :
- La CI intégrée (Dagger) qui exécute les builds/tests/lints à chaque push.
- 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
CiTaskdepuis un channelmpsc, limitée par unSemaphoreàCI_MAX_CONCURRENTpipelines simultanés. - SbomService : exécuté dans un
tokio::spawnaprè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 :
| Outil | Rôle |
|---|---|
| Docker ou Podman | Containers Dagger |
| Dagger CLI | Moteur d'exécution |
| SSH (accès sortant depuis Gitrust) | Transport |
| rsync | Copie du workspace |
| git, tar | Extraction 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 :
- Vérification de la connectivité SSH
- Installation de Docker si absent
- Installation de Dagger CLI si absent
- Création du répertoire de travail distant
- Synchronisation du
ci-engine - 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 → Settings → CI.
- 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 → Administration → Access Management → Teams :
- Créer (ou réutiliser) une équipe
gitrust. - Lui attribuer les permissions :
BOM_UPLOADPROJECT_CREATION_UPLOADVIEW_PORTFOLIOVIEW_VULNERABILITY
- 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ôme | Cause probable | Vérifier |
|---|---|---|
Pipeline reste pending | Worker non démarré, ou channel saturé | Logs CI worker started, CI_MAX_CONCURRENT |
Échec rsync vers le serveur de build | SSH bloqué, clé absente | ssh -p ${CI_REMOTE_SSH_PORT} ${CI_REMOTE_USER}@${CI_REMOTE_HOST} manuel |
dagger: command not found | Dagger non installé sur le builder | Relancer setup-remote-ci.sh |
Status Cancelled inattendu | Timeout (CI_DEFAULT_TIMEOUT) ou auto-cancel | Augmenter le timeout, vérifier pipelines concurrents |
Problèmes SBOM courants
| Symptôme | Cause probable | Vérifier |
|---|---|---|
SBOM generation disabled | CI_SBOM_ENABLED=false | .env |
syft spawn failed | Binaire introuvable | which syft, CI_SYFT_BIN |
invalid commit sha | SHA non hex 40 chars | Rare, signale un bug |
Dtrack upload 401 | API key invalide ou permissions manquantes | Régénérer, vérifier les 4 permissions |
Status processing indéfiniment | Dtrack surchargé, analyse lente | Attendre, 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=trueetCI_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=truedans.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_KEYdans.env - Gitrust redémarré
- Push → SBOM visible dans l'onglet Security
GitRust