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

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

поставка от соисполнителя

Почему это важно для SCA/OSA

Корпоративное изделие Организации редко собирается одной командой: подсистемы приходят от соисполнителей как готовая поставка. Для C/C++ это разворачивает SCA наизнанку — источник факта о составе подсистемы не ваш пайплайн, а артефакт внешней команды. Вы не наблюдаете их сборку, не снимаете ldd на их машине, не контролируете их third_party/. Всё, что у вас есть, — то, что они положили в поставку. Значит, ключевой вопрос смещается с «как восстановить состав» на «как принять чужой состав и измерить его пригодность, а не предположить её».

Отсюда главный принцип приёмки: поставке подлежит не один bom.json, а доказуемый комплект — SBOM плюс build evidence (что реально слинковалось) плюс явный список того, что соисполнитель сам не смог опознать. Без build-логов и unresolved «технически валидный SBOM» не доказывает полноту состава.

Как это проявляется

Поставку забирают по иммутабельным координатам из артефакт-репозитория (а не из почты), проверяют структуру и измеряют покрытие:

# 1. Структура поставки: должны быть SBOM, build evidence и список нераспознанного
unzip -l contractor-A.zip
#   ожидаем минимум: bom.json, build/link.log, unresolved.json

# 2. Покрытие обогащённого SBOM (jq поверх CycloneDX)
BOM=contractor-A/bom.json
echo "всего      : $(jq '.components|length' "$BOM")"
echo "без PURL   : $(jq '[.components[]|select(.purl==null)]|length' "$BOM")"
echo "с лицензией: $(jq '[.components[]|select(.licenses!=null and (.licenses|length>0))]|length' "$BOM")"

# 3. Сверка: версия ZIP == версия metadata.component внутри bom.json?
jq -r '.metadata.component.version' "$BOM"   # должна совпадать с координатами поставки
Соисполнитель Компонентов PURL coverage unresolved Вердикт
A 142 96% 3 принято
B 88 61% 27 вернуть worklist
N 210 89% 11 принято с замечаниями

Строка B — «технически валидный SBOM»: файл есть, но 27 компонентов без идентификаторов, поэтому состав подсистемы не считается известным до доразметки.

Слепая зона или приём

Слепая зона — доверие к самому факту наличия SBOM. Файл bom.json присутствует, формат валиден — и приёмка ставит галочку, не глядя на покрытие. Между тем 61% PURL coverage означает, что про 39% состава ничего не известно: эти компоненты не мэтчатся на CVE и не проверены по лицензиям. Вторая слепая зона — provenance: поставка из почты без иммутабельных координат не доказывает, что принятый ZIP — тот же, что собрали и протестировали.

«SBOM есть» ≠ «состав известен» Принимать поставку по наличию файла — значит подписаться под невидимым риском. Критерий приёмки — измеримое покрытие (доля компонентов с PURL и версией) плюс наличие build evidence и unresolved.json, а не сам факт, что bom.json лежит в архиве.

Что делать на проекте

  1. Забирайте поставку из артефакт-репозитория по иммутабельным координатам имя:версия, не из переписки.
  2. Проверяйте структуру: обязательны bom.json, build/link-логи и unresolved.json (см. build logs как аудиторский артефакт, unresolved libraries).
  3. Считайте три числа покрытия и принимайте одно из трёх решений: принято / принято с замечаниями / вернуть worklist.
  4. Сверяйте версию поставки с metadata.component.version внутри SBOM — иначе provenance ломается молча.
  5. Зафиксируйте требования к качеству данных в контракте поставки заранее (минимальный PURL coverage, обязательные артефакты).
  6. По поставке с низким покрытием возвращайте worklist (список компонентов без PURL), а не принимайте молча.

Связь