# Дизайн аудиту ланцюга постачання

> Принципи перевірки, що лежать в основі зафіксованого тесту аудиту ланцюга постачання

---

LLMS index: [llms.txt](/llms.txt)

---

[Аудит ланцюга постачання][supply-chain audit] підтверджує ефективність [заходів контролю залежностей][controls] репозиторію виключно на основі файлів, що були зафіксовані у репозиторії. На цій сторінці викладено принципи проєктування, які забезпечують надійність самого аудиту: аудит, який можна обдурити (або який проходить, навіть якщо нічого не перевіряє), гірший за його відсутність, оскільки зелений результат у такому разі свідчить про неперевірений стан. Ці принципи випливають із циклів суперечливого огляду цього аудиту та його [попередника Docsy][docsy-2714], під час кожного з яких шукаються вхідні дані, що порушують контроль, але проходять тест.

Щодо того, які заходи контролю існують і чому, див. розділ «[Безпека ланцюга постачання](../supply-chain-security/)»; що робити, коли аудит не проходить у вашому PR, див. [секцію аудиту][supply-chain audit] документів залежностей.

## Принципи {#principles}

Кожен принцип стосується одного зі способів, якими верифікатор може ввести в оману; у ході суперечливого огляду було виявлено конкретні приклади більшості з них у попередніх версіях.

1. **Перевірка виключно на основі файлів, що потрапили у репозиторій.** Аудит зчитує блокування, маніфести, `.npmrc` та `netlify.toml` (ніколи — мережу чи дерево встановлених файлів), тому він працює швидко, в автономному режимі і не піддається впливу стану, який повинен перевіряти.
2. **Включати цілі структури до списку дозволених; не використовуйте шаблони у списку заборонених.** Кожен регулярний вираз у списку заборонених для формату конфігурації рано чи пізно натрапляв на правильний варіант, якого він не передбачав (ключі TOML у лапках, з крапками та у вбудованих таблицях обходили список заборонених для ключів env). Фіксація всієї перевіреної структури (точні набори ключів, точні значення) є надійнішою і зазвичай коротшою.
3. **Виконання синтаксичного аналізу; не сканування рядків.** Синтаксичний аналізатор формату визначає його семантику. Регулярний вираз на рівні рядка неправильно моделює її, не повідомляючи про це: таблиця контексту, яку він не розпізнає, все одно має значення для Netlify.
4. **Точні ідентифікатори; відсутність збігу за префіксом або прапорцем.** Збіг за префіксом допускає додавання доповнення `&& npm install ...` до скрипту, якому аудит довіряє за назвою.
5. **Закрита помилка у разі відсутності.** Кожна перевірка підрахунку містить перевірку мінімального значення, тому порожній вхідний параметр не може стандартно пройти перевірку; записи, у яких відсутнє очікуване поле, викликають помилку, а не пропускаються.
6. **Привʼязка до ідентичності, якій довіряє npm.** npm визначає ідентичність пакунка за його URL-адресою в реєстрі `resolved`, а не за ключем блокування чи полем `version`, тому аудит повʼязує всі три елементи разом; перевірка лише тих полів, яким npm не довіряє, дозволяє пройти перевірку навіть у разі невідповідності, на яку npm би зреагував.
7. **Один «дім» на кожну інваріанту.** Список, що перевіряється у двох файлах, може змінюватися; аудит імпортує спільні значення з модуля-власника (імена env-override інсталятора Hugo походять із допоміжного модуля для перекомпіляції), а модульний тест цього модуля фіксує вміст.
8. **«Спочатку червоне».** Новій перевірці довіряють лише після того, як навмисно пошкоджений вхідний параметр призвів до її провалу; кожне завершення в історії аудиту було визнано «червоним», перш ніж його «зелений» стан був зарахований. Хибний «зелений» стан гірше за «червоний».
9. **Асерції визначають очікуваний стан**, а у разі рутинних спрацьовувань — і виправлення: асерція `allowScripts` вказує версію, до якої має бути переміщений запис у результаті підвищення версії залежності, тому повідомлення про помилку є і виправленням.
10. **Вкажіть межі сфери дії.** Області, які аудит навмисно не охоплює (файли робочих процесів, власна інсталяція теми, скрипти build-half), вказуються в аудиті та документації, щоб відсутність охоплення ніколи не сприймалася за перевірене охоплення.

## Принципи в аудиті {#principles-in-the-audit}

Один приклад на кожен принцип; [тестовий файл][audit test] є авторитетним переліком тверджень.

| Принцип                 | Екземпляр в аудиті                                                                              |
| ----------------------- | ----------------------------------------------------------------------------------------------- |
| Committed files alone   | Кожен вхід читається з checkout; набір тестів запускається без мережі                           |
| Allowlist whole shapes  | `netlify.toml`: таблиці верхнього рівня, ключі build та набори env-ключів `deepEqual`ed         |
| Parse, don't line-scan  | `netlify.toml` розбирається за допомогою `smol-toml` до будь-яких тверджень                     |
| Exact pins              | Скрипти install-closure порівнюються через `assert.equal`, ніколи `match`                       |
| Fail closed on absence  | `registryPackages > 0` floors; версією-менший lock-запис не проходить IOC чек                   |
| Identity npm trusts     | `resolved` URL кожного запису реєстру має називати власний пакунок та версію                    |
| One home per invariant  | `UNSAFE_HUGO_ENV` імпортується з `rebuild-hugo-extended.mjs`                                    |
| Red-first               | PR кожного hardening-коміту зазначає зламаний вхід, що змусив його спочатку не пройти перевірку |
| Assertions name the fix | `allowScripts covers hugo-extended at its locked version X`                                     |
| Stated scope boundary   | Коментар заголовка аудиту називає виключені поверхні                                            |

[audit test]: https://github.com/open-telemetry/opentelemetry.io/blob/main/scripts/supply-chain-audit.test.mjs
[controls]: ../../build/dependencies/#controls
[docsy-2714]: https://github.com/google/docsy/pull/2714
[supply-chain audit]: ../../build/dependencies/#audit
