Перейти к содержанию
Innovialabs

Как хранить API-ключи и секреты: не только .env-файлы

Практика4 мин

Коротко

Секреты не должны попадать в код и репозиторий: приложение получает их из переменных окружения, а сами значения хранятся в секрет-хранилище CI/CD или облака, отдельно для каждой среды, с минимальными правами и регулярной ротацией.

Коротко

Секрет — всё, что даёт доступ: API-ключи, пароли от баз данных, токены ботов, ключи подписи. Правильная схема выглядит так:

  1. В коде — только имя переменной, например DATABASE_URL.
  2. Значения хранятся в секрет-хранилище: в настройках CI/CD, хостинга или в менеджере секретов облака.
  3. У каждой среды — свои ключи: разработка, staging и production не делят один ключ.
  4. У каждого ключа — минимум прав и понятный порядок ротации.

Файл .env — удобный инструмент для локальной разработки, но не способ хранения секретов в команде.

Почему секреты утекают

  • Ключ в коде. Кто-то вставил его «временно», и он ушёл в коммит. История Git хранит его даже после удаления строки.
  • .env в репозитории. Забыли про .gitignore — файл виден всем, у кого есть доступ к коду, включая подрядчиков и форки.
  • Ключ во фронтенде. Всё, что попадает в браузер или мобильное приложение, можно извлечь. Секретный ключ платёжной системы в JavaScript-бандле — уже утечка.
  • Логи и ошибки. Приложение печатает конфигурацию при старте или трекер ошибок сохраняет заголовки запросов.
  • Пересылка в мессенджерах. Ключ отправили коллеге в чат, и он остался там навсегда.

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

Переменные окружения — правильно

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

const required = ["DATABASE_URL", "PAYMENT_API_KEY"] as const;

for (const name of required) {
  if (!process.env[name]) {
    throw new Error(`Missing env variable: ${name}`);
  }
}

Правила для .env:

  • Добавьте .env и .env.* в .gitignore до первого коммита.
  • Храните в репозитории .env.example — только имена переменных и безопасные заглушки.
  • Не логируйте process.env целиком.
  • В Next.js и похожих фреймворках переменные с публичным префиксом (например, NEXT_PUBLIC_) попадают в браузер — не кладите туда секреты.

Секреты в CI/CD и на хостинге

В GitHub Actions, GitLab CI и других системах есть встроенное хранилище секретов. Значения шифруются, маскируются в логах и подставляются только в нужные задачи.

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - run: ./deploy.sh
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

Привязывайте секреты к окружениям (environments) и защищайте production: деплой только из основной ветки, подтверждение ответственным человеком.

Когда сервисов становится много, переходите на менеджер секретов — облачный или self-hosted. Он даёт централизованный аудит, версии и ротацию.

Отдельные ключи для каждой среды

СредаКакие ключиКто имеет доступ
Локальная разработкаТестовые ключи, sandbox платёжных системРазработчики
StagingОтдельные ключи с ограниченными даннымиКоманда и CI
ProductionБоевые ключиТолько CI/CD и несколько ответственных

Если ключ разработчика утечёт, production не пострадает. А по логам сразу видно, из какой среды пришёл запрос.

Ротация и минимальные права

Минимальные права (least privilege): ключ для отправки писем не должен уметь удалять домены, а пользователю базы для отчётов не нужно право на запись. Многие сервисы позволяют ограничить ключ по действиям, IP-адресам или ресурсам — пользуйтесь этим.

Ротация — плановая замена ключа. Чтобы она не была болезненной:

  1. Приложение должно уметь работать с новым ключом без пересборки — достаточно обновить секрет и перезапустить.
  2. Порядок: создать новый ключ, обновить хранилище, задеплоить, убедиться, что всё работает, отозвать старый.
  3. Обязательно меняйте ключи при уходе сотрудника или подрядчика, у которого был к ним доступ.

Частые ошибки

  • Один «универсальный» ключ с полными правами на все проекты.
  • Боевые ключи на ноутбуках разработчиков.
  • Секреты в Docker-образе через ENV или скопированный .env.
  • Никто не знает, где и какие ключи используются, — ротацию невозможно провести.

Частые вопросы

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

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.