Integre CI e Dependency-Track

Este documento explica como habilitar e configurar os dois recursos de qualidade/segurança do gitrust:

  1. O CI integrado (Dagger) que executa as compilações/testes/lints em cada push.
  2. O rastreador de dependência (Syft + Dependency-Track) que verifica os componentes do código a cada push e detecta vulnerabilidades conhecidas.

Esses dois sistemas são independentes: um pode ser ativado sem o outro.


1. Arquitetura geral

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

Três componentes operam em paralelo:

  • CiWorker: tarefa Tokio que consome CiTask de um canal mpsc, limitado por um Semaphore para pipelines simultâneos CI_MAX_CONCURRENT.
  • SbomService: executado em um tokio::spawn após cada push, totalmente desacoplado do CI.
  • Servidor de compilação: máquina remota (ou localhost) que executa Docker + Dagger. Gitrust envia o espaço de trabalho para lá por rsync e inicia o Dagger por SSH.

2. Configure o CI

2.1 Pré-requisitos do servidor de construção

O servidor de compilação pode ser a mesma máquina do Gitrust (CI_REMOTE_HOST=localhost) ou uma máquina dedicada. Ele deve ter:

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

Instalação automática recomendada:

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

O script executa:

  1. Verificando a conectividade SSH
  2. Instalando o Docker se estiver ausente
  3. Instalando o Dagger CLI se ausente
  4. Criando o diretório de trabalho remoto
  5. Sincronização do ci-engine
  6. Teste de fumaça (versões)

2.2 Configuração Gitrust (arquivo .env)

Adicione ao .env do 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 o Gitrust: systemctl restart gitrust (ou cargo run --release).

2.3 Ativar CI em um repositório

Na interface web: acesse o repositório → ConfiguraçõesCI.

  • Marque CI ativado (obrigatório — padrão false)
  • Marque Trigger on push (ativa a execução em cada push)
  • Opcional: Cancelamento automático (cancela os pipelines atuais quando um novo é iniciado)
  • Opcional: Branch permitidos (por exemplo, main,develop — vazio = todos)

2.4 Escolha o modo: Fácil 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

Modo fácil (recomendado para iniciar)

Crie .gitrust-ci.yml na raiz do repositório:

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

Os perfis disponíveis estão localizados em deployment/ci-engine/profiles/ (rust.yaml, python.yaml, node.yaml) no repositório de origem.

Modo de energia

Para usuários avançados, crie um módulo Dagger completo em .dagger/:

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

A função ci do módulo é chamada diretamente:

dagger call -m .dagger/ ci

Vantagem: acesso ao Daggerverse, composição, testes de pipeline. Consulte a documentação do Dagger.

2.5 Monitorando um pipeline

Após um git push, uma entrada aparece na aba CI do repositório:

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

Os logs stdout/stderr são transmitidos linha por linha na tabela ci_logs e visíveis ao vivo na IU. Se falhar, uma notificação será enviada ao proprietário do repositório.


3. Configure o Rastreador de Dependência

Esta parte é totalmente independente do IC. Ele verifica o código enviado e produz um SBOM CycloneDX e, em seguida, (opcionalmente) o envia para Dependency-Track para verificação de vulnerabilidades.

3.1 Instale o Syft

Na máquina Gitrust (a verificação é feita localmente, não no construtor):

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

# Vérification
syft --version

Em .env:

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

Nesta fase: a cada push, um SBOM CycloneDX é gerado e armazenado (sem upload externo). Visível na aba Segurança do repositório: número de componentes, sha256 da BOM.

3.2 Implantar rastreamento de dependência

Dependency-Track é um aplicativo Java que armazena SBOM e se correlaciona com bancos de dados CVE/OSV/NVD. Implantação recomendada do Docker:

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 Crie uma chave API

Em Dependency-Track → AdministraçãoGerenciamento de acessoEquipes:

  1. Crie (ou reutilize) uma equipe gitrust.
  2. Dê permissões:
  3. BOM_UPLOAD
  4. PROJECT_CREATION_UPLOAD
  5. VER_PORTFÓLIO
  6. VER_VULNERABILIDADE
  7. Gere uma chave de API e copie-a.

3.4 Configurar Gitrust

Adicione a .env:

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

Reinicie o Gitrust. A cada empurrão:

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 Leia os resultados

Aba Segurança do repositório → Inserção do SBOM:

  • Número de componentes detectados
  • Contadores por gravidade: Crítico/Alto/Médio/Baixo
  • Link direto para o projeto no Dependency-Track (se o UUID for resolvido)
  • Hash sha256 da BOM (rastreabilidade)

Se o Dependency-Track levar mais de 30 segundos para analisar, o status permanecerá processando - um varredor subsequente procurará as descobertas.


4. Depuração

Problemas comuns de IC

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 comuns 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 úteis

# 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 verificação 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