License compliance check: що ламається у складальному конвеєрі
Ліцензійний інцидент майже ніколи не виглядає як інцидент. Поки реліз збирається, ніхто не помічає, що чергова транзитивна залежність притягла умови, які забороняють використання в закритому продукті.
Перевірка ліцензій у збірці живе окремим скриптом на машині інженера — тому заборонені ліцензії в залежностях доїжджають до продакшену мовчки, а спливають на аудиті або угоді, коли змінювати склад уже дорого.
Причин три. Дерево залежностей оновлюється швидше, ніж хтось устигає читати умови: одна правка закріпленого файлу додає десяток нових пакетів. Конвеєр тягне різні джерела — менеджер пакетів, образи з реєстру, готові бінарні модулі, куди аналізатор за замовчуванням не заходить.
А ручний прогін раз на квартал не встигає за частотою змін і швидко перестає бути обов'язковим кроком.
Ціна пропуску — не рядок у звіті. Ліцензійні ризики релізу перетворюються на вимогу вирізати або переписати функціональність, а іноді на претензію правовласника й зупинку постачань. Відкочувати доводиться не одну зміну, а весь ланцюжок залежностей, включно з транзитивними.
Закривається це перенесенням license compliance check усередину конвеєра: окремий крок звіряє дерево залежностей із політикою — дозволені, умовно припустимі та заборонені ліцензії — до публікації артефакту. Збірка зупиняється на етапі перевірки, а не в проді. Розбираємо, як це влаштовано і де проходить межа між блокуванням і попередженням.
Що дає автоматична перевірка на кожному злитті
Перевірка ліцензій, вбудована в конвеєр, дивиться не реліз загалом, а конкретний набір змін у злитті: нові та оновлені залежності, транзитивні пакети, зміну версій. Нижче — що команда отримує у вимірюваному вигляді.
- Покриття змін — правило спрацьовує на кожному злитті в основну гілку, а не перед випуском; частка змін, що пройшли автоматичну перевірку залежностей, виходить до 100% без ручного контролю.
- Час розбору ліцензій — звіт надходить із готовим розбором: яка ліцензія, який пакет її приніс і хто підтягнув залежність. Розбір одного злиття займає хвилини замість годин звірки маніфестів.
- Усунений клас відмов — ліцензії з обов'язковим розкриттям вихідного коду не доходять до випуску: злиття блокується, інженер одразу бачить відповідну заміну пакета.
- Єдиний формат звіту — результати складаються в машинозчитуваний вигляд (SPDX), тому одне вивантаження годиться і для юридичної перевірки, і як історія рішень щодо кожного пакета.
- Винятки під контролем — дозволені вручну пакети фіксуються з обґрунтуванням і терміном перегляду, тому підтвердження не губляться між релізами.
- Зворотний зв'язок до випуску — розробник дізнається про проблему у своєму злитті, а не на прийманні; обсяг переробок падає разом із кількістю несподіваних ліцензій.
Сумарно це переводить ліцензійну чистоту з разової акції перед випуском у постійний фон: перевірку проходить кожна зміна, а не лише та, що потрапила до ручної вибірки. Далі розбираємо, як така перевірка налаштовується і що заважає їй шуміти.
Режими перевірки: блокувальний, попереджувальний, відкладений
Режим перевірки — це компроміс між ціною хибного спрацювання та ціною пропущеної ліцензії.
У першому випадку зупиняється випуск і інженери вручну розбирають, чи справді компонент несумісний, у другому — спірний код іде в постачання, і розбиратися доводиться вже з юридичними наслідками.
Глибина аналізу залежностей налаштовується окремо від режиму: можна перевіряти лише прямі залежності або розбирати все дерево, включно з транзитивними. Друге чесніше, але вимагає зафіксованих версій — інакше правило спрацьовує на компоненті, який у збірку взагалі не потрапив.
| Режим | Коли підходить | Обмеження |
|---|---|---|
| Блокувальний | Релізні гілки та збірки, що потрапляють у постачання замовнику | Зупиняє випуск за будь-якої невідповідності; без вивіреного списку дозволених ліцензій дає хибні спрацювання |
| Попереджувальний | Гілки розробки, ранні стадії роботи над задачею | Нічого не зупиняє: знахідки накопичуються й ідуть у реліз, якщо звіт ніхто регулярно не розбирає |
| Відкладена перевірка ліцензій | Зовнішні та транзитивні залежності, реєстр компонентів | На збірку не впливає: невідповідність виявляється пізніше, коли код уже в основній гілці |
На практиці режими комбінують: блокувальний вмикають на релізних гілках, де важлива кожна хвилина простою, попереджувальний — на решті, а відкладену перевірку запускають за розкладом, щоб відстежувати зміну ліцензій у зовнішніх компонентів. Такий набір дає строгість там, де вона виправдана, і не заважає щоденній роботі.
Упровадження за кроками: від інвентаризації до регламенту
Порядок кроків тут не формальність: якщо почати з налаштування блокувань, конвеєр стане на першому ж злитті й перевірку вимкнуть. Тому спочатку збираємо факти про те, що вже використовується, потім формулюємо правила, і лише згодом вмикаємо їх у роботу.
- Інвентаризація залежностей. Збираємо повний реєстр: прямі та транзитивні бібліотеки, образи, зовнішні компоненти — з ліцензією та версією для кожного. Розділяємо те, що потрапляє в продукт, який постачається, і те, що живе лише у збірці: вимоги до них різняться.
- Політика допуску ліцензій. Розкладаємо ліцензії за трьома групами: дозволені без питань, ті, що вимагають умов (зазначення авторства, збереження тексту), заборонені. Спірні випадки фіксуємо окремо — з обґрунтуванням, хто і на якій підставі ухвалив рішення.
- Налаштування перевірки в конвеєрі. Правила переносимо в автоматичну перевірку, яка запускається на кожній зміні та дивиться маніфести й файли блокування. Порушення зупиняє збірку із зазначенням конкретної залежності та ліцензії — інженер одразу бачить, що лагодити.
- Перевірка на тестовому злитті. Проганяємо правило на реальному запиті, а не на навчальному прикладі: дивимося, скільки хибних спрацювань, чи не гальмує перевірка збірку, чи зрозуміле повідомлення про помилку. Далі налаштовуємо винятки — точніше, ніж вимкнення правила цілком.
- Порядок розбору порушень. Домовляємося, що робити при спрацюванні: замінити бібліотеку, отримати письмовий дозвіл, зафіксувати виняток із терміном. Без цього кроку перевірка перетворюється на постійну суперечку з розробниками.
- Передача регламенту. Віддаємо документ із групами ліцензій, інструкцією з розбору порушень і точками, де правило живе в коді. Регламент оновлюється при зміні політики — інакше він втрачає силу за пару місяців.
Артефакти впровадження: політики допуску, схеми, регламенти
Підсумок роботи — не налаштований інструмент, який живе, поки поруч інженер, а комплект артефактів, за якими команда сама відтворює перевірку ліцензійної чистоти (license compliance check). Усе лежить у репозиторії поруч із кодом, проходить рев'ю і версіонується разом із сервісами.
- Політики допуску ліцензій — правила з розбивкою за способом використання: що припустимо для внутрішнього сервісу, що для продукту, який постачається, що йде на ручне погодження.
- Схема потоку перевірки — від фіксації залежностей до блокування збірки: точка входу, обов'язкові кроки, місце для рішення людини.
- Реєстр винятків — таблиця з обґрунтуванням кожного відступу, власником і датою перегляду, щоб послаблення не ставали постійними.
- Документація щодо ліцензій — перелік компонентів та їхніх умов: які зобов'язання виникають під час постачання і що додати до релізу.
- Регламент для команди — що робити при спрацюванні перевірки: як розібрати причину, до кого йти, як оформити виняток.
- Порядок оновлення правил — хто додає нову ліцензію до списків, як зміна проходить рев'ю і як про неї дізнається команда.
- Звіти щодо релізу — що перевірено, що залишилося поза перевіркою, де накопичилися винятки.
Формати відкриті: політики — текстові файли, документація — звичайні текстові файли поруч із кодом. Такий комплект переживає зміну інструментів і людей.
Кейс: прибрали клас відмов у випусках через ліцензії
Реліз став за два дні до викладки: у збірку транзитивно потрапила бібліотека під ліцензією, що вимагає розкриття похідного коду, а модель розповсюдження продукту цього не допускала.
Розбір зайняв три зустрічі — юристи шукали, хто і коли додав пакет, інженери перевіряли, чи можна замінити його без переписування модуля. Випуск зсунувся, хоча код був готовий і протестований: проблема виявилася не в логіці, а в складі збірки.
До: перевірка в кінці шляху
Контроль ліцензій ішов на етапі підготовки релізу, після заморозки коду, коли вартість виправлення максимальна. Вісім випадків із десяти спливали в останні дні перед викладкою, а виправлення вимагало повернути задачу в розробку й заново прогнати регресію. Історія перевірок не накопичувалася — кожен інцидент розбирали з нуля.
Після: контроль на злитті
Перевірку перенесли в момент злиття: на кожну зміну збирається перелік залежностей та їхніх ліцензій, сканування на базі ScanCode звіряє його з політикою — дозвільні та заборонні списки плюс винятки з датою перегляду.
Висновок надходить в обговорення зміни за кілька хвилин, поруч зі змінами в коді, і автор одразу бачить пакет, що порушив правило.
Частка невідповідностей, знайдених на етапі релізу, знизилася приблизно з 80% до 10%, затримка випуску через перевірки — з кількох днів до годин, розбір одного інциденту займає 10–15 хвилин замість серії нарад.
Відмови та винятки фіксуються в політиці, перелік ліцензій накопичується автоматично, тому повторний розбір вручну більше не потрібен.
Чим політика compliance відрізняється від пошуку вразливостей?
Політика compliance і пошук уразливостей дивляться на один і той самий набір залежностей, але відповідають на різні питання. Перша — про права: чи можна взагалі використовувати цей компонент у продукті і на яких умовах. Друга — про безпеку: чи є в компоненті відома діра і чи досяжна вона в нашому сценарії.
Звідси й різні сигнали на виході. Ліцензія із зобов'язанням розкриття похідного коду в закритому продукті — це не дефект безпеки, і сканер уразливостей її просто не покаже.
Зворотна ситуація трапляється не рідше: критична вразливість у компоненті під дозвільною ліцензією прав не порушує, але вимагає термінового оновлення.
Різняться реакції та власники знахідок. Ліцензійний випадок закривається заміною компонента, ізоляцією його в окремий сервіс або усвідомленим рішенням на рівні продукту.
Уразливість закривається патчем, оновленням версії або компенсувальним заходом на периметрі — і тут рішення ухвалює інженер, а не юрист. Терміни теж різні: діру правлять за критичністю, ліцензію — до випуску.
Саме тому в конвеєрі обидві перевірки ставлять поруч, але не змішують в один звіт. Один розбір складу збірки дає два незалежні вердикти: щодо прав і щодо безпеки, з різними правилами блокування.
Якщо скласти їх у загальний список, ліцензійна знахідка потоне серед сотень попереджень сканера й піде в прод.
Суміщення перевірок у конвеєрі дає виграш у часі: залежності розбираються один раз, а правила застосовуються двічі. Шлюз якості при цьому спільний — збірка не йде далі, якщо порушено політику compliance або перевищено поріг критичності щодо уразливостей.
Так відмінність перевірок залишається видимою, а рішення про випуск ухвалюється за обома підставами одразу.
Технічні питання: винятки, обмеження, крайні випадки
Перевірка ліцензійної сумісності спирається на метадані пакетів, а не на текст ліцензійного файлу всередині архіву. Подвійне ліцензування, вкладені умови та пакети без явної позначки вона позначає як спірні — і це коректно: коло звужує інструмент, а вердикт виносить людина.
Що робити із залежностями, які вже працюють у проді?
Перевірка читає маніфести й артефакти збірки, а не те, що запущено на серверах, тому перший прогін покаже весь накопичений хвіст одразу. Гасити його блокуванням не можна: спочатку інвентаризація — які пакети під обмежувальними умовами, де вони реально викликаються, чи є заміна. Блокувальні правила вмикаємо на погоджений набір, решта йде в чергу з датою розбору.
Як оформити погоджений виняток?
Виняток живе в репозиторії поруч із маніфестом — у файлі політики, а не в листуванні. У запису є ім'я пакета, діапазон версій, причина, хто погодив і дата перегляду; прострочений запис знову валить збірку, тому виняток не стає вічним.
Коли обмеження йде від правовласника, погодження оформлюємо письмово й додаємо до запису — до відповіді пакет залишається у списку.
Наскільки перевірка сповільнює збірку?
Розбір дерева залежностей кешується між запусками, тому перевірка додає секунди, а не хвилини. Звіт формується окремим кроком: падає конкретне правило, а не весь конвеєр, і збірка образу не зупиняється.
Межі знаємо заздалегідь — пакети із закритими метаданими й локально вендорені бібліотеки перевірка не бачить, їх закриваємо окремими правилами.
Обговоримо задачу: що уточнити перед стартом робіт
Перед стартом важливо зрозуміти, як влаштований ваш реєстр залежностей і в якому місці випуску перевірка ліцензій дасть ефект, а не просто додасть шум. Уточнюємо джерела компонентів, чинні правила погодження і те, наскільки глибоко потрібно розбирати транзитивні залежності. Від цього залежить і обсяг робіт, і оцінка термінів налаштування.
- Реєстр залежностей: які пакетні менеджери використовуються, чи є приватні та внутрішні дзеркала, яка частка прямих і транзитивних компонентів.
- Політика ліцензій: які типи дозволені, що вважаємо неприйнятним у продукті, який постачається, кого повідомляти при спірній ліцензії.
- Точки контролю у збірці: на якому етапі перевірка блокує випуск, а де достатньо попередження й запису у звіт.
- Порядок винятків: як оформлюється тимчасовий дозвіл, хто його погоджує і коли його переглядають.
- Артефакти та звітність: чи потрібен перелік усіх компонентів збірки з ліцензіями і в якому вигляді його передавати далі.
- Легасі в постачанні: компоненти, які вже відвантажуються, і вимоги до їх окремого розбору.
- Критерії приймання: частка компонентів із підтвердженою ліцензією і припустимий час проходження перевірки на збірку.
Зібраних вхідних даних достатньо, щоб повернутися з планом упровадження перевірки ліцензій: етапи, склад змін у збірці, точки блокувань і оцінка термінів налаштування. Опишіть задачу — обговоримо її предметно й запропонуємо порядок робіт під ваш процес випуску.







