Activer le dual-scan (contre-vérification Trivy)¶
Le dual-scan exécute Trivy comme second moteur de vulnérabilités
indépendant sur les paquets déjà publiés par Grype, afin de mettre en
évidence ce que le scan initial de Grype aurait manqué. Ce guide couvre son
activation et la lecture de ses résultats — pour comprendre pourquoi il
existe comme un balayage périodique séparé plutôt que comme un second scan
bloquant au moment de l'upload, voir la docstring du module
services/dual_scan.py, résumée ci-dessous.
SaaS uniquement
Le dual-scan n'est disponible que dans Repod SaaS. Il nécessite le
conteneur sidecar depot-trivy, qui n'existe que dans
docker-compose.saas.yml — il n'existe pas d'overlay équivalent pour
l'EE on-premise ou la CE, et la fonctionnalité n'a aucun effet si elle
est activée ailleurs. services/dual_scan.py:is_enabled() vérifie
d'abord DEPLOYMENT_MODE=saas et renvoie False de façon
inconditionnelle sinon, quoi que dise settings.json.
1. Prérequis¶
- Le mode de déploiement doit être
saas(DEPLOYMENT_MODE=saas), avec le servicedepot-trivyen cours d'exécution (docker-compose.saas.ymlle démarre automatiquement — pas de script de configuration séparé). - Le rôle
admin, pour modifiersettings.json["dual_scan"]. - La fonctionnalité de licence
dual_scandoit être incluse dans le plan du tenant (voirPLANSdansservices/tenant_manager.py).
2. Ce que ça fait — et ne fait pas¶
- Trivy ne s'exécute jamais dans le chemin d'upload/import. Grype seul
continue de décider accepter /
pending_review/ bloquer au moment de l'upload — inchangé. Exécuter deux scans complets de façon synchrone par upload doublerait la latence d'upload sans bénéfice. - Trivy ne s'exécute que dans un balayage périodique en arrière-plan (cron
dual_scan_daily) sur les paquets déjà àstatus = "validated"— deb, rpm, apk, artefacts Maven, PyPI et npm (OCI est exclu ; ses images sont déjà scannées intégralement par Grype viaoci-dir:, il n'y a donc pas d'écart équivalent propre à Trivy pour lui). - Chaque CVE dans le
cve_resultsd'un paquet scanné gagne un champdetected_by:["grype"],["trivy"], ou["grype", "trivy"]. Les résultats de Grype ne sont jamais écartés ni écrasés. - Seule une CVE avec
detected_by == ["trivy"]— une information réellement nouvelle que Grype a manquée — peut changer le sort d'un paquet. Une CVE que les deux moteurs reconnaissent déjà ne redéclenche jamais une décision, même si elle est Critical. - Un résultat
["trivy"]uniquement qui enfreintcve_policyfait basculer le paquet àpending_reviewet l'achemine vers la même file de décision RSSI que toute autre décision CVE (POST /security/packages/{name}/{version}/decide) — aucun nouveau mécanisme de revue.blockest ici rétrogradé enreview, jamais un rejet pur et simple à nouveau : une correspondance Trivy uniquement est basée sur le nom/la version et plus bruitée que les résultats propres à Grype, donc bloquer strictement un paquet déjà publié sur cette base serait disproportionné.
3. L'activer¶
curl -s -X PATCH http://localhost:8000/api/v1/settings/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"dual_scan": {
"enabled": true,
"hour": 5,
"minute": 15,
"max_artifacts_per_run": 50,
"max_runtime_minutes": 30
}
}'
| Champ | Défaut | Signification |
|---|---|---|
enabled |
false |
Doit être explicitement mis à true — opt-in, même convention que mirror/backup/drift. |
hour / minute |
5 / 15 |
Heure UTC à laquelle s'exécute le job cron dual_scan_daily. |
max_artifacts_per_run |
50 |
Plafonne le nombre de paquets validated re-scannés par exécution, les plus anciennement re-scannés en premier. |
max_runtime_minutes |
30 |
Le balayage arrête de prendre en charge de nouveaux artefacts au-delà de ce budget en temps réel, même si le plafond d'artefacts n'a pas été atteint. |
Confirmer que la planification a bien pris effet :
4. Lire detected_by sur la page Sécurité¶
Ouvrez la vue de détail des CVE d'un paquet (page Sécurité → paquet → liste des CVE). Chaque ligne de CVE porte un petit badge une fois qu'elle est passée par un cycle de dual-scan :
- « Grype + Trivy » (gris, discret) — les deux moteurs ont trouvé cette CVE indépendamment. C'est une confirmation, pas une information nouvelle — délibérément stylisé comme le badge le moins accrocheur.
- « Trivy uniquement » (violet) — trouvée uniquement par le scan de
seconde opinion, absente du résultat initial de Grype. C'est le signal
actionnable : c'est ce qui déclenche une réévaluation de la politique et,
si c'est suffisamment sévère au regard de
cve_policy, un étatpending_review.
Un paquet jamais touché par un dual-scan (pas encore atteint par le
balayage, ou fonctionnalité désactivée au moment de sa publication)
n'affiche aucun champ detected_by et aucun badge — c'est attendu, pas une
erreur, pour tout paquet publié avant l'activation du dual-scan ou encore
en attente de son tour dans le balayage.
La sortie brute de Trivy et l'horodatage du dernier scan sont conservés
séparément sur le manifeste (trivy_scan.matches, trivy_scan.scanned_at)
à des fins d'audit, aux côtés de trivy_scan.divergent_cve_ids — la liste
exacte des identifiants CVE qui étaient Trivy-uniquement lors du dernier
passage.
5. Exemple détaillé¶
- Un
.debest uploadé et publié normalement — Grype ne trouve rien au-dessus du seuil decve_policyconfiguré, le paquet passe envalidated. - Le lendemain, la base de données de vulnérabilités Trivy récupère une CVE pour l'une des bibliothèques embarquées du paquet que la base de Grype n'a pas encore appariée.
- À
05:15UTC,dual_scan_dailyatteint ce paquet dans son balayage (en supposant qu'il soit dans les limites demax_artifacts_per_runpour cette exécution — les paquets les plus anciens et non scannés depuis longtemps sont priorisés). - Trivy rapporte la CVE ; elle est absente du
cve_resultsexistant du paquet, elle atterrit donc danstrivy_only. - Si la sévérité de la CVE correspond à
reviewoublockdanscve_policy, le paquet bascule enpending_review, une étape de validationdual_scanest ajoutée au manifeste, et une entrée de journal d'audit (DUAL_SCAN,PENDING_REVIEW) est écrite. - Le paquet apparaît désormais dans la file de revue RSSI exactement
comme tout paquet
pending_reviewau moment de l'upload, avec un badge["trivy"]uniquement sur la CVE signalée dans la page Sécurité.
Vérifier que ça a fonctionné¶
GET /settings/affichedual_scan.enabled: trueavec la planification que vous avez définie.- Attendez (ou déclenchez manuellement, via une fenêtre de maintenance) la
prochaine exécution de
dual_scan_daily, puis vérifiez les logs backend : - Choisissez un paquet qui était
validatedavant l'exécution du balayage et confirmez que son instantané de manifeste possède désormais une sectiontrivy_scan: - Si Trivy était injoignable pendant une exécution, le manifeste obtient
trivy_scan.error = "trivy indisponible"etcve_resultsreste inchangé — c'est le chemin fail-soft, pas un bug : l'indisponibilité temporaire d'un second moteur ne bloque ni ne corrompt jamais le résultat existant basé sur Grype.