Намного лучше, чем простой .env

Полгода назад я рекомендовал всем перестать использовать файлы .env в пользу подходов, использующих платформы управления секретами. С тех пор я узнал и научился намного большему, как эффективно управлять переменными окружения. В этой статье я снова аргументирую, почему мы должны уменьшить практику хранения всех переменных окружения в файле .env и перейти к более комплексному подходу для их управления в локальной разработке, который лучше, чем простой .env.

Прежде чем вы меня начнете критиковать, я хочу сказать, что моя позиция не заключается в том, что вам нужно полностью избавиться от файла .env. Я утверждаю, что переменные окружения вашего приложения не должны храниться непосредственно в файле .env. Это не означает, однако, что вы не можете хранить в нем токен, который будет подгружать остальные переменные окружения во время выполнения.

Кстати, хочу также отметить, что эта статья предназначена для команд разработки программного обеспечения, а не для команд по безопасности и DevOps, которые уже разобрались в этом вопросе.

Не чините то, что не сломано

В начале разработчики жестко хардкодили переменные окружения в свой код. После того, как стало понятно, что хардкодить их в систему контроля версийнебезопасно, мы ввели файлы появились .env для разделения ответственности, то есть для отделения чувствительных данных от остального кода.

На практике создают .env файлы, добавляли туда переменные окружения и добавляли этот файл в .gitignore. Затем запускаются приложения и переменные окружения считываются из файлов во время локальной разработки и в продакшне. До сих пор у разработчиков это считается основополагающем аспектом, и сторонники этого подхода часто говорят: «не чините то, что не сломано».

Если вы из таких упрямых сторонников, то прекратите чтение; если вы открыты для улучшений и готовы нарушить традицию, продолжайте.

У разработчиков есть нерешенные проблемы

В основе проблемы с файлами .env лежит их несовершенство, и мы все сталкивались с этим в разной степени, в зависимости от масштаба наших приложений и инфраструктуры; об этом знают люди из отделов безопасности и DevOps. Чтобы понять мой аргумент о том, почему текущее использование файлов .env неэффективно, важно забыть о привычных подходах и разбить управление переменными окружения локально на первоначальные принципы. Давайте рассмотрим, что нужно разработчикам:

  • Надежность: Мы хотим убедиться, что у разработчиков всегда есть доступ к правильным переменным окружения. Зачастую разработчики добавляют новые переменные окружения и забывают сообщить об этом другим членам команды. В результате приложения запускаются и… выходят из строя.
  • Безопасность: Мы хотим хранить наши переменные окружения в безопасности. Не добавлять их в систему контроля версий. Мы хотим защитить переменные окружения от злоумышленников. В этой статье фокус делается на файлах .env, которые обычно используются в разработке. Содержат менее критичные переменные окружения.

Обратите внимание, что мои аргументы выше обобщаются на все этапы разработки. От разработки до продакшена, и эти требования растут с увеличением масштаба и сложности инфраструктуры приложения. В любом случае, мы стремимся к надежности и безопасности при работе с переменными окружения. Нам нужны правильные переменные окружения в правильных руках и местах надежных хранилищах.

Что не так с файлами .env?

Хотя файлы .env предотвращают хардкодинг и коммит переменных окружения в системе контроля версий, они полностью не удовлетворяют критериям надежности.

Когда в команде два человека, поддерживать файлы .env легко. Потому что вам не нужно делиться переменными окружения с множеством других разработчиков. Но с увеличением размера команды вы начинаете сталкиваться с проблемой рассеивания секретов. И становится неудобно вручную делиться переменными окружения.

Возьмем, например, архитектуру микросервисов, где у каждого сервиса есть свой набор переменных окружения. Здесь разработчики часто сталкиваются с явлением, известным как рассеивание секретов, когда переменные окружения разбрасываются по всей инфраструктуре, и их сложно управлять.

Разработчикам нужно централизовать управление переменными окружения

Естественным образом, решение заключается в хранении переменных окружения в одном централизованном месте. Дать разработчикам извлекать их оттуда для использования в своих приложениях. Оказывается, что это действительно то, что делают большие команды. Но даже в этом случае есть некоторые вариации. Иногда команды хранят переменные окружения в менеджерах паролей. Иногда — шифруют их и хранят напрямую в закрытом репозитории на GitHub.

Такие методы работают, но, как правило, они вводят дополнительный шаг. Который заключается в ручном извлечении или обновлении переменных окружения перед запуском приложения. Вы можете написать собственный скрипт, который будет извлекать секреты и внедрять их в приложение. Но это вносит дополнительные неудобства.

Разработчикам нужен инструмент без лишних затрат, который автоматически извлекает и добавляет переменные окружения в приложение. Для этого более продвинутые команды используют специальный инструмент, который называется менеджером секретов. Предназначенным для управления переменными окружения. Решения Infisical, Vault, AWS Parameter Store, Google Secret Manager, помогают безопасно хранить переменные окружения. И надежно предоставлять их вашей инфраструктуре. При правильной настройке эти инструменты могут эффективно предоставлять переменные окружения в сложной микросервисной инфраструктуре. От локальной разработки через CI/CD-пайплайны до продакшена.

Разработчики просто не знают об этом лучшем подходе

К сожалению, за пределами отдела безопасности и DevOps большинство разработчиков никогда не слышали о менеджерах секретов, и это можно понять по количеству просмотров видео на YouTube на тему управления секретами по сравнению с любыми другими темами. Давайте будем честны, управление секретами не считается таким увлекательным темой, как искусственный интеллект или ChatGPT.

Причина непопулярности менеджеров секретов заключается в их неудобстве. Да, инструменты, созданные для решения проблемы рассеивания секретов, о которой я упоминал ранее, исторически вносили новые проблемы с нежелательными характеристиками. С одной стороны, возникают сложности с началом работы; никто не хочет смотреть курсы и читать десятки страниц документации, чтобы выучить основные концепции хранения и извлечения переменных окружения из менеджера секретов. С другой стороны, простые инструменты являются закрытыми и, хорошо, как им можно доверять?

Ладно, я знаю, что теперь меня подвергнут критике фанаты Vault, но давайте будем реалистами. Если бы какой-либо инструмент для управления секретами был так же прост в использовании, как установка пакета dotenv, его импортирование и запуск вашего приложения, то мы бы видели массовое принятие менеджеров секретов повсюду.

Но мы этого не видим.

Вместо этого, мы продолжаем иметь более 30 миллионов загрузок в неделю пакета dotenv только для Node.js и печальную статистику, что лишь 10% организаций по всему миру перешли на использование менеджеров секретов.

Если бы они были легки в использовании и надежны

В начале этой статьи я ясно сказал, что моя позиция не заключается в том, что вам нужно полностью избавиться от файла .env. Я утверждаю, что переменные окружения вашего приложения не должны храниться непосредственно в файле .env.

Хотя у меня есть много советов и стратегий по управлению переменными окружения, главный из них, на который я намекаю в этой статье, — это гибридный подход, заключающийся в использовании менеджера секретов в сочетании с файлом .env.

Вместо того чтобы хранить переменные окружения вашего приложения непосредственно в файле .env, вы можете хранить их в специальной платформе управления секретами, предпочтительно с минимальными накладными расходами. Затем сохраните токен доступа в файле .env, который ваше приложение может использовать для извлечения переменных окружения из менеджера секретов во время выполнения. Это простое изменение позволит улучшить надежность получения правильного набора переменных окружения в любое время для всей вашей команды.

Достаточно, покажите мне ваше рекомендацию, дайте код

Чтобы упростить вещи, я буду использовать Infisical — платформу для управления секретами с открытым исходным кодом и полностью шифрованным облачным решением, в которой вы можете хранить переменные окружения. Вы также можете использовать другой менеджер секретов, такой как Vault или AWS Parameter Store, у каждого из которых есть свои собственные SDK для использования.

Я выбираю Infisical, потому что его можно разместить на вашей собственной инфраструктуре, у него хорошая документация и отличный интерфейс. Стоит также отметить, что его можно разместить на Fly.io и Render, а также на AWS, Kubernetes и т. д.

В любом случае, мы будем использовать Node SDK для получения переменных окружения во время выполнения в этом примере, хотя также существуют другие SDK и методы.

Начало работы

Прежде чем мы сможем извлечь переменные окружения в ваше Node-приложение, вам нужно добавить их в проект в Infisical Cloud или в self-hosted версии Infisical.

Ладно, давайте начнем.

Сначала установите пакет infisical-node в ваш проект:

$ npm install infisical-node --save
Zsh

Далее импортируйте SDK и создайте клиентский экземпляр с вашим токеном Infisical:

import InfisicalClient from "infisical-node";

const client = new InfisicalClient({
  token: "your_infisical_token"
});
Python

Чтобы обеспечить оптимальную производительность, рекомендуется создать единственный экземпляр клиента Infisical и экспортировать его для использования во всем приложении. Причина в том, что Node SDK кэширует каждый секрет и периодически его обновляет, что снижает количество избыточных вызовов; этот встроенный кэширование делает синхронизацию переменных окружения безупречной при масштабировании.

Также рекомендую хранить токен Infisical в файле .env при разработке локально или в качестве единственной переменной окружения в продакшене. Таким образом, вам не нужно вставлять его в код вашего приложения. Вы сможете использовать его для извлечения остальных переменных окружения.

Теперь вы можете использовать клиент для извлечения секретов для вашего приложения по запросу:

app.get("/", async (req, res) => {
  const name = await client.getSecret("NAME");
  res.send(`Hello! My name is: ${name.secretValue}`);
});
JavaScript

Вот и все!

Когда приложение нуждается в переменной окружения, оно может запросить ее из Infisical по запросу. Теперь вы можете просматривать все переменные окружения вашего приложения в одном центральном месте. И избежать пропуска каких-либо переменных окружения.

Можно ли доверять менеджеру секретов?

Переход на использование менеджера секретов может быть сначала сложным, и это совершенно нормально. Вам нужно доверять тому, что решение, с которым вы работаете, безопасно. Поставщик не будет просматривать или изменять ваши данные. Основная инфраструктура будет работать и надежно предоставлять переменные окружения по мере необходимости. Во многих отношениях использование менеджеров секретов кажется сложнее, чем хранение переменных окружения в децентрализованном репозитории. Или, возможно, централизованном, но зашифрованном репозитории на GitHub.

Однако для каждой задачи есть подходящий инструмент. Использование специализированных средств для управления переменными окружения определенно лучше, чем любой ручной процесс. Который либо неэффективен, либо подвержен ошибкам; это особенно верно в случаях, когда ваша инфраструктура разбросана по разным местам.

Мне нравится аналогия с менеджерами паролей, такими как 1Password и Bitwarden. Раньше я был доволен управлением десятками паролей вручную и иногда их забывал. Потом у меня стало много разных паролей для разных сервисов. Каждый удовлетворял своим требованиям, но я стал забывать пароли. Это заставило меня подключиться к менеджеру паролей. Потому что я не мог постоянно нажимать кнопку «Забыть мой пароль».

То же самое относится и к менеджерам секретов. Когда вы являетесь самостоятельным разработчиком, вы можете использовать ручные подходы для хранения ваших переменных окружения. Вы начинаете масштабировать свой проект и у вас появляется команда из более пяти разработчиков. Вы должны задуматься о поддержании своей инфраструктуры управления секретами. Хотя нет 100% гарантии надежности любого процесса. Можно подойти к 99,99%, и мои рекомендации по выбору менеджера секретов таковы:

  • Выберите решение с открытым исходным кодом или созданное крупными облачными поставщиками; такое решение будет более устойчивым, и вы сможете проверить и, в случае с открытым исходным кодом, внести изменения в код при необходимости.
  • Выберите что-то, что обеспечивает хороший опыт разработчика для размера вашей команды. Если у вас есть команды ответственные за надежность сайта и процессы, вы можете позволить себе использовать более сложные инструменты. В противном случае, если вы меньшая команда, выберите решение с минимальными сложностями. Сконцентрируйтесь на создании остальной части вашего приложения.

Заключение

В течение длительного времени разработчики по умолчанию хранили все свои переменные окружения в файле .env, в основном потому, что это был наиболее безупречный способ быстро начать работу локально. Альтернативы, такие как другие платформы управления секретами, были слишком громоздкими для внедрения. Так и не стали популярными, потому что они были слишком сложны в использовании/изучении. Предназначены для группы безопасности и DevOps, а не разработчиков.

В этой статье я показал, что подход хранения всех переменных окружения в файле .env не обеспечивает надежность синхронизации переменных окружения вашей команды. Путем использования специализированного менеджера секретов, предпочтительно с низкой сложностью, и хранения только одного токена в вашем файле .env, который ваше приложение может использовать для извлечения остальных переменных окружения, вы можете сохранить преимущества безопасного отделения конфиденциальных данных от вашего кодовой базы и, в то же время, обеспечить надежность переменных окружения в вашей инфраструктуре.


Опубликовано

в

от

Метки:

Комментарии

Добавить комментарий