Skip to content

Справочник HTTP API

CVE Intelligence Panel предоставляет безсессионный JSON REST API на сервере Node/Express. UI обращается к тем же endpoint'ам через прокси Vite в разработке (/apilocalhost:3001) и по same-origin путям в production. Интеграторы могут вызывать API из скриптов, CI-ворот или внутренних дашбордов без загрузки React-клиента.

Эта глава описывает все публичные маршруты, валидацию запросов, формы ответов, коды ошибок и операционные лимиты. Для интерактивных проб без живого сервера используйте вкладку API Explorer (мок в браузере). Для машиночитаемых контрактов запросите GET /api/openapi.json.

Принципы проектирования API

API следует общепринятым соглашениям: JSON-тела, UTF-8, без session cookie (удобно для reverse proxy и API gateway), и явные режимы сканирования (full vs watch), отражённые в meta.mode. Каждое сканирование независимо; сервер не сохраняет ваш стек или находки, если вы сами не храните ответы на клиенте.

Поддерживаются два префикса URL:

Префикс Назначение
/api/* Пути, совместимые с поставляемым UI
/api/v1/* Версионированная поверхность (те же обработчики, стабильно для интеграций)

Новым интеграциям следует предпочитать /api/v1 и рассматривать /api как alias на период перехода.

Discovery и метаданные

Перед сканированием клиенты обычно вызывают discovery endpoint'ы, чтобы узнать лимиты, доступные источники и runtime-конфигурацию.

Health — GET /api/health (также /api/v1/health)

Возвращает liveness и несекретные флаги возможностей. Используйте для health check балансировщика и startup probe.

Поля ответа (кратко):

Поле Значение
ok Всегда true, когда процесс работает
version Semver приложения из package.json (например 1.1.0)
sources ID встроенных фидов
nvdApiKey / githubToken Заданы ли env-учётные данные (не сами значения)
scanDays Окно look-back из SCAN_DAYS (по умолчанию 60)
translate Разрешён ли серверный перевод
limits Числовые лимиты (размер стека, размеры batch)

Detailed probe: GET /api/health?detailed=true (same on /api/v1/health) adds uptime, per-source reachability, cache size/backend, optional air-gap mirror flags, translation provider, and alert config:

Field Meaning
uptime Process uptime in seconds
sources Object map of source ID → { reachable, lastOkAt, … }
cache { size, backend } — memory or Redis
airgap Present when AIRGAPPED=true — mirror URL health
translation.activeProvider DeepL, LibreTranslate, or GoogleGTX
alerts.webhookConfigured true when any notification channel env is set
alerts.minSeverity NOTIFICATION_MIN_SEVERITY or ALERT_MIN_SEVERITY (default HIGH)

Prometheus metrics — GET /metrics

Root path (not under /api). Returns Prometheus text when METRICS_ENABLED=true (default). Set METRICS_PROTECT=true to require the same API_SECRET as API routes. See Self-hosted metrics.

Capabilities — GET /api/capabilities

Возвращает структурированные лимиты продукта и feature flags (макс. инструментов на scan, локали перевода, режимы scan). Предпочтительнее health при построении форм или CI-валидаторов.

Каталог источников — GET /api/sources

Возвращает встроенный реестр источников (NVD, OSV, GitHub, CISA KEV, RSS) с флагами kind, fullScan, watchScan и URL RSS по умолчанию. Пользовательские фиды здесь не перечислены; клиенты передают их в каждом запросе через customFeeds.

OpenAPI — GET /api/openapi.json

Отдаёт документ OpenAPI 3.1 (server/openapi/spec.json) для codegen, импорта в Postman или contract-тестов.

Валидация запросов и ошибки

Все тела POST должны быть JSON-объектами. Ошибки валидации возвращают HTTP 400:

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

Сбои upstream (rate limit NVD, timeout RSS) возвращают 502 или 429 с текстом error и опциональным code (SCAN_FAILED, WATCH_FAILED). UI показывает error строкой; интеграторы могут также читать code и details.

Rate limit приложения (middleware): при превышении клиентом квот scan или watch на IP сервер возвращает HTTP 429:

{
  "error": "Too many scan requests. Try again later.",
  "code": "RATE_LIMITED",
  "retryAfterSec": 42
}
  • POST /scan и POST /watch используют отдельные поминутные bucket.
  • POST /scan/validate не ограничивается (безопасно для CI и проверки стека).
  • Настройка через RATE_LIMIT_SCAN_PER_MIN и RATE_LIMIT_WATCH_PER_MIN в .env.

API key (optional): When API_SECRET is set, protected routes require X-Api-Key or Authorization: Bearer. Missing/wrong → 401 { "code": "AUTH_REQUIRED" }. Health endpoints stay open.

RBAC (v1, when API_SECRET is set): /api/v1/* enforces API_ROLE (default admin). Insufficient role → 403 { "code": "FORBIDDEN" }. Legacy /api/* does not enforce RBAC — prefer /api/v1 for authenticated deployments.

Multi-tenant header (v1): Send X-Tenant-Id: <slug> when using PostgreSQL (DATABASE_URL).

Правила стека:

  • stack — обязательный непустой массив имён инструментов (trim), макс. 50 инструментов.
  • customFeeds — опционально, макс. 20 записей; каждая требует id и url.
  • enabledBuiltin — опциональная карта source ID → boolean; отсутствующие ключи по умолчанию включены.

Validate без сканирования — POST /api/scan/validate

Проверяет stack, enabledBuiltin и customFeeds без вызова внешних CVE-провайдеров. Используйте в мастерах или CI, чтобы отклонить плохой ввод до дорогого full scan.

Пример запроса:

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

Пример ответа:

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

Full scan — POST /api/scan

Запускает полное сканирование: NVD, OSV, GitHub Advisories, CISA KEV, встроенный RSS и включённые пользовательские RSS. Результаты объединяются по CVE ID, обогащаются флагами KEV, опционально переводятся и возвращаются одним payload.

Тело запроса:

Поле Тип Обяз. Описание
stack string[] да Имена инструментов для сопоставления
translate boolean нет Если true, перевод title/description
locale fa | ar | ru | zh | fr нет Целевой язык при translate: true
enabledBuiltin object нет Переключатели по источникам
customFeeds array нет Доп. RSS/Atom (custom:… ID)

Пример:

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

Ответ: ScanResponsevulns[], summary, search_date, meta (sources_checked, sources_updated_at, duration_ms, mode: "full").

Каждая уязвимость включает id, tool, title, severity, опционально affected_versions, fixed_version, sources[], url, patch_available, exploited_in_wild, при EPSS — epss (0–1) и riskScore (0–10), при compliance — cwe[] и compliance_controls[], и при обогащении translations / title_fa.

Последовательность scan (вид интегратора)

sequenceDiagram
  participant Client
  participant API as Express API
  participant Feeds as Внешние фиды

  Client->>API: POST /api/scan { stack, translate, locale }
  API->>Feeds: Параллельно NVD/OSV/GitHub/KEV/RSS
  Feeds-->>API: Сырые находки
  API->>API: Merge, KEV enrich, опц. перевод
  API-->>Client: 200 { vulns, summary, meta }

Описание диаграммы

Клиент отправляет один JSON payload. Сервер fan-out к настроенным источникам, нормализует записи в общую форму уязвимости, дедуплицирует по CVE ID и применяет опциональный перевод для первых N элементов (контролируется TRANSLATE_MAX_ITEMS). Ответ включает метаданные времени для прогресса или аудита SLA.

Пошаговый порядок

  1. Вызовите GET /api/capabilities для maxStackTools и translateLocales.
  2. Опционально POST /api/scan/validate с тем же телом, что планируете для scan.
  3. POST /api/scan с stack и опциями источников.
  4. Сохраните vulns и meta.sources_updated_at, если нужны инкрементальные badge в UI.
  5. При 429 увеличьте backoff и реже повторяйте NVD-heavy scan.

Watch — POST /api/watch

Запускает режим watch: OSV, GitHub, KEV и RSS без NVD для меньшей задержки. Тело как у scan плюс опциональный knownIds (уже виденные CVE ID). Ответ добавляет newVulns и hasNew для alerting pipeline.

Пример:

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

Ответ: как у scan плюс newVulns[], hasNew: boolean, meta.mode: "watch".

Когда newVulns не пуст и заданы переменные уведомлений, сервер отправляет настроенные каналы через NotificationService (не влияет на JSON-ответ).

Translate — POST /api/translate

Пакетный перевод английских полей title / description в локаль UI через MyMemory / LibreTranslate / Ollama (см. Configuration). Используется при смене языка UI после scan или для элементов сверх лимитов серверного перевода при scan.

Запрос:

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

Ответ: { "locale": "ru", "items": [{ "id", "tool", "title", "description" }] }
Макс. элементов на запрос: TRANSLATE_BATCH_MAX (по умолчанию 40).

Versioned API (/api/v1 only)

These routes exist only under /api/v1. Legacy /api/* covers scan, watch, validate, translate, and metadata aliases only.

Scan stream (SSE) — POST /api/v1/scan/stream

Same JSON body as full scan. Response is Server-Sent Events with progress events, then complete or error. Roles: admin, scanner.

Scan history — GET /api/v1/scans/history

Query limit (1–200, default 50). Returns { enabled, tenant, items[] }. 503 DATABASE_DISABLED without DATABASE_URL. Roles: read + history roles.

Query days (1–365, default 30). Same database requirement as history.

Tenants and saved stacks

Method Path Roles Description
POST /api/v1/tenants admin Create tenant
GET/POST /api/v1/tenants/stacks read / admin List / create stacks
GET/PUT/DELETE /api/v1/tenants/stacks/:id read / admin Stack CRUD

Kubernetes discovery — GET /api/v1/discovery/kubernetes

Requires K8S_DISCOVERY_ENABLED=true. Roles: admin, scanner.

Сводка endpoint'ов

Метод Путь Описание
GET /api/health Liveness + flags (?detailed=true)
GET /metrics Prometheus metrics
GET /api/capabilities Лимиты и возможности
GET /api/sources Каталог встроенных источников
GET /api/openapi.json Спецификация OpenAPI 3.1
POST /api/scan/validate Только валидация стека/источников
POST /api/scan Full scan
POST /api/watch Watch poll + diff
POST /api/translate Пакетный перевод
POST /api/v1/scan/stream Full scan over SSE (v1 only)
GET /api/v1/scans/history Tenant scan history
GET /api/v1/scans/trends Tenant scan trends
GET/POST /api/v1/tenants/stacks Saved stacks
GET /api/v1/discovery/kubernetes K8s discovery

Legacy /api/* aliases cover core scan/metadata routes (not v1-only rows).

Безопасность и развёртывание

API рассчитан на доверенные сети. Опциональная auth: API_SECRET на сервере; клиенты шлют X-Api-Key или Authorization: Bearer. GET /api/health и GET /api/v1/health без ключа для load balancer. Не выставляйте без TLS в публичный интернет. Задайте NVD_API_KEY для большей пропускной способности.

Связанные главы

Попробуйте запросы во вкладке API Explorer.