Как не устроить утечку секретов через Git
Пару постов назад я рассказала, что делать, если API-ключ или токен уже попал в репо, а теперь про то, как снизить вероятность этого события.
Самый очевидный вариант, конечно, не коммитить секреты. Совет прекрасный, но, увы, не рабочий 😁
Secret detection — инструменты, которые ищут потенциальные секреты в коде, конфигурациях и истории Git. Например, Gitleaks, TruffleHog или detect-secrets. Они используют регулярные выражения, проверку энтропии и другие механизмы, а некоторые умеют проверять, действуют ли найденные учётные данные. Но идеальной точности ждать не стоит: будут и ложные срабатывания, и пропущенные секреты.
В идеале действовать на нескольких уровнях:
Pre-commit. Проверяем изменения ещё до создания коммита. Это быстро и удобно: разработчик сразу узнаёт, что случайно собирается отправить в Git что-то лишнее. Минус в том, что локальные хуки можно обойти, а кто-то вообще забудет их установить.
CI. Запускаем сканирование в пайплайне и блокируем изменения при обнаружении потенциальных секретов. Здесь уже не приходится надеяться на локальные настройки каждого разработчика. При этом CI часто срабатывает после того, как коммит уже оказался на сервере, поэтому полностью предотвратить утечку он не может.
Push protection. Некоторые Git-хостинги умеют проверять изменения при отправке и отклонять push, если находят секрет. Например, такая возможность есть у GitHub. Это особенно полезно, потому что секрет не успевает попасть в удалённый репозиторий. Правда, покрытие зависит от платформы, настроек и типов секретов.
Но даже если настроить все три механизма, проблема не исчезнет полностью. Анализатор может не распознать нестандартный ключ, секрет может попасть в логи или артефакты сборки, а разработчик — обойти предупреждение. Поэтому важно думать не только о предотвращении утечки, но и о её последствиях.
Отдельные учётные данные для разных окружений. Токен для локальной разработки не должен открывать доступ к продакшену. Для dev, staging и prod лучше использовать разные секреты, которые можно отзывать независимо друг от друга.
Минимальные права доступа. Если сервису достаточно читать данные из одного бакета, ему не нужен доступ на запись ко всему хранилищу. Чем меньше возможностей у утёкшего ключа, тем меньше потенциальный ущерб. Сюда же относятся короткоживущие учётные данные и автоматическая ротация там, где это поддерживается. Например, в CI часто можно обойтись временными токенами через OIDC вместо постоянного облачного ключа, который годами лежит в переменных окружения.
Для хранения секретов лучше использовать предназначенные для этого инструменты: менеджеры секретов, защищённые переменные CI/CD и механизмы выдачи временных учётных данных. .gitignore полезен, но системой управления секретами от этого не становится.
В этом посте были ссылки, но мы их удалили по правилам Сетки