Категории
Как передать пароли и ключи API при работе с агентами ИИ
21.10.2026 | из категории: Нейросети
Главный принцип, который отличает «просто дал ключ» от «сделал безопасно»: агент никогда не должен видеть сам секрет. Он должен видеть только результат его использования.
Если вы работаете с агентами вроде Claude Code, Codex или Cursor, которые сами запускают команды, тестируют и ходят в базы данных, — вы уже поняли главную боль. Агенту нужен доступ к секретам, чтобы что-то проверить. Но как только секрет попадает в контекст модели, он считается скомпрометированным: промпт-инъекция, логи, случайно сгенерированный код — всё это может его вынести наружу.
Ниже — рабочие архитектурные подходы, которые используют разработчики, а не «менять пароли после каждой задачи».
Почему .env и переменные окружения больше не работают
Раньше стандартом было положить ключ в .env и сказать «не читай». Для агента это не граница безопасности. Файл .env лежит в рабочей директории, агент может его прочитать, изменить, закоммитить или вывести в лог. Переменные окружения тоже наследуются всеми дочерними процессами, включая вредоносные зависимости и сгенерированный код.
Решение не в том, чтобы «лучше прятать файл», а в том, чтобы вынести секрет за пределы досягаемости агента. Любой секрет, попавший в контекст модели или в её рабочую директорию, считается скомпрометированным.
Подход 1: инъекция секретов на уровне выполнения рекомендуется
Это самый прямой и распространённый способ для локальных агентов.
Как работает: секреты хранятся в локальном зашифрованном хранилище (DPAPI на Windows, Keychain на macOS, Secret Service на Linux). Когда агенту нужно выполнить команду с секретом, он вызывает специальный инструмент или CLI. Этот инструмент сам подставляет значение в дочерний процесс и возвращает агенту только вывод, причём с вырезанными секретами.
Инструменты, которые это реализуют
AgentSecure
При setup реальные секреты переносятся в локальное хранилище, а в проектных файлах остаются только псевдонимы. Когда агенту нужен секрет, он идёт через MCP-инструмент, который валидирует место назначения и подставляет реальное значение вне контекста агента.
keygrant
Модель видит только имена секретов, значения никогда не попадают в контекст. При выполнении команды значения инжектируются в окружение дочернего процесса, а весь вывод редактируется перед возвратом модели — включая base64, hex и URL-encoded варианты. Каждое первое использование секрета в сессии требует явного подтверждения пользователя, грант живёт 15 минут и привязан к сессии.
key-amnesia
При попытке агента использовать секрет открывается отдельное консольное окно, в которое агент не может ни читать, ни писать. Мастер-пароль вводите только вы, физически с клавиатуры.
Даже если агент «заражён» промпт-инъекцией, он не может вывести секрет, потому что у него его нет. Он может попросить выполнить команду, но команда выполнится в песочнице, а вывод вернётся очищенным.
Подход 2: прокси-подстановка на сетевом уровне
Этот подход ещё жёстче: агент вообще не знает, что такое реальный ключ. В коде и в .env лежат только плейсхолдеры вида nv://STRIPE_KEY. При исходящем HTTPS-запросе локальный прокси перехватывает его, подставляет реальный секрет в памяти и отправляет дальше.
Пример — nv-protocol (nvenv): позиционируется как «криптографический прокси, развязывающий сырые креды и видимое рабочее пространство автономных агентов». В .env и в переменных окружения — только плейсхолдеры. Реальные значения хранятся в зашифрованном vault (SQLite + DPAPI на Windows). Подстановка происходит на границе сокета при TLS-хендшейке.
# В .env агент видит только это:
STRIPE_KEY=nv://STRIPE_KEY
DATABASE_URL=nv://DATABASE_URL
# Реальные значения лежат в vault и
# подставляются прокси при исходящем запросе
Если агент работает с внешними API (Stripe, AWS, базы данных по сети) и вы хотите, чтобы даже сгенерированный им код не мог вывести ключ. Прокси подставит секрет только для разрешённого хоста.
Подход 3: Just-in-Time доступ и отдельные идентичности
Microsoft в своих рекомендациях по безопасности агентов прямо советует: уникальная идентичность для каждого агента и Just-in-Time доступ — повышенные права включаются только на время выполнения конкретной задачи, потом автоматически отключаются.
На практике это выглядит так:
- Не давайте агенту ваш личный ключ. Создайте отдельную учётную запись с минимальными правами: только чтение, только конкретная папка, только конкретный сервис.
- Если агенту нужны повышенные права — они выдаются на время (например, на 15 минут) и отзываются автоматически.
- Все действия агента логируются отдельно от ваших, чтобы можно было отследить, что именно он делал.
Агенту для тестов обычно достаточно read-only доступа к тестовой базе. Не давайте ему продовый ключ «на всякий случай». Если задача требует записи — выдайте временный грант, а не постоянный ключ.
Подход 4: песочница и минимальные права
Песочница ограничивает не то, что агент видит, а то, куда он может пойти. Даже если секрет попал в контекст, песочница не даст отправить его на внешний хост.
- Сетевые ограничения: разрешите исходящие соединения только к нужным хостам (allowlist). Всё остальное блокируется.
- Файловые ограничения: агент видит только рабочую директорию, а не весь домашний каталог.
- Отсутствие доступа к секретам хоста: переменные окружения хоста, SSH-ключи и конфиги cloud-провайдера не пробрасываются в песочницу.
OpenAI в документации по агентам прямо пишет: «Agent-generated code can read the environment key. Keep your application API key outside the environment». То есть ключи не должны лежать в окружении, куда агент может залезть.
Сравнение подходов
| Подход | Агент видит секрет? | Защита от промпт-инъекции | Сложность внедрения |
|---|---|---|---|
| Инъекция на уровне выполнения | нет | Высокая | Низкая (готовые инструменты) |
| Прокси-подстановка | нет | Высокая | Средняя (нужен прокси) |
| JIT + отдельная идентичность | да, но временно | Средняя | Средняя (нужна настройка IAM) |
| Песочница | зависит | Средняя | Средняя (нужна настройка сети) |
.env в рабочей директории |
да, полностью | Нет | Нулевая |
Чек-лист перед запуском агента
- Секреты не лежат в рабочей директории агента. Ни в
.env, ни в конфигах, ни в коде. - Агент использует отдельную учётную запись с минимальными правами, а не ваш личный ключ.
- Для тестов — read-only доступ к тестовой базе, а не к проду.
- Вывод команд очищается перед возвратом агенту (инструмент вроде keygrant или AgentSecure).
- Исходящие соединения ограничены allowlist-ом нужных хостов.
- Логи агента отделены от ваших, чтобы можно было отследить его действия.
- Если нужны повышенные права — они выдаются на время (JIT), а не постоянно.
Что делать, если секрет всё-таки утёк
Если секрет попал в контекст модели, в лог или в сгенерированный код — считайте его скомпрометированным. Отзовите и смените. Это не «после каждой задачи», а «только если произошла утечка». Если вы построили работу через инъекцию, прокси или JIT-доступ, утечки не происходит, и менять ничего не нужно.
Порядок действий при утечке:
- Немедленно отзовите ключ в панели управления сервиса (VPN, облако, база данных).
- Создайте новый ключ и положите его в защищённое хранилище, а не в
.env. - Проверьте логи сервиса на предмет несанкционированных действий за период, пока ключ был активен.
- Если ключ был в публичном репозитории — удалите его из истории git (не просто новым коммитом).
Менять пароли после каждой задачи не нужно. Нужно перестать давать агенту пароли. Пусть он просит выполнить действие, а секрет подставляет доверенный слой — инъекция, прокси или JIT-доступ — и возвращает агенту только результат. Тогда единственный раз, когда вам придётся менять пароль, — это если вы знаете, что он попал в лог или в контекст модели.