Integre CI y Dependency-Track

Este documento explica cómo habilitar y configurar las dos características de calidad/seguridad de gitrust:

  1. El CI integrado (Dagger) que ejecuta las compilaciones/pruebas/lints en cada inserción.
  2. El rastreador de dependencias (Syft + Dependency-Track) que escanea los componentes del código con cada inserción y detecta vulnerabilidades conocidas.

Estos dos sistemas son independientes: uno se puede activar sin el otro.


1. Arquitectura general

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

Tres componentes operan en paralelo:

  • CiWorker: Tarea de Tokio que consume CiTask de un canal mpsc, limitada por un Semaphore a canalizaciones simultáneas CI_MAX_CONCURRENT.
  • SbomService: ejecutado en un tokio::spawn después de cada push, totalmente desacoplado del CI.
  • Servidor de compilación: máquina remota (o localhost) que ejecuta Docker + Dagger. Gitrust envía el espacio de trabajo allí mediante rsync y lanza Dagger mediante SSH.

2. Configurar el CI

2.1 Requisitos previos del servidor de compilación

El servidor de compilación puede ser la misma máquina que Gitrust (CI_REMOTE_HOST=localhost) o una máquina dedicada. Debe tener:

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

Instalación automática recomendada:

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

El script se ejecuta:

  1. Comprobando la conectividad SSH
  2. Instalación de Docker si está ausente
  3. Instalación de Dagger CLI si no está presente
  4. Creando el directorio de trabajo remoto
  5. Sincronización del ci-motor
  6. Prueba de humo (versiones)

2.2 Configuración de Gitrust (archivo .env)

Agregue al .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

Reinicie Gitrust: systemctl restart gitrust (o cargo run --release).

2.3 Activar CI en un repositorio

En la interfaz web: vaya al repositorio → ConfiguraciónCI.

  • Marque CI habilitado (obligatorio; predeterminado: "falso")
  • Marque Disparador al presionar (activa la ejecución en cada presión)
  • Opcional: Cancelación automática (cancela las canalizaciones actuales cuando comienza una nueva)
  • Opcional: Ramas permitidas (por ejemplo, principal,desarrollo — vacía = todas)

2.4 Elegir modo: Fácil o Poderoso

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

Modo fácil (recomendado para comenzar)

Cree .gitrust-ci.yml en la raíz del repositorio:

# 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"

Los perfiles disponibles se encuentran en deployment/ci-engine/profiles/ (rust.yaml, python.yaml, node.yaml) en el repositorio de origen.

Modo de energía

Para usuarios avanzados, cree un módulo Dagger completo en .dagger/:

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

La función ci del módulo se llama directamente:

dagger call -m .dagger/ ci

Ventaja: acceso a Daggerverse, composición, pruebas de canalización. Consulte la [documentación de Dagger] (https://docs.dagger.io/).

2.5 Monitoreo de una tubería

Después de un git push, aparece una entrada en la pestaña CI del repositorio:

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 --> [*]

Los registros stdout/stderr se transmiten línea por línea en la tabla ci_logs y son visibles en vivo en la interfaz de usuario. Si falla, se envía una notificación al propietario del repositorio.


3. Configure el rastreador de dependencias

Esta parte es completamente independiente del CI. Escanea el código enviado y produce un SBOM CycloneDX, luego (opcionalmente) lo envía a Dependency-Track para escanear vulnerabilidades.

3.1 Instalar Syft

En la máquina Gitrust (el escaneo se realiza localmente, no en el constructor):

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

# Vérification
syft --version

En .env:

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

En esta etapa: con cada pulsación, se genera y almacena un SBOM CycloneDX (sin carga externa). Visible en la pestaña Seguridad del repositorio: número de componentes, sha256 de la BOM.

3.2 Implementar seguimiento de dependencia

Dependency-Track es una aplicación Java que almacena SBOM y se correlaciona con bases de datos CVE/OSV/NVD. Implementación de Docker recomendada:

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 Crear una clave API

En Dependency-Track → AdministraciónGestión de accesoEquipos:

  1. Cree (o reutilice) un equipo "gitrust".
  2. Dale permisos:
  3. BOM_UPLOAD
  4. PROJECT_CREATION_UPLOAD
  5. VER_PORTAFOLIO
  6. VER_VULNERABILIDAD
  7. Genere una clave API y cópiela.

3.4 Configurar Gitrust

Agregar a .env:

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

Reinicie Gitrust. Con cada empujón:

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 Leer los resultados

Pestaña Seguridad del repositorio → Insertar SBOM:

  • Número de componentes detectados
  • Contadores por gravedad: Crítico / Alto / Medio / Bajo
  • Enlace directo al proyecto en Dependency-Track (si se resuelve el UUID)
  • Hash sha256 de BOM (trazabilidad)

Si Dependency-Track tarda más de 30 segundos en analizarse, el estado sigue siendo "procesando": un barrido posterior buscará los resultados.


4. Depuración

Problemas comunes de CI

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

Problemas comunes de SBOM

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

Registros útiles

# 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. Lista de verificación resumida

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