Управління секретами в GitOps: де розривається контур доставки
Типова картина: поруч із маніфестами в репозиторії лежить файл, де паролі, токени та ключі записані відкритим текстом. Розгортання з цього репозиторію проходить зеленим, усе працює — до першого аудиту, звільнення інженера або зміни підрядника.
Проблема не в одному файлі. Облікові дані лежать у маніфестах відкритим текстом: підключення до баз, доступи до зовнішніх сервісів, ключі шифрування — усе відкрито для будь-кого, хто має доступ до репозиторію.
Права на них видані вручну: інженер заходить у панель, створює обліковий запис, видає роль і ніде це не фіксує. Ротації немає — ключ живе роками, і ніхто не скаже, скільки його копій уже розійшлося по локальних машинах і резервних копіях.
Історія комітів пам’ятає все: навіть якщо видалити файл і закомітити очищену версію, значення залишиться в історії секретів у комітах — тобто в кожному клоні репозиторію в кожного, хто його колись робив.
Витік облікових даних із репозиторію розкривається не одразу: логи показують, що ключ використовується, але не показують, що він уже поза контролем.
Найдорожче це дається взнаки в момент передачі: іде інженер або змінюється підрядник, і ніхто не може перелічити живі доступи, кому вони видані та що зламається при відкликанні.
Залишається ручна звірка панелей із репозиторієм — при невідстежуваній ротації та без гарантії, що старі ключі вже недійсні.
Розбираємо, як це закривається: як секрети проходять через той самий контур доставки, що й інші маніфести, але при цьому ні в репозиторії, ні в його історії не залишається відкритих значень.
Що змінюється після впровадження: швидкість, доступ, відмови
Перехід на управління секретами через Git помітний не за кількістю інструментів, а за трьома змінами: середовища стають відтворюваними, ротація перестає бути ручною операцією, а розходження конфігурації перестає валити сервіси.
Відтворюваність середовищ
Контур піднімається з репозиторію повністю: маніфести, політики доступу та зашифровані значення лежать поруч і версіонуються. Тестове середовище отримує ту саму структуру секретів, що й продуктивне, відрізняються лише значення, тому поведінка збігається.
Час відновлення сервісу після аварії впирається в застосування маніфестів, а не в пошук паролів по чатах і нотатках.
Керована ротація без зупинки сервісів
Зміна ключа або пароля перестає бути ручним обходом сервісів. Значення змінюється в зашифрованому файлі або в зовнішньому сховищі, оператор синхронізації підтягує нову версію, застосунок забирає її в міру оновлення пода.
Старий секрет відкликається окремим кроком — залишається вікно, коли чинні обидві версії, і викатка проходить без простою.
Знятий клас відмов
Розходження конфігурації між середовищами закривається тим, що джерело правди одне. Зміна проходить рев’ю і потрапляє в Git, а не в кластер руками, тому не буває «зміну внесли на проді й забули про стейдж».
Якщо фактичний стан розійшовся з описаним, синхронізація повертає його до репозиторію, і інцидент не розростається.
Порівняння підходів: шифрування в репозиторії та зовнішні сховища
Обидва підходи прибирають ручне створення секретів у кластері, але платять за це різним. Шифрування файлів залишає ключ розшифрування всередині кластера і потребує перешифрування при кожній ротації; зовнішнє сховище додає мережеву залежність і другий контур відмовостійкості. Вибір визначають кількість кластерів, частота ротації та вимога довести, хто і коли читав значення.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Шифрування файлів у репозиторії (SOPS, Sealed Secrets) | один-два кластери, невелика команда, десятки секретів | ключ розшифрування все одно в кластері; відкликання доступу — перешифрування всіх файлів |
| Зовнішнє сховище та оператор синхронізації (ESO) | мультикластер, кілька команд, ротація за розкладом | потрібен відмовостійкий контур сховища і мережева доступність; свій клас відмов |
| Гібрид: завантажувальні секрети в репозиторії, робочі — у зовнішньому | доступи до сховища та первинна ініціалізація | два набори прав і дві процедури ротації |
Чим платять за шифрування файлів у репозиторії
Ключ розшифрування живе в кластері, тому розділення прав на розшифрування виходить грубим: доступ до простору імен відкриває всі секрети в ньому. Ротація — це перешифрування всіх файлів і новий коміт, а попередні версії шифротексту залишаються в історії репозиторію. Діфи нечитабельні: рев’ю показує зміну блоба, а не зміну значення.
Коли виправдане зовнішнє сховище
Сховище виправдане, коли секретів сотні, кластерів більше двох, а ротація йде за розкладом: відкликання доступу миттєве, журнал звернень фіксує читання. Ціна — мережевий доступ стає критичним шляхом: якщо оператор не кешує значення, недоступність сховища зупиняє викатку.
Етапи впровадження: аудит, схема, налаштування, перевірка, передача
Порядок робіт спирається на принцип: спочатку фіксуємо фактичний стан, потім проєктуємо контур і лише потім змінюємо робочі середовища. Секрети переносяться по одному, тому релізи не зупиняються.
Як виглядає аудит поточного стану
Інвентаризація займає один-два дні й не потребує доступу до значень самих секретів. Збираємо, де вони лежать зараз — змінні середовища, файли на серверах, значення в репозиторіях, ручні записи в базах, — хто їх читає, що відбувається при ротації та в кого на руках майстер-ключі.
На виході — карта залежностей і перелік місць, де секрет потрапляє у відкритому вигляді: історія комітів, логи збірки, дампи конфігурації.
- Аудит поводження з секретами — карта залежностей, точки витоку, критичні сервіси.
- Схема контуру доставки — що шифрується в репозиторії, що живе в зовнішньому сховищі, як значення потрапляє в под.
- Налаштування політик доступу — ролі, простори імен, область видимості ключів.
- Міграція наявних секретів — по одному, з тимчасовою паралельною роботою старої та нової схеми.
- Вбудовування в конвеєр збірки та релізу — перевірки на потрапляння відкритих значень у коміт.
- Перевірка відмови та відновлення — рестарт, втрата вузла, відкликання ключа, відкат релізу.
- Передача контуру команді — доступи, регламент ротації, розбір із черговими.
Як проходить приймання контуру замовником
Приймання — це прогін сценаріїв на копії контуру, а не демонстрація: додаємо секрет, змінюємо значення, відкликаємо доступ, виводимо з ладу один вузол і дивимося, чи відновлюється видача.
Замовник повторює ключові сценарії разом із нашими інженерами, отримує журнал перевірок і регламент ротації — після цього контур вважається прийнятим.
Схеми доступу, політики ротації та документація контуру
Пакет документації збираємо так, щоб чергова зміна і новий інженер розібралися в контурі без нас. Матеріали лежать поруч із маніфестами в тому самому репозиторії та змінюються через перевірку, а не листом у пошті.
- Схема контуру: середовища та межі довіри, які сховища секретів підключені до репозиторію та як пов’язані між собою.
- Політики доступу: ролі на читання та запис, розмежування за середовищами, принцип найменших прав, порядок видачі та відкликання доступу.
- Регламент ротації: таблиця секретів із періодом заміни, порядок зміни ключа шифрування, хто запускає ротацію та за якими ознаками підтверджує результат.
- Інструкція з відновлення: що робити при втраті кореневого ключа або компрометації — від відкликання значень до перевірки, що навантаження отримали нові.
- Документація середовища: перелік просторів імен, прив’язка сервісів до сховищ, призначення змінних, дії при розходженні.
- Матриця відповідальності: хто володіє контуром, хто чергує, до кого йти при інциденті.
Як ці матеріали живуть після передачі
Документи версіонуються разом із маніфестами: зміни до них проходять таку саму перевірку, тому інструкція не розходиться з фактичним станом контуру. Раз на квартал звіряємо регламент ротації з журналом змін — якщо секрет замінювали поза графіком, причина потрапляє в документ.
Відновлення окремо перевіряємо на навчальному контурі. Якщо кроки не сходяться, правимо інструкцію, а не домовляємося на словах. Так пакет залишається робочим інструментом, а не папкою, відкритою один раз при прийманні.
Кейс: виведення секретів із репозиторію без простою сервісів
Контур із трьох кластерів і півсотні сервісів тримав секрети прямо в репозиторіях: токени баз, ключі зовнішніх систем, сертифікати. Читати їх міг будь-хто з доступом до проєкту, а історія правок зберігала старі значення.
Переводили поетапно — спочатку пілот на некритичних сервісах, потім робочі, — щоб не зупиняти сервіси.
Що було до
Ротація одного ключа розтягувалася на два-три тижні: правку готували руками, погоджували, чекали вікно обслуговування і перезапускали сервіси. Відкат зміни означав відновлення з резервної копії та звірку значень вручну, поки частина контуру працювала зі старим ключем.
Заміри до: поза репозиторієм — нуль секретів, середня ротація — 18 днів, простій при викатці — до 40 хвилин.
Що стало після
Шифрування в репозиторії закрили через Sealed Secrets: розшифрування можливе лише в кластері, а застосунки отримують значення за ролями. Ротація в робочому контурі — один коміт у захищену гілку, значення розходиться по всіх кластерах за десятки хвилин без зупинки сервісів.
Відкат — звичайний revert коміту, перевірка на бойовому контурі йде на пілоті раніше за робочі кластери.
«Ми перевіряли схему на бойовому контурі на кожному кроці: спочатку пілот, потім робочі. Головне — ротація перестала бути подією з простоєм і вікном обслуговування», — інженер команди.
Як ротувати секрети в GitOps, не зупиняючи сервіси?
Секрет потрапляє в pod не сам по собі: його підставляє агент, а застосунок читає змінну при старті. Отже, ротація — це не заміна значення в сховищі, а послідовність: спочатку випускаємо другу версію, потім перемикаємо споживачів, і лише після цього відкликаємо стару.
Ключовий прийом — вікно перекриття доступів. У сховищі одночасно живуть дві версії: нова та попередня, ще чинна. Застосунок отримує нову через External Secrets Operator, а стара залишається робочою, поки останній екземпляр не перейде на нову.
Якщо один pod відстав або тримає з’єднання із зовнішнім ресурсом, він продовжує працювати — ротація без простою тримається саме на цьому перекритті.
Далі — перевірка живучості. Поди замінюються по черзі, не більше одного за раз: проба готовності та реальний запит до залежного ресурсу підтверджують, що новий доступ справді прийнято. Лише коли весь набір відповідає, вікно ротації закривається і стара версія відкликається.
Якщо перевірка не пройшла, спрацьовує автоматичний відкат: повертаємо попередню версію секрету, поди перечитують її, стан стабілізується, а інженер отримує повідомлення з причиною. Невдала ротація перетворюється на один зайвий перезапуск замість простою.
Практика проста: ротуємо по одному сервісу, вікно перекриття тримаємо коротким, час обираємо поза піком навантаження і ведемо журнал випущених версій. Ротувати все одразу — найнадійніший спосіб отримати той самий простій, якого ми уникаємо.
Інженерні сумніви: шифрування, доступ, відкат, аудит
Технічні заперечення в команд замовника майже завжди ті самі, тому відповідаємо порядком дій і межами застосовності, а не обіцянками. Схема працює там, де секрети описані декларативно і з’являються в кластері з git або зовнішнього сховища.
Хто і де розшифровує секрет?
Залежить від інструмента. Sealed Secrets розкриває значення лише контролер усередині кластера — приватний ключ не потрапляє ні в репозиторій, ні на робочі станції інженерів. SOPS зберігає шифротекст у git і розкриває його ключем age або GPG на етапі застосування.
External Secrets Operator значень у репозиторії не тримає: у git лежить посилання на запис у зовнішньому сховищі, а об’єкт збирається в кластері.
Як розмежувати права між командами та середовищами?
Права діляться на два контури: доступ до git і доступ до розшифрування. У репозиторії працюють обов’язкове погодження та CODEOWNERS за каталогами середовищ, а ключі розшифрування видаються окремо на кожен стенд.
Тоді розробник править маніфест тестового середовища, але не може розкрити секрети промислового контуру.
Що відбувається при відкаті на попередній реліз?
Відкат — це revert коміту: попередня версія секрету повертається тим самим застосуванням, що й будь-яка інша зміна. Умова одна — значення має залишатися в джерелі.
Контролер кластера або зовнішнє сховище тримають історію версій, інакше відкат поверне посилання без даних, і под із секретом не підніметься.
Як влаштований аудит доступу до секретів?
Аудит зшивається з трьох журналів: історія комітів і автор зміни в git, журнал звернень до API кластера, журнал видач у зовнішньому сховищі. За назвою секрету та часом видно, хто змінював об’єкт, який контролер його прочитав і чи був доступ поза звичайним контуром.
Секрети, які не можна покласти в git навіть зашифрованими — кореневі токени, початкова конфігурація, ключі самого сховища, — виносимо в окремий контур ручного введення і в репозиторій не переносимо.
Обговоримо задачу і повернемося з оцінкою та планом робіт
Секрети в GitOps ламаються не на етапі встановлення контролера, а на стиках: розшифрування всередині кластера, ротація, права службових облікових записів, поведінка при відкаті на попередню ревізію.
Щоб оцінка обсягу була предметною, а не «плюс-мінус», починаємо з розбору поточної схеми — як вона влаштована у вас зараз.
Що розбираємо на дзвінку:
- Розбір поточної схеми: де джерело правди для секретів, як вони потрапляють у репозиторій, що і на якому кроці розшифровується.
- Точки відмови: зберігання ключів шифрування, доступи службових облікових записів, розходження між середовищами, сценарій відкату.
- Порівняння варіантів — Sealed Secrets, SOPS, зовнішній оператор секретів — з обмеженнями кожного стосовно вашої схеми, а не в загальному вигляді.
- Порядок кроків: що переносимо першим, де залишаємо ручний контур на перехідний період, як перевіряємо, що секрет доїхав.
- Оцінка обсягу: склад правок у маніфестах і ролях, регламент ротації, зона відповідальності за ключі.
- Що залишається в команди: документація, шаблони секретів, перевірки в конвеєрі постачання до застосування змін.
Такий розбір займає одну розмову і одразу показує, де ви вже закриті, а де залишається ручна робота. Опишіть задачу — поточний контур, масштаб і обмеження за доступами. Повернемося з оцінкою та планом робіт.







