SBOM: де ламається облік залежностей у збірці
Збірка проходить зелений статус, образ іде в реєстр, реліз їде в прод.
За кілька днів надходить повідомлення про уразливість у транзитивній залежності — і точний склад цього постачання відновити нічим: маніфести перезаписані наступною збіркою, файл фіксації версій в артефакт не потрапив, версії підтягувалися за діапазоном. Питання «чи є у нас уразливий компонент саме в цій версії?» залишається без відповіді.
Далі починається ручний перебір.
Інженер шукає коміт за датою релізу, перезбирає проєкт тим самим набором вихідних кодів і все одно не може стверджувати, що отримав той самий результат: оновлений мінорний пакет, інший набір системних бібліотек у базовому образі, кеш внутрішнього проксі.
На таку реконструкцію йдуть години, а вікно між виявленням уразливості та підтвердженою відповіддю весь цей час відкрите.
Корінь у тому, що SBOM народжується не там, де має.
Його генерують окремим кроком постфактум, за файлом залежностей і поза контекстом збірки: до списку потрапляють прямі залежності, але не те, що реально лягло в шари образу — транзитивні пакети системного менеджера, вендорні бібліотеки, скопійовані в артефакт.
Без прив'язки до незмінного ідентифікатора образу документ описує «приблизно цю збірку», а не конкретне постачання, і облік компонентів перестає бути перевірним.
Плюс розрізненість форматів: одна команда віддає склад збірки в одному вигляді, інша — в іншому, і звести їх в один запит без ручної нормалізації неможливо. Розбираємо, як вбудувати генерацію в конвеєр так, щоб прозорість постачання підтверджувалася для кожного артефакту.
Практична користь регулярної генерації SBOM
Регулярна генерація SBOM перетворює перелік залежностей з разового папірця на потік даних.
Генератор Anchore Syft запускається у конвеєрі збірки на кожну збірку основної гілки, читає дерево залежностей з маніфестів менеджерів пакетів і файлової системи образу, а результат зберігає документом у форматі CycloneDX поряд із самим артефактом.
Далі документ підписується й іде в реєстр: версія образу та її склад пов'язані жорстко, а не з пам'яті інженера.
Коли надходить оповіщення про уразливість у транзитивній бібліотеці, робота йде запитом до реєстру, а не обходом десятків репозиторіїв. Відповідь — перелік сервісів і версій, де компонент присутній, з точністю до збірки.
Розбір інциденту скорочується з кількох годин на узгодження «де це взагалі використовується» до хвилин: відразу видно, що патчити, а що можна не чіпати.
Простежуваність працює і у зворотний бік. Для будь-якого запущеного контейнера піднімається його SBOM, і на питання «які компоненти і під якими ліцензіями зараз у проді» відповідає документ, а не реконструкція з історії змін.
Це ж закриває зовнішні запити щодо безпеки: склад постачання вивантажується з реєстру, а не збирається заново.
Контроль залежностей тримається на порівнянні двох SBOM: різниця показує, що реально змінилося під час оновлення бази образу або версії бібліотеки.
Необлічені транзитивні залежності, які тягнуться вглиб на кілька рівнів, перестають бути сюрпризом — клас відмов «після релізу з'ясувалося, що приїхало зайве» зникає з практики.
Ключовий ефект дає саме регулярність: розклад у конвеєрі дає безперервну картину, разовий знімок — лише фотографію на дату. Замість десяти таблиць і нотаток у різних місцях з'являється єдиний реєстр компонентів, з яким працюють і розробка, і безпека.
Способи формування складу: порівняння підходів
Опис складу можна отримати трьома різними шляхами, і вони не взаємозамінні.
Автоматична генерація на етапі збірки фіксує все, що реально потрапило в артефакт; напівавтоматичний режим додає записи про компоненти, які аналізатор не розпізнає; разовий розбір готового артефакту потрібен там, де перезбирання не планується.
Формати опису складу — CycloneDX або SPDX — вибираються окремо від способу: важлива сумісність із системами, які читатимуть ці дані.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Автоматичний, у конвеєрі збірки | Регулярні релізи, потрібен свіжий склад на кожен артефакт | Потребує окремої стадії; динамічні завантаження видно не завжди |
| Напівавтоматичний, з ручною верифікацією | Змішаний стек, частина компонентів ставиться поза менеджерами пакетів | Потрібен регламент підтримки; склад застаріває між ревізіями |
| Разовий розбір готового артефакту | Системи, які не перезбираються | Дає зріз на дату розбору, сам не оновлюється |
Різниця між варіантами — це різниця між свіжістю даних і вартістю їх підтримки. Автоматичний режим дає максимальну глибину аналізу: видно прямі й транзитивні залежності, вкладені системні пакети.
Обмеження генерації — компоненти, що підвантажуються під час роботи із зовнішніх джерел, у такий розбір не потрапляють.
Напівавтоматичний підхід закриває цю діру ціною регламенту: у кожного ручного запису мають бути версія й джерело, інакше опис втрачає достовірність. Разовий розбір корисний як відправна точка — він показує повну картину на поточний момент, але не оновлюється разом із системою.
Робоча схема — автоматична генерація в конвеєрі як основа плюс періодичний перезбір складу для рідко оновлюваних систем.
Як ми налаштовуємо генерацію SBOM: етапи робіт
Налаштування генерації SBOM — це не підключення одного розширення, а послідовність із шести кроків: від інвентаризації компонентів до передачі документації.
Кожен етап відповідає за свій клас помилок, і пропуск будь-якого з них призводить до переліку, який формально існує, але не відображає реальний склад артефакту.
- Інвентаризація компонентів. Обходимо репозиторії, фіксуємо мови, менеджери залежностей, наявність транзитивних і вендорних бібліотек, компонентів усередині образів. На виході — перелік сервісів із позначкою, де генерація покриває все автоматично, а де потрібне ручне доведення.
- Схема потоків. Визначаємо, у який момент формується документ — під час збірки артефакту чи під час випуску образу, де він зберігається і як пов'язується з конкретною збіркою, щоб за номером релізу можна було знайти саме його перелік.
- Вбудовування у збірку. Генерація стає кроком конвеєра: якщо документ не сформовано, збірка зупиняється. Так перелік перестає бути необов'язковим артефактом, який роблять «коли попросять».
- Налаштування правил. Вибираємо формат — SPDX або CycloneDX, задаємо склад полів, глибину розбору залежностей і поведінку для компонентів без метаданих: позначаємо явно, а не викидаємо мовчки.
- Перевірка результату. Звіряємо склад з документа з фактичним вмістом артефакту, перевіряємо версії, ліцензії та дублікати. Розбіжності — це або помилка генератора, або сліди ручних правок збірки.
- Передача документації. Віддаємо схему, опис правил, інструкцію для розробника й порядок оновлення при зміні залежностей, щоб налаштування не розійшлося з реальною збіркою при першій же великій зміні.
Склад постачання: конфігурації, схеми та регламенти
Налаштування генерації SBOM — це не разовий звіт за одним релізом, а зміна контуру збірки: збірка сама формує перелік компонентів, підписує його й передає у сховище.
Замовнику залишається не «магія підрядника», а набір артефактів, за якими його команда працює далі самостійно і відтворює результат на новому проєкті.
Що саме передаємо:
- Конфігурації контуру збірки — завдання й шаблони етапів, де ввімкнено генерацію переліку, з поясненнями щодо кожного параметра.
- Схеми процесів — шлях від зміни коду до публікації SBOM: точки збірки, перевірок і передачі артефакту, з ролями та відповідальними.
- Політики контролю складу — правила зупинки збірки при компоненті з відомою уразливістю або неприпустимою ліцензією.
- Політики доступу — матриця прав на переліки, налаштування підписів і перевірка справжності артефактів.
- Шаблони звітів — вивантаження у стандартних форматах опису складу (SPDX, CycloneDX) з фільтрами за критичністю.
- Інструкції для команди — як випустити реліз, відкотити правило й розібрати розбіжність у складі.
- Регламент оновлення — періодичність перегляду забороненого списку й порядок дій при зміні залежностей.
Кожен пункт приймаємо на вашому контурі: запускаємо збірку з навмисно проблемною залежністю й перевіряємо, що правило спрацьовує, а звіт формується коректно.
Кейс: як скоротився розбір інцидентів після впровадження
Що було до автоматизації
Інцидент з уразливістю в транзитивній бібліотеці розбирали вручну: інженер піднімав журнали збірок, звіряв маніфести залежностей і файли фіксації версій за кожним сервісом.
На визначення повного списку зачеплених компонентів ішло від 4 до 6 годин, а щодо частини збірок картина залишалася неповною — доводилося перезбирати сервіси «про всяк випадок». За десятків репозиторіїв це розтягувалося на окремий робочий день і затримувало випуск виправлення.
Що змінили
Генерацію SBOM увімкнули прямо в крок збірки: документ складу компонентів створюється автоматично й прив'язується до незмінного ідентифікатора образу, а не до імені тегу.
Повідомлення про уразливість із зовнішнього джерела запускає пошук за всіма накопиченими документами — у Dependency-Track такий запит повертає перелік зачеплених збірок за хвилини, включно з транзитивними залежностями, яких немає у явних маніфестах.
Окремо закрили питання якості даних: образ вважається випущеним лише за наявності SBOM, тому частка збірок із документом складу сягнула 100%.
Метрики після
Час визначення зачеплених компонентів скоротився з 4–6 годин до 15–25 хвилин, причому це повний перелік, а не вибірка за кількома сервісами. Кількість перезбирань «для підстраховки» впала майже до нуля: видно, у яких образах компонент є, а в яких немає.
Розбір інциденту більше не залежить від того, хто з інженерів пам'ятає історію конкретного репозиторію.
Чим відрізняється разовий звіт про склад від регулярної генерації SBOM?
Разовий звіт — знімок складу на момент запиту: інвентаризація того, що вже розгорнуто. Регулярна генерація прив'язує SBOM до кожного артефакту на етапі збірки, тому документ існує для будь-якої версії, що потрапила в середовище. Різниця не у форматі файлу, а в тому, які питання система здатна закрити.
| Критерій | Разовий звіт | Регулярна генерація |
|---|---|---|
| Актуальність даних | Застаріває після першого ж релізу | Оновлюється з кожною збіркою |
| Трудовитрати | Ручний збір під кожен запит | Налаштовується один раз у конвеєрі |
| Покриття випусків | Лише версії, що потрапили у вибірку | Усі артефакти, включно з відкатами |
| Повторні перевірки | Щоразу заново | Вибірка з готового сховища |
| Нова уразливість | Інвентаризація з нуля | Пошук за компонентом за хвилини |
Актуальність — ключова розбіжність. Знімок відповідає на питання «що було в системі на момент аудиту» і після пари релізів втрачає зв'язок із реальністю: у ньому залишаються зняті залежності й немає нових.
Коли надходить повідомлення про уразливість, потрібно за хвилини зрозуміти, які працюючі версії її містять, — за знімком це потребує нового обходу.
Другий вододіл — повторювані перевірки. Регулярна генерація перетворює відповідь на запит безпеки на вибірку за індексом компонентів: збірка публікує SBOM у сховище, пошук за зачепленою бібліотекою видає список версій і середовищ. Ручний звіт такого сценарію не витримує — вартість повторення порівнянна з першою інвентаризацією.
Робоча схема — комбінувати: разовий аудит для успадкованих систем, які вже працюють і не перезбираються, регулярна генерація — для всього, що випускається далі.
Правила підпису та зберігання SBOM роблять таку перевірку відтворюваною, а не залежною від того, хто і коли згадав зібрати звіт.
Технічні сумніви: часті питання щодо впровадження
Сумніви викликає не сама генерація переліку, а її вбудовування в працюючий конвеєр збірки: що доведеться змінювати, як бути з компонентами, поставленими вручну, і чи не виявиться перелік неповним. Зібрали чотири заперечення, які найчастіше звучать на етапі оцінки, і відповідь на кожне.
Чи доведеться перебудовувати конвеєр збірки?
Крок генерації додається після формування образу, решта етапів та їхні параметри не змінюються. Він поза критичним шляхом: за недоступності генератора образ публікується з позначкою, а обов'язковість переліку вмикається окремим правилом.
Що з компонентами, поставленими вручну?
Їх знаходить сканування вмісту образу: звіряються шляхи встановлення, сигнатури файлів і записи менеджерів пакетів. Такі бібліотеки потрапляють до переліку з позначкою джерела, а частка нерозпізнаних файлів іде у звіт.
Як переконатися, що перелік повний?
Повнота перевіряється порівнянням з еталоном і покриттям за шарами образу: вважається частка файлів, віднесених до відомих компонентів. Розбіжність вище порогу стає блокувальним правилом, а не попередженням.
Уже є сканер і сховище — відмовлятися?
Перелік віддається у стандартних відкритих форматах, тому підхоплюється поточними сканерами й реєстром без заміни. Генератору потрібен доступ на читання образів і запис у сховище переліків — політики описуємо окремо.
Якщо вашого сценарію в списку немає — опишіть його, повернемося з оцінкою та планом.Обговоримо задачу: що надіслати для оцінки та плану
Щоб повернутися з оцінкою строків і планом робіт із генерації складу ПЗ (SBOM), доступ до вашого контуру на старті не потрібен. Достатньо опису того, як влаштовані збірка й реліз, — цього вистачає, щоб побачити обсяг робіт і вузькі місця.
Що описати за пунктами:
- Контур збірки — які системи збирають артефакти, де зберігаються залежності й чи є доступ до маніфестів на етапі збірки, а не лише в готовому образі.
- Мови та менеджери пакетів за сервісами — від них залежить, які формати складу ми генеруємо і як зводимо їх в один документ.
- Тип артефактів — образи, архіви, системні пакети: для кожного потрібен свій набір джерел даних.
- Споживач складу — реєстр, система контролю уразливостей або зовнішній аудит: від цього залежить формат вивантаження й ступінь деталізації.
- Точка вбудовування — склад з'являється в процесі збірки, перед публікацією артефакту або за розкладом для вже випущених версій.
- Зберігання та історія — скільки версій складу потрібно тримати і як швидко знаходити склад конкретного релізу.
- Обмеження щодо доступу — закриті сегменти й ізольовані контури, де збірка йде без зовнішньої мережі.
Якщо частини даних поки немає — опишіть як є: прогалини враховуємо в плані робіт і закриваємо на етапі обстеження. За описом повернемося з оцінкою строків, складом етапів і тим, що знадобиться від вашої команди.







