Пиков / КАПО
Как читать авторский курс и нормативные материалы

Это учебные материалы, а не заключение о соответствии конкретного продукта. Организационные модели курса отделяйте от терминов стандарта: ППК в опубликованном проекте — машиночитаемый перечень, а живой реестр его версий является практикой сопровождения. Термин OSA в разных материалах имеет разный охват. Статус и обязательность нормативного документа проверяются отдельно; проект КАПО опубликован как проект первой редакции.

П08. Dependency-Track как портфель SBOM

Контекст Grype и OSV-Scanner дают разовый снимок. Dependency-Track решает другую задачу: он хранит портфель SBOM по проектам и версиям и непрерывно перепроверяет их при каждом обновлении базы уязвимостей. Новая CVE, опубликованная завтра, «подсветит» уже загруженный позавчера релиз — без повторного скана. Загрузка SBOM идёт через REST API; результат — список находок проекта (VDR), который можно выгрузить.

Цель

Загрузить готовый CycloneDX-SBOM в проект Dependency-Track через API, дождаться завершения анализа и выгрузить VDR проекта в формате CycloneDX.

Проверяемый результат: проект в Dependency-Track с известным projectUUID, ненулевым числом компонентов и списком уязвимостей; выгруженный vdr.cdx.json с разделом vulnerabilities[].

Команда или действие

Нужны базовый URL API ($DT) и API-ключ ($APIKEY) из роли с правами BOM_UPLOAD и VIEW_PORTFOLIO. Стенд поднимается официальным docker-compose Dependency-Track (apiserver + frontend).

DT="http://localhost:8081"
APIKEY="odt_xxxxxxxxxxxxxxxxxxxx"

# 1. Загрузить SBOM (base64-вариант через JSON — самый переносимый)
curl -s -X PUT "$DT/api/v1/bom" \
  -H "X-Api-Key: $APIKEY" -H "Content-Type: application/json" \
  -d "$(jq -n --arg pn "demo-service" --arg pv "1.0.0" \
        --arg bom "$(base64 -w0 sbom.cdx.json)" \
        '{projectName:$pn, projectVersion:$pv, autoCreate:true, bom:$bom}')"
# -> {"token":"a1b2c3d4-...."}

# 2. Дождаться окончания обработки по токену (true = ещё обрабатывается)
TOKEN="a1b2c3d4-...."
curl -s -H "X-Api-Key: $APIKEY" "$DT/api/v1/bom/token/$TOKEN"
# -> {"processing": false}  — анализ завершён

# 3. Найти UUID проекта
curl -s -H "X-Api-Key: $APIKEY" \
  "$DT/api/v1/project/lookup?name=demo-service&version=1.0.0" | jq '.uuid'

# 4. Выгрузить VDR проекта (CycloneDX с vulnerabilities)
PUUID="<uuid из шага 3>"
curl -s -H "X-Api-Key: $APIKEY" \
  "$DT/api/v1/bom/cyclonedx/project/$PUUID?variant=withVulnerabilities" \
  -o vdr.cdx.json

alpine/curl-вариант загрузки Если jq/base64 неудобны, тот же SBOM грузится мультипартом: curl -X POST "$DT/api/v1/bom" -H "X-Api-Key: $APIKEY" -F "project=$PUUID" -F "bom=@sbom.cdx.json". Вариант с projectName+autoCreate=true удобнее на первом запуске — проект создаётся сам.

Что вы должны увидеть

Шаг загрузки возвращает токен обработки:

{ "token": "88c7a8b2-3f1e-4a9d-9b2c-1e2f3a4b5c6d" }

Опрос токена меняется с true на false, когда анализ закончен:

{ "processing": false }

Выгруженный vdr.cdx.json содержит и компоненты, и находки:

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.5",
  "metadata": { "component": { "name": "demo-service", "version": "1.0.0" } },
  "vulnerabilities": [
    {
      "id": "CVE-2022-25883",
      "source": { "name": "OSSINDEX" },
      "ratings": [{ "severity": "high" }],
      "affects": [{ "ref": "pkg:npm/semver@7.3.7" }]
    }
  ]
}

В веб-интерфейсе у проекта появятся метрики: число компонентов, светофор по severity (Critical/High/Medium/Low) и вкладка Audit для разметки VEX-состояний. Ориентир: компонентов столько же, сколько в SBOM; находок — обычно десятки.

Проверка артефакта jq '.vulnerabilities | length' vdr.cdx.json — число находок. jq '.components | length' vdr.cdx.json сверьте с числом компонентов исходного SBOM: они должны совпасть.

Если не получилось

Типичные ошибки - HTTP 401 / The supplied API key is invalid. Ключ без нужного права или истёк. Для загрузки нужно BOM_UPLOAD, для выгрузки — VIEW_PORTFOLIO (и PORTFOLIO_MANAGEMENT для autoCreate). - processing навсегда true или находок 0. Анализ ещё идёт (опрашивайте токен) либо включены/выключены не те анализаторы (OSS Index, Internal, OSV). Без сети OSS Index недоступен — используйте внутренний анализатор и зеркало OSV. - HTTP 400 при PUT. Битый base64 или невалидный CycloneDX. Проверьте SBOM локально (jq . sbom.cdx.json) и кодирование (base64 -w0, без переносов строк). - Проект не находится через lookup. Перепутаны name/version или autoCreate не сработал из-за прав. Найдите UUID списком: curl -H "X-Api-Key: $APIKEY" "$DT/api/v1/project" | jq '.[].uuid'.

Критерий зачёта

Показать преподавателю: 1. ответ API с токеном и переход processing → false; 2. UUID проекта и его метрики в веб-интерфейсе (компоненты + светофор severity); 3. выгруженный vdr.cdx.json с непустым vulnerabilities[]; 4. одно предложение о том, чем непрерывный мониторинг портфеля отличается от разового скана из П06. Grype поверх готового SBOM.

Почему gate здесь manual, а не ci Dependency-Track — это портфель и continuous monitoring, а не шаг сборки. Решение «блокировать релиз» принимает человек по дашборду и политике, а не пайплайн на каждом коммите. Автоматический CI-gate в этой группе живёт в П06. Grype поверх готового SBOM и П07. OSV-Scanner и lockfiles.

Нормативная связка

М06. Поиск уязвимостей и управление VDR/VEX · OWASP Dependency-Track · NIST SP 800-218 SSDF (RV.1/RV.2) · OWASP SCVS · Политика управления уязвимостями компонентов · Порядок загрузки VDR из Dependency-Track

Смежные практики: П07. OSV-Scanner и lockfiles · П09. VDR и VEX различие факта и решения · П35. VEX triage