Справочник HTTP API¶
CVE Intelligence Panel предоставляет безсессионный JSON REST API на сервере Node/Express. UI обращается к тем же endpoint'ам через прокси Vite в разработке (/api → localhost: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 }
}
Ответ: ScanResponse — vulns[], 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.
Пошаговый порядок¶
- Вызовите
GET /api/capabilitiesдляmaxStackToolsиtranslateLocales. - Опционально
POST /api/scan/validateс тем же телом, что планируете для scan. POST /api/scanсstackи опциями источников.- Сохраните
vulnsиmeta.sources_updated_at, если нужны инкрементальные badge в UI. - При 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.
Scan trends — GET /api/v1/scans/trends¶
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 для большей пропускной способности.
Связанные главы¶
- Configuration — переменные окружения
- Architecture — layout модулей сервера
- Scan and watch — семантика режимов продукта
Попробуйте запросы во вкладке API Explorer.