Skip to content

Référence HTTP API

CVE Intelligence Panel expose une API REST JSON sans état sur le serveur Node/Express. L’UI utilise les mêmes endpoints via le proxy Vite en développement (/apilocalhost:3001) et des chemins same-origin en production. Les intégrateurs peuvent appeler l’API depuis des scripts, des portes CI ou des tableaux de bord internes sans charger le client React.

Ce chapitre décrit chaque route publique, la validation des requêtes, les formes de réponse, les codes d’erreur et les limites opérationnelles. Pour des essais interactifs sans serveur actif, utilisez l’onglet API Explorer (mock navigateur). Pour les contrats lisibles par machine, appelez GET /api/openapi.json.

Principes de conception de l’API

L’API suit les conventions courantes : corps JSON, UTF-8, pas de cookies de session (adaptée aux reverse proxy et API gateway), et modes de scan explicites (full vs watch) reflétés dans meta.mode. Chaque scan est indépendant ; le serveur ne persiste ni votre stack ni les résultats sauf si vous stockez les réponses côté client.

Deux préfixes d’URL sont pris en charge :

Préfixe Rôle
/api/* Chemins compatibles avec l’UI livrée
/api/v1/* Surface versionnée (mêmes handlers, stable pour l’intégration)

Les nouvelles intégrations devraient préférer /api/v1 et traiter /api comme alias pendant la transition.

Découverte et métadonnées

Avant un scan, les clients appellent généralement les endpoints de découverte pour connaître les limites, les sources disponibles et la configuration runtime.

Santé — GET /api/health (aussi /api/v1/health)

Retourne la liveness plus des indicateurs non secrets. À utiliser pour les health checks de load balancer et les sondes de démarrage.

Champs de réponse (résumé) :

Champ Signification
ok Toujours true lorsque le processus tourne
version Semver de l’app depuis package.json (ex. 1.1.0)
sources IDs des flux intégrés
nvdApiKey / githubToken Si les identifiants env sont définis (pas les valeurs)
scanDays Fenêtre look-back depuis SCAN_DAYS (défaut 60)
translate Si la traduction côté serveur est autorisée
limits Plafonds numériques (taille stack, tailles de batch)

Detailed probe: GET /api/health?detailed=true — uptime, reachability par source, cache, air-gap, alerts.webhookConfigured (toute chaîne de notification), alerts.minSeverity.

Prometheus metrics — GET /metrics

Chemin racine (hors /api). METRICS_ENABLED=true par défaut ; METRICS_PROTECT=true exige API_SECRET. Voir Self-hosted metrics.

Capabilities — GET /api/capabilities

Retourne les limites produit et feature flags structurés (max outils par scan, locales de traduction, modes de scan). Préférez ceci à l’analyse de health pour construire des formulaires ou validateurs CI.

Catalogue des sources — GET /api/sources

Retourne le registre des sources intégrées (NVD, OSV, GitHub, CISA KEV, flux RSS) avec kind, fullScan, watchScan, plus les URL RSS par défaut. Les flux personnalisés ne sont pas listés ici ; les clients les fournissent par requête via customFeeds.

OpenAPI — GET /api/openapi.json

Sert le document OpenAPI 3.1 (server/openapi/spec.json) pour codegen, import Postman ou tests de contrat.

Validation des requêtes et erreurs

Tous les corps POST doivent être des objets JSON. Les échecs de validation renvoient HTTP 400 :

{
  "error": "Human-readable message",
  "code": "VALIDATION_ERROR",
  "details": { "max": 50, "received": 72 }
}

Les échecs upstream (rate limit NVD, timeout RSS) renvoient 502 ou 429 avec texte error et code optionnel (SCAN_FAILED, WATCH_FAILED). L’UI affiche error comme chaîne ; les intégrateurs peuvent aussi lire code et details.

Limite de débit applicative (middleware) : lorsqu’un client dépasse les quotas scan ou veille par IP, le serveur renvoie HTTP 429 :

{
  "error": "Too many scan requests. Try again later.",
  "code": "RATE_LIMITED",
  "retryAfterSec": 42
}
  • POST /scan et POST /watch utilisent des buckets séparés par minute.
  • POST /scan/validate est exempt (sûr pour CI et vérification de pile).
  • Régler via RATE_LIMIT_SCAN_PER_MIN et RATE_LIMIT_WATCH_PER_MIN dans .env.

API key / RBAC (v1): avec API_SECRET, routes protégées + rôles sur /api/v1/* (API_ROLE, 403 si rôle insuffisant). En-tête X-Tenant-Id avec PostgreSQL.

Règles de stack :

  • stack — tableau obligatoire non vide de noms d’outils (trim), max 50 outils.
  • customFeeds — optionnel, max 20 entrées ; chaque entrée requiert id et url.
  • enabledBuiltin — carte optionnelle source ID → boolean ; clés absentes activées par défaut.

Validation sans scan — POST /api/scan/validate

Valide stack, enabledBuiltin et customFeeds sans appeler les fournisseurs CVE externes. À utiliser dans les assistants ou CI pour rejeter une entrée invalide avant un full scan coûteux.

Exemple de requête :

{
  "stack": ["Redis", "HAProxy"],
  "enabledBuiltin": { "NVD": true, "TuxCare": false },
  "customFeeds": [{ "id": "custom:team-feed", "name": "Team RSS", "url": "https://example.com/cve.rss" }]
}

Exemple de réponse :

{
  "valid": true,
  "stack": ["Redis", "HAProxy"],
  "toolCount": 2,
  "customFeedCount": 1,
  "message": "Stack and source options are valid; run POST /api/scan for findings."
}

Scan complet — POST /api/scan

Exécute un scan complet : NVD, OSV, GitHub Advisories, CISA KEV, RSS intégrés et flux RSS personnalisés activés. Les résultats sont fusionnés par ID CVE, enrichis des flags KEV, traduits optionnellement, puis renvoyés en une seule charge.

Corps de requête :

Champ Type Requis Description
stack string[] oui Noms d’outils à matcher
translate boolean non Si true, traduire titres/descriptions
locale fa | ar | ru | zh | fr non Langue cible si translate: true
enabledBuiltin object non Bascules par source
customFeeds array non Flux RSS/Atom supplémentaires (IDs custom:…)

Exemple :

{
  "stack": ["Redis", "HAProxy", "Kubernetes"],
  "translate": true,
  "locale": "fr",
  "enabledBuiltin": { "NVD": true, "TheHackerNews": true }
}

Réponse : ScanResponsevulns[], summary, search_date, meta (sources_checked, sources_updated_at, duration_ms, mode: "full").

Chaque vulnérabilité inclut id, tool, title, severity, optionnellement affected_versions, fixed_version, sources[], url, patch_available, exploited_in_wild, optionnellement epss (0–1) et riskScore (0–10) si EPSS est activé, cwe[] et compliance_controls[] si la conformité est activée, et translations / title_fa si enrichi.

Séquence de scan (vue intégrateur)

sequenceDiagram
  participant Client
  participant API as Express API
  participant Feeds as Flux externes

  Client->>API: POST /api/scan { stack, translate, locale }
  API->>Feeds: NVD/OSV/GitHub/KEV/RSS en parallèle
  Feeds-->>API: Résultats bruts
  API->>API: Fusion, enrichissement KEV, traduction opt.
  API-->>Client: 200 { vulns, summary, meta }

Description du diagramme

Le client envoie une charge JSON unique. Le serveur distribue vers les sources configurées, normalise les enregistrements en forme de vulnérabilité commune, déduplique par ID CVE et applique une traduction optionnelle sur les N premiers éléments (contrôlé par TRANSLATE_MAX_ITEMS). La réponse inclut des métadonnées de timing pour afficher la progression ou auditer les SLA.

Déroulement pas à pas

  1. Appelez GET /api/capabilities pour lire maxStackTools et translateLocales.
  2. Optionnellement POST /api/scan/validate avec le même corps que le scan prévu.
  3. POST /api/scan avec stack et options de sources.
  4. Stockez vulns et meta.sources_updated_at si vous avez besoin de badges UI incrémentaux.
  5. Sur 429, augmentez le backoff et réduisez la fréquence des scans lourds en NVD.

Watch — POST /api/watch

Exécute le mode watch : OSV, GitHub, KEV et RSS sans NVD pour une latence moindre. Le corps correspond au scan plus knownIds optionnel (IDs CVE déjà vus). La réponse ajoute newVulns et hasNew pour les pipelines d’alerte.

Exemple :

{
  "stack": ["Redis"],
  "knownIds": ["CVE-2024-1234", "CVE-2023-9999"],
  "translate": false
}

Réponse : comme scan plus newVulns[], hasNew: boolean, meta.mode: "watch".

Lorsque newVulns est non vide et que les variables de notification sont définies, le serveur envoie les canaux configurés via NotificationService (sans affecter la réponse JSON).

Translate — POST /api/translate

Traduit par lot les champs anglais title / description vers une locale UI via MyMemory / LibreTranslate / Ollama (voir Configuration). Utilisé quand la langue UI change après un scan ou pour des éléments au-delà des limites de traduction serveur lors du scan.

Requête :

{
  "locale": "fr",
  "items": [
    {
      "id": "CVE-2024-1",
      "tool": "Redis",
      "title": "Heap buffer overflow",
      "description": "…"
    }
  ]
}

Réponse : { "locale": "fr", "items": [{ "id", "tool", "title", "description" }] }
Max éléments par requête : TRANSLATE_BATCH_MAX (défaut 40).

Versioned API (/api/v1 only)

POST /api/v1/scan/stream (SSE), historique/tendances scans, tenants/stacks CRUD, GET /api/v1/discovery/kubernetes. Détails : chapitre EN.

Résumé des endpoints

Méthode Chemin Description
GET /api/health Liveness + flags (?detailed=true)
GET /metrics Métriques Prometheus
GET /api/capabilities Limites et fonctionnalités
GET /api/sources Catalogue sources intégrées
GET /api/openapi.json Spécification OpenAPI 3.1
POST /api/scan/validate Validation stack/sources uniquement
POST /api/scan Scan complet
POST /api/watch Poll watch + diff
POST /api/translate Traduction par lot
POST /api/v1/scan/stream Scan SSE (v1)
GET /api/v1/scans/history Historique tenant
GET/POST /api/v1/tenants/stacks Stacks enregistrées
GET /api/v1/discovery/kubernetes Découverte K8s

Alias /api/* pour scan/metadata de base ; routes v1-only listées ci-dessus.

Sécurité et déploiement

L’API est prévue pour des réseaux de confiance. Auth optionnelle : API_SECRET côté serveur ; les clients envoient X-Api-Key ou Authorization: Bearer. GET /api/health et GET /api/v1/health restent ouverts pour les sondes. Ne pas exposer sans TLS sur Internet public. Définissez NVD_API_KEY pour un débit plus élevé.

Chapitres associés

Essayez les requêtes dans l’onglet API Explorer.