Страница CI/CD переменных — это кладбище забытых секретов. Я знаю, потому что только что провёл аудит.

55 переменных. Столько я нашёл, когда открыл настройки GitLab CI/CD для production-сервиса. Строки подключения в открытом виде. Устаревшие пароли, которые никто не помнит, зачем создавал. Дублирующие токены с чуть разными именами. Красивый бардак, который все боялись трогать.

Знакомо?

Проблема, о которой никто не говорит

Вот какая штука с CI/CD переменными: они накапливаются как пыль. Каждый разработчик, касающийся пайплайна, добавляет "ещё одну переменную." Никто не удаляет, потому что никто не знает, что сломается. Через полгода у тебя 55 переменных, половина из которых — призраки.

Но это хуже, чем бардак. Это — угроза безопасности.

Строки подключения лежат в UI GitLab. Даже "замаскированные" — они в одном неправильно настроенном джобе от утечки в логи. Креденшалы Service Principal, которые ротируются... никогда. Пароли к базам данных, которые вывели из эксплуатации два спринта назад.

Это не DevOps. Это тикающий инцидент-репорт.

Аудит

Я сделал то, что никто не хотел. Прошёл каждую переменную. Одну за одной. Сверился с реальным YAML пайплайна. Сверился с PowerShell-скриптами деплоя. Составил карту: кто что использует, где и зачем.

Результат?

  • 25 переменных — активно используются, необходимы для деплоя
  • 30 переменных — мертвы. Не используются. Легаси. Забыты.
  • 4 из этих 30 — реальные строки подключения, которые надо было ротировать месяцы назад

55% "конфигурации" пайплайна было мусором. Больше половины.

Миграция: из переменных в Vault

Строкам подключения не место в CI/CD переменных. Точка. Им место в Azure Key Vault — централизованном, с контролем доступа, аудируемом, ротируемом.

Паттерн миграции:

До: Пайплайн читает строку подключения из GitLab-переменной. Плейнтекст. Управляется вручную. Ротируется... когда кто-то вспомнит.

После: Пайплайн аутентифицируется в Azure через UAMI (User-Assigned Managed Identity), получает секрет из Key Vault в рантайме, использует, забывает. Никакого плейнтекста в пайплайне. Никакой ручной ротации. Никаких "кто менял эту переменную в прошлый вторник?"

Реализация удивительно чистая:

  1. Храним имена секретов (не значения) в YAML пайплайна — это просто ссылки, не секреты
  2. Аутентифицируемся в Azure через федеративные токены — ноль хранимых креденшалов
  3. Получаем секреты динамически при деплое — az keyvault secret show
  4. Используем и забываем

Красота в том, что UAMI означает: пайплайн не хранит ни одного Azure-креденшала. Никаких паролей Service Principal. Никаких client secret. Идентити управляется самим Azure. Пайплайн просто говорит "я тот, кто я есть" — и Azure верит, потому что есть OIDC federation trust.

Почему UAMI, а не Service Principal

Service Principal — это изолента Azure-аутентификации. Работают, да. Но с багажом:

  • Client secret, которые истекают и ломают пайплайн в 3 часа ночи
  • Церемонии ручной ротации, которых все боятся
  • Креденшалы, хранящиеся в очередной CI/CD переменной (что обнуляет смысл)

UAMI переворачивает модель. Идентити назначается раннеру, управляется Azure, аутентифицируется через OIDC-федерацию. Без секретов. Без ротации. Без инцидентов в 3 ночи, потому что кто-то забыл обновить пароль.

Zero-trust — не маркетинговый термин, когда ты реально это внедряешь.

Зачистка

После миграции секретов в Key Vault я удалил устаревшие переменные. Четыре строки подключения, которые месяцами лежали в GitLab — нет их больше. Затем предложил очистку оставшихся 26 неиспользуемых переменных после ревью скриптов.

Пайплайн даже не дрогнул. Потому что пайплайну они никогда не были нужны.

Самое трудное в зачистке — осознать, сколько из твоей "критической конфигурации" — это просто остатки чьего-то эксперимента двухлетней давности.

Чему я научился

Управление секретами — не разовый проект. Это гигиена. Как чистить зубы — скучно, рутинно, но пропусти — и всё сгниёт.

Каждый пайплайн заслуживает аудита. Не раз в год для галочки комплаенса. Регулярно. Потому что переменные накапливаются, секреты стареют, а то, что было "временным" в Sprint 12, становится постоянным техдолгом к Sprint 30.

Количество переменных в пайплайне обратно пропорционально уровню безопасности команды. Меньше переменных — чище архитектура.

55 переменных. 25 выживших. Один Key Vault. Ноль секретов в пайплайне.

Так и должно быть.