
Переменные окружения помогают отделить настройки приложения от исходного кода, но сами по себе не защищают секреты. Чтобы не добавить ключи в репозиторий, заранее разделите локальные файлы, безопасный шаблон и настройки CI или production, исключите секретные файлы через .gitignore и передавайте чувствительные значения через менеджер секретов или защищённое хранилище платформы.
Опорные правила безопасной работы с конфигурацией
- Считайте секретом любое значение, которое даёт доступ к данным, учётной записи или инфраструктуре.
- Храните реальные локальные значения отдельно от репозитория; в репозитории оставляйте только шаблон с названиями переменных.
- Добавьте правила исключения файлов до того, как создадите файл с секретами.
- Не переносите production-ключи в локальную разработку и тестирование.
- При утечке сначала отзовите или замените ключ, затем разбирайтесь с историей Git.
- Проверяйте новые изменения на утечки до слияния и публикации.
Проверьте, какие значения действительно считаются секретами
Инструкция подходит командам и индивидуальным разработчикам, которые хранят настройки приложения в Git и запускают его локально, в CI или на сервере. Она особенно полезна, если в проекте есть токены, пароли, ключи API или строки подключения.
Секретом обычно является значение, раскрытие которого может дать доступ к сервису или данным. Адрес публичного API, название режима запуска или порт приложения часто не секретны, но их всё равно стоит настраивать отдельно, если они различаются между средами. Не помещайте в переменные окружения данные, которые приложение может безопасно получать из открытой конфигурации.
Разделите локальные настройки, шаблоны и конфигурацию среды
До начала работы подготовьте три независимых источника конфигурации:
- Локальный файл - например,
.envс тестовыми значениями для запуска на компьютере. Он не должен попадать в Git. - Шаблон - например,
.env.exampleтолько с именами переменных и безопасными пояснениями. - Настройки среды - переменные для тестирования и production, задаваемые через CI/CD или инфраструктурную платформу.
Заранее уточните, как приложение загружает переменные окружения, кто управляет доступом к CI и production, где хранится конфигурация и кто может её менять. Для локальной разработки используйте отдельные тестовые учётные данные, если они нужны: не копируйте production-ключи на рабочие станции.
Настройте .gitignore до создания первого файла с секретами
Сначала проверьте правила репозитория, затем создавайте локальные файлы конфигурации. Мини-чеклист подготовки:
- Определите имена файлов и переменных, которые использует приложение.
- Найдите существующие правила в корневом и вложенных файлах
.gitignore. - Уточните, какой шаблон конфигурации нужен коллегам для запуска проекта.
- Убедитесь, что для тестирования и production предусмотрены отдельные значения.
-
Добавьте исключения в .gitignore. Укажите локальные файлы конфигурации и варианты, используемые инструментами проекта. Синтаксис и имена адаптируйте к репозиторию:
.env .env.* !.env.exampleПравило с отрицанием оставляет шаблон отслеживаемым Git, но не отменяет более широкие правила, заданные в других файлах исключений. Проверьте итоговое поведение перед коммитом.
-
Создайте безопасный шаблон. В
.env.exampleперечислите нужные имена переменных, но не вставляйте реальные значения:APP_MODE=development API_TOKEN= DATABASE_URL=При необходимости добавьте комментарии с инструкциями о том, где получить тестовое значение.
-
Проверьте, что локальный файл игнорируется. Создайте
.envтолько после настройки исключений и выполните проверку Git:git check-ignore -v .envКоманда должна показать правило, из-за которого файл исключён. Если файл уже отслеживается, одного добавления в
.gitignoreнедостаточно. -
Проверьте состав изменений перед коммитом. Просмотрите список и содержимое подготовленных файлов:
git status --short git diff --cachedУбедитесь, что в индекс не попали локальная конфигурация, логи, дампы базы данных или файлы с учётными данными.
- Документируйте настройку для команды. Укажите в README, как скопировать шаблон в локальный файл и где получить тестовые значения. Не публикуйте в документации сами ключи или доступы.
Передавайте переменные окружения через менеджер секретов
Для CI и production задавайте чувствительные значения в защищённом хранилище платформы или через менеджер секретов для разработчиков. Переменная должна быть доступна только нужному заданию или среде, а не всем пользователям и процессам без необходимости. Это практический способ организовать управление переменными окружения без коммита секретов в репозиторий.
Проверьте результат внедрения по списку:
- Сборка приложения получает нужные переменные без файла с production-секретами в репозитории.
- Для локального запуска используются отдельные значения, не совпадающие с production.
- Секреты CI доступны только необходимым заданиям и окружениям.
- В журнале сборки не выводятся значения переменных и команды, раскрывающие секреты.
- Для тестирования и production настроены разные наборы учётных данных.
- Доступ к хранилищу ограничен по ролям и рабочим задачам.
- В инструкции для разработчиков описано, как получить доступ, не размещая ключи в чате или коммитах.
- Известно, кто и каким способом заменяет или отзывает ключ при утечке.
Пример для CI: задайте API_TOKEN в настройках секретов проекта, а в конфигурации задания укажите только имя переменной. Не вставляйте значение токена в YAML-файл, который хранится в Git.
Проверьте историю Git и удалите случайно опубликованные ключи
Удаление строки из текущей версии файла не делает ранее опубликованный ключ безопасным: значение может остаться в коммитах, копиях репозитория или журналах сборки. При подозрении на утечку действуйте так:
- Отзовите или замените опубликованный ключ через сервис, который его выдал.
- Проверьте, где он мог использоваться: репозиторий, CI, журналы, образы и резервные копии.
- Удалите секрет из текущей версии кода и перенесите его в защищённое хранилище.
- Оцените необходимость очистки истории Git и согласуйте переписывание истории с командой.
- Проверьте доступы и журналы сервиса на подозрительное использование, если они доступны.
Частые ошибки, которых стоит избегать:
- Добавлять файл в
.gitignoreи считать, что уже отслеживаемый файл удалён из индекса. - Удалять ключ из последнего коммита, но оставлять его действующим.
- Считать приватный репозиторий надёжным местом для секретов.
- Публиковать реальные значения в шаблоне, README, задаче или сообщении в чате.
- Передавать production-ключи в локальную среду для удобства отладки.
- Печатать переменные окружения целиком в логах CI при диагностике.
- Переписывать историю Git без предупреждения: это может нарушить работу коллег и автоматизации.
Если секрет попал в удалённый репозиторий, сначала отзовите его. Очистка истории снижает риск повторного обнаружения значения, но не заменяет отзыв ключа.
Добавьте проверку утечек секретов в рабочий процесс
Выберите подход, подходящий размеру команды и способу сборки проекта:
- Локальный Git-хук. Подходит как раннее предупреждение до коммита. Не считайте его единственной защитой: проверку можно обойти.
- Проверка в CI. Уместна, когда изменения проходят автоматическую сборку. Настройте остановку или уведомление при обнаружении подозрительного значения и проверьте, что отчёт не раскрывает его.
- Сканирование репозитория. Полезно для проверки новых изменений и доступной истории. При обнаружении секрета применяйте процедуру отзыва, даже если значение уже удалено из текущего файла.
- Политика доступа и ротации. Подходит командам, которые регулярно меняют ключи и управляют несколькими средами. Определите владельцев секретов и порядок выдачи, замены и отзыва доступа.
Система управления секретами не отменяет безопасную работу с Git: шаблоны должны оставаться без чувствительных значений, а журналирование и права доступа - быть ограниченными. Так хранение переменных окружения в проекте остаётся понятным для команды и не превращает репозиторий в хранилище ключей.
Разбор спорных случаев: .env, CI и уже опубликованные ключи
Можно ли добавить .env.example в репозиторий?
Да, если в файле только имена переменных и безопасные пояснения. Перед коммитом проверьте, что в шаблон не попали действующие ключи, пароли или строки подключения с доступом.
Надёжно ли хранить .env в приватном репозитории?
Нет: приватность репозитория не делает его хранилищем секретов. Доступ к репозиторию может расшириться, а значения - попасть в копии или историю, поэтому используйте отдельное защищённое хранилище.
Нужно ли добавлять все переменные в .gitignore?
Нет, в Git исключают файлы, которые содержат локальные секреты, а не сами переменные окружения. Безопасные шаблоны и конфигурацию без чувствительных значений можно хранить в репозитории.
Что делать, если секрет попал в коммит, но коммит не отправляли?
Удалите значение из подготовленных изменений и проверьте индекс и текущую версию файла. Если ключ мог стать доступен кому-либо ещё или его происхождение неясно, отзовите его и выпустите новый.
Достаточно ли удалить опубликованный ключ из файла?
Нет. Сначала отзовите или замените ключ у выдавшего его сервиса; затем проверьте историю Git и другие места, куда значение могло попасть.
Можно ли передавать секреты в CI через файл?
Это зависит от платформы и способа создания файла, но файл не должен попадать в репозиторий, артефакты или логи. Предпочтительно использовать встроенное защищённое хранилище и выдавать значение заданию только на время выполнения.
Стоит ли использовать менеджер секретов локально?
Это уместно, если команде нужно централизованно выдавать и отзывать доступы или работать с несколькими средами. Для небольшого локального проекта допустим игнорируемый файл с тестовыми значениями, если он не содержит production-секретов.