Безопасность12 мин

Где хранить API-ключи и секреты в проекте с ИИ-агентом

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

Обложка статьи: Где хранить API-ключи и секреты в проекте с ИИ-агентомЧеловек 2.0
≡
Коротко

Что забрать из статьи

  • 1Безопасная схема отделяет секрет от кода и текста, доступного модели. Приложение или серверный инструмент получает значение только во время выполнения, а агент видит ограниченную операцию и безопасный результат — не сам ключ.
  • 2«После утечки перепишем историю и закончим». Первое действие — отзыв или ротация. Очистка истории снижает дальнейшее распространение, но не отменяет уже полученный доступ.
Где это применять

Почему секрет нельзя хранить рядом с инструкцией для агента

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

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

Что считать секретом

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

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

Пять мест, где секрет хранить нельзя

  1. В исходном коде, отслеживаемом конфигурационном файле или истории Git.
  2. В issue, pull request, wiki, чате, промпте или комментарии к задаче.
  3. В Dockerfile, build argument, слое образа или обычном Compose YAML.
  4. В stdout, stderr, telemetry, трассировке запроса либо отладочном дампе.
  5. В общем документе или скриншоте, который затем попадёт в пакет, письмо или базу знаний.

Файл с примером настройки должен содержать только названия переменных и безопасные заглушки вроде [REDACTED]. Реальные значения в шаблон не добавляют.

Где хранить секрет в зависимости от среды

Локальная разработка. Допустим отдельный локальный файл, который исключён из Git, имеет ограниченные права и не отправляется агенту целиком. Файл .env — удобный механизм, но не универсально самый защищённый: значение может раскрыться через окружение процесса, ошибочный лог, дамп или доступ другого пользователя. Если файл уже отслеживается Git, одного добавления в .gitignore недостаточно.

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

Контейнер. Не встраивайте значение в Dockerfile или image layer. Подайте секрет во время выполнения через поддерживаемый механизм. Docker Compose может смонтировать явно разрешённому сервису секрет как файл, но уровень защиты всё равно зависит от исходного файла, прав на хосте и выбранного оркестратора.

Крылатый робот рядом с открытым круглым сейфом, светящимися капсулами и трубками

Как провести границу между агентом и ключом

Не вставляйте секрет в системный промпт, описание скила, сообщение пользователю или текст задания. Промпт нельзя считать защищённым хранилищем и механизмом авторизации.

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

Пошаговая настройка безопасного хранения

Шаг 1. Составьте реестр. Для каждого секрета запишите владельца, сервис, среду, потребителей и последствия компрометации. Не записывайте само значение в реестр.

Шаг 2. Уберите значение из кода и контекста агента. Проверьте отслеживаемые файлы, историю, вложения и артефакты. В конфигурации оставьте только ссылку, имя переменной или путь к runtime-файлу.

Шаг 3. Создайте отдельный credential для конкретной среды и сервиса. Не используйте один ключ для локальной разработки, CI и production.

Шаг 4. Выдайте минимум прав. Ограничьте доступ нужными операциями, ресурсами, средой, источником запроса или сроком жизни, если провайдер это поддерживает.

Шаг 5. Настройте runtime injection. Секрет должен появляться у процесса только при запуске или обращении к хранилищу. Не передавайте его в командной строке, если она попадает в историю shell или список процессов.

Шаг 6. Включите secret scanning и push protection. Это дополнительная защита: сканер видит известные и настроенные паттерны, но не гарантирует обнаружение любого секрета.

Шаг 7. Выполните безопасный smoke test. Подтвердите успешную авторизацию и ожидаемую операцию, не печатая значение, заголовки авторизации или строку подключения.

Шаг 8. Проверьте отзыв и замену. Владелец должен знать, где отключить старый credential, как выдать новый и какие процессы нужно перезапустить.

Проверяемый пример без раскрытия значения

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

Ожидаемый результат проверки: операция проходит; при отсутствии секрета процесс завершается понятной ошибкой; в stdout, stderr и журнале нет значения или его полного отпечатка; отозванный credential перестаёт работать; после замены сервис снова проходит smoke test.

Что делать, если ключ уже попал в Git, чат или лог

  1. Считайте секрет скомпрометированным и остановите дальнейшее распространение артефакта.
  2. Сразу отзовите credential у провайдера и при необходимости выпустите новый.
  3. Проверьте журналы использования: время, источник, операции и признаки чужого доступа.
  4. Удалите значение из текущих файлов, сообщений, логов и сборочных пакетов в пределах доступной процедуры.
  5. Если секрет попал в Git, после отзыва оцените необходимость очистки истории по официальной инструкции платформы и предупредите команду о побочных эффектах переписывания истории.
  6. Найдите причину: неверный шаблон, логирование заголовков, слишком широкие права, отсутствие guard или ручная передача через чат.

Удаление строки следующим коммитом не обезвреживает старый ключ: прежнее значение остаётся в истории и могло быть скопировано. Push protection также не заменяет отзыв уже раскрытого credential.

Крылатый белый робот с синими глазами рядом с красным ключом, осколками и устройством с синими ключами

Частые ошибки диагностики

«Файл есть в .gitignore — значит всё безопасно». Если Git уже отслеживал файл, правило не уберёт его из индекса и истории. Проверьте фактический список отслеживаемых файлов.

«Сканер ничего не нашёл — секретов нет». Сканеры зависят от поддерживаемых и настроенных паттернов. Дополните автоматическую проверку ревизией конфигурации и мест, где процесс пишет логи.

«Переменная окружения автоматически безопасна». Это канал передачи конфигурации, а не самостоятельная гарантия. Учитывайте доступ к процессу, дампы, дочерние процессы и журналирование.

«Ключ нужен агенту, поэтому вставим его в prompt». Агенту нужна операция. Credential должен оставаться на границе инструмента, где действуют авторизация, ограничения и аудит.

«После утечки перепишем историю и закончим». Первое действие — отзыв или ротация. Очистка истории снижает дальнейшее распространение, но не отменяет уже полученный доступ.

Чек-лист готовности

  1. В отслеживаемых файлах, вложениях и пакете статьи нет реальных секретов.
  2. Процесс получает credential во время выполнения, а модель не видит его значение.
  3. Права ограничены средой, сервисом и необходимыми операциями.
  4. Smoke test подтверждает доступ без утечки в вывод и логи.
  5. Secret scanning и push protection настроены как дополнительный слой.
  6. Проверена процедура revoke/replace и назначен владелец.
  7. Зафиксирована дата следующего пересмотра.

Что делать дальше

Начните с одного проекта: составьте реестр секретов, перенесите значения из отслеживаемых файлов в подходящее хранилище и проверьте процедуру отзыва. Затем распространите тот же стандарт на CI, контейнеры и инструменты агента.

Больше практических материалов собрано в разделе «Гайды и рабочие сценарии» «Человек 2.0». Если нужен живой разбор своей задачи, посмотрите, как устроена Среда внедрения ИИ.

FAQ

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

Нужно ли менять ключ по расписанию? Частота зависит от риска и возможностей провайдера. Критично уметь быстро отозвать и заменить credential; короткий срок жизни и автоматическая ротация уменьшают окно компрометации.

Достаточно ли GitHub push protection? Нет. Он блокирует часть поддерживаемых секретов и может иметь исключения. Нужны минимальные права, runtime injection, безопасные логи и готовая процедура отзыва.

Нужно ли давать ключ самой модели? Нет. Модель вызывает ограниченный инструмент, а credential остаётся у серверного процесса.

Источники

Дальше читать

Связанные материалы

Все статьи →