Минулого місяця я нарешті сів і подивився, як у нас насправді влаштоване керування секретами в проді. Не на схему архітектури. Не на policy-документ, де написані всі правильні слова. На реальність — на 55 змінних CI/CD пайплайнів, від яких тихо залежав кожен білд. Дванадцять із них лежали відкритим текстом. Тридцять узагалі не використовувалися — рештки від проєктів, які давно викотили й забули. І в жодної не було політики ротації. Один пароль від бази не мінявся чотирнадцять місяців — і при цьому бадьоро друкувався в логи білдів, які міг прочитати будь-хто з доступом до пайплайну.

Ніхто не знав. Ніхто не перевіряв. Пайплайни працювали — отже, питань ні в кого не виникало. У цьому й полягає тихий жах роботи з безпекою: її не видно рівно до тієї миті, коли її стає видно. А ця мить зазвичай має вигляд наради, на якій ти пояснюєш, як пароль у відкритому вигляді чотирнадцятимісячної давнини опинився там, де його бути не мало.

Аудит, про який мене ніхто не просив

Мені цього не доручали. Мені просто набридло не знати. Тому я витягнув усі змінні з усіх пайплайнів і прочитав їх по одній. П'ятдесят п'ять записів. Половина — беззмістовне сміття, посилання на ресурси, яких давно немає. А серед цього шуму — дванадцять справжніх, живих секретів відкритим текстом: паролі від баз, API-ключ, креди до storage. Речі, витік яких коштує тобі не зіпсованого дня, а звіту про інцидент.

І ось що робить ситуацію гіршою, ніж це звучить: це були не тестові пайплайни. Це був прод, який працював місяцями й ганяв реальні дані. Креди працювали — отже, система була "в нормі". Ось вона, пастка: секрет у плейнтексті не дає взагалі жодних симптомів рівно до тієї хвилини, коли видає їх усі й одразу.

Чому ручний аудит — це вже брехня

Стандартна відповідь на все це — квартальний security review. Хтось заходить у консоль, руками перевіряє IAM, по черзі проклацує security-групи й заносить усе в таблицю. До моменту, коли він зберігає цей файл, він уже художня література. Поки тривала перевірка, хтось підняв новий ресурс. Хтось змінив storage account. Аудит — це фотографія минулого, якого вже немає.

Ручний security review не масштабується, і, що гірше, він бреше тобі в обличчя не змигнувши. Він ставить зелену галочку системі, яка змінилася просто під час перевірки. Якщо твоя безпека живе в таблиці — ти вже відстав. Бо атакувальники не чекають на твоє квартальне рев'ю.

У мене є сертифікат CEH. Не заради бейджа в LinkedIn — я його отримав, бо хотів думати так, як думають ті, хто експлуатує саме таку лінь. І чесна правда в тому, що секрети у відкритому вигляді у змінній білда — це не якась екзотична поверхня атаки. Це перше, що шукає будь-хто.

Що я зробив насправді

Саме прибирання було зовсім не ефектним і зайняло приблизно тиждень:

  • Усе поїхало в Azure Key Vault. Більше жоден секрет не живе сирою змінною пайплайну.
  • Автентифікація через managed identity. Пайплайн доводить, хто він, і забирає потрібне — жодних вічних кредів у полі налаштувань.
  • 12 секретів із плейнтексту зашифровані й прибрані за RBAC. Доступ тепер — це рішення, а не значення за замовчуванням.
  • Налаштована автоматична ротація. Історія з чотирнадцятимісячним паролем більше фізично неможлива — ніщо не живе достатньо довго, щоб нею стати.
  • 30 невикористовуваних змінних видалені під корінь. Мертвий конфіг — це поверхня атаки без жодного плюса.

Я зробив аудитором сам пайплайн

Разове прибирання розв'язує проблему рівно на один день. Сенс у тому, щоб зробити поганий стан неможливим до повернення. Тому я вшив перевірки в сам пайплайн — жорсткими гейтами, не warning-ами, а справжніми блокерами, які зупиняють білд:

  • Terraform compliance-перевірки запускаються до будь-якого деплою, ловлячи помилки конфігурації в джерелі, а не коли вони вже в проді.
  • Сканування секретів на кожному коміті. Кред у дифі просто не доїде до main.
  • AWS Security Hub збирає знахідки по всіх акаунтах, а кастомні сканери на Python закривають ті правила комплаєнсу, під які немає готового інструмента.

Відкриті security-групи, надто широкий IAM, незашифрований storage, публічні бакети, відсутність логування — усе ловиться автоматично, за хвилини, а не раз на рік, коли приходить аудитор.

Фраза, до якої я весь час повертаюся

Вразливість без плану усунення — це просто тривога. Вразливість, яку взагалі ніхто не шукає, — це зворотний відлік.

П'ятдесят п'ять змінних. Чотирнадцять місяців. Ніхто не дивився — поки не подивився я. У цьому вся різниця між security-інцидентом і прибиранням у середу по обіді. Тож поставлю тобі те саме незручне запитання, що поставив собі: коли востаннє хтось справді перевіряв змінні твоїх пайплайнів?