Что пишут в блогах

Подписаться

Что пишут в блогах (EN)

Разделы портала

Онлайн-тренинги

.
Не разрешайте ИИ читать .env-файлы
17.08.2026 00:00

Автор: Филип Рик (Filip Hric)
Оригинал статьи
Перевод: Ольга Алифанова

ИИ-ассистенты для написания кода - Claude Code, Cursor и GitHub Copilot, - становятся частью повседневного рабочего процесса. Они читают файлы, понимают кодовую базу и помогают писать код быстрее. Но есть проблема — они также могут читать .env-файлы. В последнее время в соцсетях ходит история об этом, и я сам столкнулся с этим на практике:

 

Некоторые ИИ-инструменты, такие как Cursor, по умолчанию не читают .env-файл, но Claude Code, наоборот, заглянет в него, если явно не запретить. Хороший способ предотвратить это — настроить файл ~/.claude/settings.json, который задаёт правило по умолчанию для всех проектов.

{
"permissions": {
"read": {
"deny": [
"**/.env*",
"**/*.pem",
"**/*.key",
"**/secrets/**",
"**/credentials/**",
"**/.aws/**",
"**/.ssh/**",
"**/docker-compose*.yml",
"**/config/database.yml"
]
}
}
}

Почему это плохо

Когда ИИ-ассистент читает .env-файл, секреты отправляются в LLM. API-ключи, пароли к базе данных и другие учётные данные становятся частью контекстного окна. Это риск безопасности, который иногда игнорируют, пока не становится слишком поздно.

???? Если это с вами произошло:

Считайте любой утёкший секрет скомпрометированным. Случайная вставка API-ключа в Google, отправка его в Slack или коммит в репозиторий — всё это риск безопасности и требует немедленной реакции. Немедленно отзовите API-ключ и создайте новый. Если работа ведётся в команде, сообщите об этом, чтобы ключ также обновили коллеги. Лучше признать ошибку, чем столкнуться с её последствиями. Такое случается и с лучшими из нас.

Хорошая новость – есть решение, которое позволяет защитить секреты, сохранив удобство .env-файлов. В этой статье я покажу, как настроить это с помощью инструмента 1Password CLI. Существуют и другие решения — Bitwarden, Doppler или сервисы от AWS, Google и Azure, которые предоставляют аналогичную функциональность.

Как это работает

Идея простая. Вместо хранения реальных значений секретов в .env-файле:

# Традиционный .env файл – секреты прямым текстом
DATABASE_URL=postgres://user:password123@localhost/mydb
API_KEY=sk-abc123secret

ссылки на секреты хранятся в хранилище 1Password:

# With 1Password references - no actual secrets
DATABASE_URL="op://Development/Database/connection_string"
API_KEY="op://Development/Stripe/api_key"

Формат выглядит так: op://vault-name/item-name/field-name

При запуске приложения используется команда op run, которая подставляет реальные значения во время выполнения:

op run --env-file=.env -- npm run dev

1Password перехватывает ссылки и заменяет их реальными значениями из хранилища. Секреты существуют только в памяти во время выполнения — они никогда не записываются на диск.

Почему это лучше

Такой подход даёт несколько преимуществ:

  • Безопасность при работе с ИИ — когда Claude Code или Cursor читают .env-файл, они видят только ссылки вроде op://Work/Stripe/api_key, а не реальные секреты
  • Отсутствие секретов в системе контроля версий — .env-файл можно безопасно коммитить, потому что в нём только ссылки
  • Совместная работа в команде — секреты распространяются через хранилище 1Password, а не копируются между машинами или отправляются через Slack
  • Мгновенная ротация — обновите секрет в 1Password, и он сразу станет доступен всей команде
  • Аудит — 1Password ведёт журнал доступа к секретам

Настройка

Давайте пройдём по процессу настройки. Используется macOS, но шаги похожи и для других платформ.

Шаг 1: Установка 1Password CLI

Если Homebrew ещё не установлен, сначала установите его. Затем выполните:

brew install --cask 1password-cli

Шаг 2: Включите интеграцию с десктопным приложением

Этот шаг важен — он позволяет CLI аутентифицироваться через десктопное приложение 1Password, что даёт возможность использовать Touch ID вместо ввода мастер-пароля каждый раз.

Откройте десктопное приложение 1Password и:

  • Перейдите в Settings
  • Перейдите в раздел Developer
  • Включите «Integrate with 1Password CLI»

Шаг 3: Проверьте подключение

Убедитесь, что всё работает:

op vault list

Должен отобразиться список хранилищ. Если это работает, всё настроено.

Использование в проектах

Теперь применим это на практике. Допустим, есть проект с .env-файлом:

DATABASE_URL=postgres://user:
 Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript
 /myapp
STRIPE_SECRET_KEY=sk_live_abc123
OPENAI_API_KEY=sk-openai-xyz789

Сначала создайте эти секреты в 1Password. Рекомендуется завести отдельное хранилище для секретов разработки или организовать их в существующем Work-хранилище.

Затем обновите .env-файл, используя ссылки:

DATABASE_URL="op://Work/Database Production/connection_string"
STRIPE_SECRET_KEY="op://Work/Stripe/secret_key"
OPENAI_API_KEY="op://Work/OpenAI/api_key"

Теперь запустите приложение:

op run --env-file=.env -- npm run dev

CLI запросит аутентификацию (или использует Touch ID), получит секреты из хранилища и передаст их как переменные окружения.

Как сделать это более кратким и емким

У вас может возникнуть вопрос, нужно ли каждый раз писать op run. Есть несколько вариантов.

Можно обновить скрипты в package.json:

{
"scripts": {
"dev": "op run --env-file=.env -- next dev",
"start": "op run --env-file=.env -- node server.js"
}
}

Теперь npm run dev автоматически использует 1Password.

Или создать алиас в .zshrc:

alias dev="op run --env-file=.env -- npm run dev"

При этом небольшое трение от использования op run даже полезно — оно напоминает, что осуществляется доступ к секретам, и помогает держать безопасность в фокусе.

Отладка

Когда учётные данные так хорошо скрыты, отладка может стать запутанной. 1Password CLI не выводит значения переменных окружения в терминал. Допустим, есть скрипт:

console.log(process.env.DATABASE_URL);

При запуске он выведет только ссылку на секрет, а не его значение:

op run node index.js
# output
op://Work/Database Production/connection_string

Чтобы увидеть реальное значение, используйте флаг --no-masking:

op run --no-masking node index.js
# output
postgres://user: Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript /myapp

Заключение

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

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

Надеюсь, это поможет! Если материал оказался полезным, поделитесь им с командой. Можно подписаться на меня в Twitter или LinkedIn, где я публикую больше подобного контента.

Обсудить в форуме