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
tokio task]
Sbom[SbomService
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
poussé] --> Tree{Arbre du
commit contient ?}
Tree -->|.dagger/| Power[Mode Power
dagger call -m .dagger/ ci]
Tree -->|.gitrust-ci.yml| Easy[Mode Easy
dagger call -m ci-engine test-pr]
Tree -->|rien| None[Pas de pipeline]
Power --> Run[Exécution
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/ :
La fonction ci du module est appelée directement :
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 :
À 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
+ 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=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