Передавать секреты, не компрометируя их
"Ключи API, доступы к базам данных, сертификаты: практики передачи секретов между командами, подрядчиками и клиентами так, чтобы не найти их в истории три года спустя."
Лучший переданный секрет тот, который не передавали
Каждый проект начинается с одного и того же ритуала: «пришли доступы?». И каждая команда импровизирует ответ, чаще всего неверный. Пароль в письме, ключ API в канале Slack, файл .env во вложении: секрет только что покинул всякий периметр контроля, навсегда.
Прежде чем искать канал получше, задайте главный вопрос: должен ли этот секрет вообще существовать в такой форме? Механизмы федеративной идентичности (OIDC между CI и облаком, роли IAM, идентичности рабочих нагрузок) заменяют статический секрет эфемерным доказательством личности. Нечего передавать, нечему утекать, нечего ротировать. Когда такая возможность есть, она побеждает: остальная часть статьи касается только секретов, которым действительно нужно перемещаться между людьми.
Каналы, которые дисквалифицируют сами себя
Некоторые каналы отпадают сразу, без обсуждений:
- электронная почта: реплицируется на серверах, которые никто не контролирует, индексируется, архивируется, пересылается;
- командный мессенджер: историю читают администраторы, её экспортируют при миграциях и хранят долго после ухода участников;
- тикет или общий документ: переживёт проект и всплывёт в полнотекстовом поиске три года спустя;
- SMS и личные мессенджеры: смешивают частный и рабочий периметры.
Общая черта: неуправляемая персистентность. Приемлемый канал обмена гарантирует ровно обратное, то есть сквозное шифрование и исчезновение.
Что работает: от простого к оснащённому
Для разовой передачи достаточно одноразовой короткоживущей ссылки, созданной аудируемым инструментом: получатель открывает, секрет самоуничтожается. Получение подтверждают по второму каналу (звонок, сообщение), что заодно подтверждает: ссылку использовал нужный человек.
Для длительного сотрудничества разовых передач уже мало: нужно общее пространство. Командный менеджер паролей с хранилищами по периметрам остаётся самым доступным вариантом; централизованный менеджер секретов (с журналом доступов и ролевыми политиками) становится уместным, как только инфраструктура это оправдывает. Критерий выбора один и тот же: можно ли узнать, кто к чему обращался, и отозвать доступ одним действием?
Схему стоит повторить: уведомление никогда не содержит секрета. Оно лишь говорит, где его забрать, со своими собственными правами.
Минимальные привилегии не паранойя, а бюджет
Каждый переданный секрет, долг: кому-то придётся о нём помнить, ротировать его, отзывать. Этот долг сокращают у источника:
- секреты по окружениям: никогда один и тот же токен в стейджинге и продакшене;
- секреты по людям и сервисам: никаких общих аккаунтов «team», за которые никто не отвечает;
- минимальные права: ключ только на чтение для задачи только на чтение;
- короткие сроки жизни по умолчанию: истечение срока лучшая из ротаций.
История Git не забывает никогда
Самая частая утечка не проходит ни по одному каналу обмена: её коммитят. .env, добавленный «временно», строка подключения в конфиге, ключ в тесте. История вечная и распределённая память: каждый клон уносит копию.
Защита строится слоями. Строгий .gitignore для файлов окружения. Сканер секретов в pre-commit и в CI, блокирующий до публикации. И одно абсолютное правило на день, когда секрет всё же попал в историю: чистки никогда не достаточно, секрет считается скомпрометированным и немедленно ротируется. Переписывание истории ограничивает будущую экспозицию, но не отменяет утечку.
Выход, часть обмена
Процесс обмена секретами оценивается по офбордингу. Уход участника команды, конец контракта, расторжение с подрядчиком запускают одну и ту же механику: отозвать именные доступы, ротировать общие секреты, к которым человек имел доступ, проверить журнал. Если этот список больно составлять, значит секреты раздавались без инвентаря, а инвентарь ровно то, что хранилище даёт бесплатно.
Чек-лист, который мы применяем
- Можно ли заменить секрет эфемерной идентичностью? Если да, заменить.
- Ни одного секрета открытым текстом в письме, чате, тикете, документе.
- Разовая передача: одноразовая ссылка, уведомление по другому каналу.
- Длительная работа: общее хранилище, ролевой доступ, журнал.
- Секрет на окружение и на человека, с минимальными правами и сроком.
- Сканер секретов в pre-commit и CI.
- Секрет в истории = скомпрометированный секрет: немедленная ротация.
- Офбординг по сценарию: отозвать, ротировать, проверить журнал.
Ничто из этого не дорого. Дорог забытый в Slack токен, который всё ещё открывает продакшен через два года после конца проекта.