# Продакшен-секреты MCP через брокер или переменные среды

> Сравниваем продакшен-секреты MCP через брокер Vault и переменные среды: видимость, срок жизни, отзыв, аудит и утечки в журналах.

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

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

## Доставка секретов и авторизация MCP решают разные задачи

Авторизация MCP защищает соединение между MCP-клиентом и MCP-сервером. Она не защищает автоматически учетные данные, с которыми сервер обращается к базе данных, облачному API, платежному сервису или системе развертывания. Считайте их двумя разными контурами учетных данных с отдельными издателями, аудиториями, сроками жизни и журналами аудита.

Спецификация авторизации Model Context Protocol требует, чтобы MCP-сервер с HTTP проверял, выпущен ли токен доступа именно для него. Она также запрещает сквозную передачу токена: сервер не должен брать токен, полученный от MCP-клиента, и пересылать его во внешний API. Это правило проводит полезную границу. Входящий токен подтверждает, кто может вызвать MCP-сервер. Другие, исходящие учетные данные определяют, что сервер вправе сделать после приема вызова.

Локальные серверы со stdio устроены иначе. Спецификация рекомендует реализациям со stdio получать учетные данные из среды, а не применять поток HTTP-авторизации. Это рекомендация по транспорту, а не разрешение заполнять среду процесса администраторскими токенами продакшена. Локальный сервер все равно работает с правами клиента на уровне операционной системы, а руководство MCP по безопасности предупреждает: взломанный локальный сервер получает доступ к файлам, сети и другим ресурсам, доступным процессу.

Зафиксируйте оба контура до выбора способа доставки:

| Контур | Аудитория учетных данных | Держатель | Обычные свидетельства |
| --- | --- | --- | --- |
| От клиента к MCP-серверу | MCP-сервер | MCP-клиент | Субъект, клиент, область доступа, ID запроса |
| От MCP-сервера к продакшен-сервису | Один внешний сервис или одна операция | Исполнитель инструмента или брокер | Рабочая нагрузка, роль, аренда, ресурс, действие |

Если один bearer-токен пересекает обе строки, система объединила два решения о доверии в одно. Vault уже не исправит эту ошибку. Сервер должен обменять или запросить учетные данные, предназначенные для внешнего ресурса. Система аудита должна сохранить связь между входящей личностью и исходящим действием, не копируя ни один секрет.

## Передача через среду расширяет границу процесса

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

Обычно передача происходит до запуска процесса. Планировщик, CI-раннер, контейнерная платформа или Vault Agent получает значение и помещает его в `DB_PASSWORD`, `CLOUD_TOKEN` либо похожую переменную. Код приложения читает ее через стандартный API среды выполнения. Во время задачи сетевой запрос к брокеру не нужен, поэтому компонентов меньше и в пути запроса нет еще одной зависимости.

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

Переменные среды также расходятся через обычные рабочие механизмы. Отладочные обработчики печатают конфигурацию. Тестовые фреймворки добавляют среду в пакет сведений об ошибке. Супервизоры процессов показывают параметры запуска. Инструмент выполняет `env` при поиске проблемы с путями. Ни одно из этих действий не похоже на чтение секрета в менеджере секретов, поэтому его журнал аудита не объяснит утечку.

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

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

## Брокер безопасен, только пока родительские права остаются у него

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

Самая сильная схема использует брокер возможностей. Агент отправляет структурированный запрос, например `deploy release 184 to staging`. Брокер проверяет личность рабочей нагрузки, одобрение пользователя, целевую среду, имя инструмента и политику. Затем он обращается к системе развертывания, не возвращая продакшен-учетные данные процессу MCP. Ответ инструмента содержит ID развертывания и статус, а не токен доступа.

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

Прокси для чтения секретов слабее. Если агент может сказать `read secret/data/anything` и держит токен с доступом к множеству путей, прокси перенес точку API, но сохранил широкие права. Списки разрешенных путей помогают, однако статический администраторский пароль базы данных, полученный через такой список, остается многоразовым администраторским паролем.

Важнее всего родительские учетные данные. Брокер должен входить через личность рабочей нагрузки или держать токен Vault в отдельном процессе, который агент не может исследовать. Никогда не передавайте токен Vault в MCP-сервер только ради того, чтобы сервер мог получать другие секреты. Такой токен открывает все пути, разрешенные его политикой, и часто живет дольше любых исходящих учетных данных. Одной инъекции в промпт или подробного исключения достаточно, чтобы узкая задача превратилась в инвентаризацию секретов.

Vault response wrapping помогает при передаче. Документация HashiCorp объясняет, что обернутый ответ содержит одноразовый wrapping-токен вместо исходного секрета, причем у него отдельный и часто более короткий срок жизни. Получатель может проверить путь создания до распаковки. Если токен уже кто-то распаковал, назначенный получатель увидит ошибку, которую нужно расследовать. Обертка сокращает риск при перемещении значения, но распакованным учетным данным все равно нужны узкая роль и короткая аренда.

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

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

Интерфейс брокера должен быть уже интерфейса менеджера секретов. Методы наподобие `issue_orders_reader(task_id, approval_id)` и `deploy_release(target, digest)` дают коду политик стабильные объекты для проверки. Универсальный метод `get_secret(path)` экспортирует пространство имен Vault в агент и подталкивает вызывающий код собирать права из строк. После инъекции в промпт атакующему нужна именно такая свобода.

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

## Короткий срок жизни должен совпадать с границей задачи

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

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

HashiCorp различает динамические секреты и значения в движке KV. У динамических секретов есть аренда, и Vault умеет ее отзывать. Статические значения KV не получают это свойство только потому, что агент прочитал их из Vault. В архитектурных схемах эту границу часто стирают. Перенос годового токена поставщика из настройки CI в Vault KV централизует хранение и журнал чтения, однако поставщик продолжит принимать скопированный токен, пока кто-то не выполнит ротацию у самого поставщика.

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

Используйте политику, которая запрещает просмотр и фиксирует путь роли. Этот фрагмент позволяет брокеру запросить одну роль базы данных и не дает просматривать соседние роли:

```hcl
path "database/creds/mcp-orders-reader" {
  capabilities = ["read"]
}

path "database/roles/*" {
  capabilities = ["deny"]
}

path "secret/data/*" {
  capabilities = ["deny"]
}
```

Политика намеренно скучна. Не добавляйте `list` для удобства оператора в личность среды выполнения. Доступ для расследования выдавайте через отдельную человеческую роль со своим одобрением и записью аудита.

## Отзыв должен доходить до внешнего сервиса

Отзыв работает лишь тогда, когда издатель может заставить внешний сервис отклонять учетные данные, а приложение прекращает использовать кэшированные копии. Удаление переменной среды, отзыв токена Vault или завершение MCP-сессии могут оставить настоящие продакшен-учетные данные действующими.

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

За этим обещанием скрываются режимы отказа. Vault может не связаться с базой данных или облачным сервисом при попытке удалить личность. HashiCorp описывает для такого случая безотзывные аренды. Процедура реагирования должна проверять внешний сервис, а не завершаться после ответа `vault lease revoke` или исчезновения аренды с панели.

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

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

## Журнал аудита должен показывать причины, а не значения секретов

Полезный журнал аудита отвечает на вопросы: кто запросил действие, какая политика его разрешила, какие учетные данные или аренда были выданы, какой продакшен-ресурс изменился и успешно ли завершилась операция. Для этого не нужно хранить bearer-значение.

Устройства аудита Vault записывают запросы и ответы, проходящие через Vault. Так появляются свидетельства аутентификации, чтения секрета, создания аренды, продления и отзыва. Они не фиксируют каждый SQL-запрос или вызов облачного API после выдачи секрета. Журналы внешнего сервиса все равно нужны. Они становятся намного полезнее, когда динамические учетные данные создают отдельную личность для каждой рабочей нагрузки или задачи.

Передавайте один correlation ID через всю границу. Создайте его, когда MCP-сервер принимает вызов инструмента, затем прикрепите к запросу брокера, записи одобрения, журналу исполнителя и метаданным внешнего запроса, если сервис их поддерживает. Входящую личность пользователя или рабочей нагрузки храните отдельно от сущности Vault и исходящего принципала. Эти личности описывают разные решения, поэтому не затирайте их одним полем `actor`.

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

Разница между журналом доступа и цепочкой причин становится заметна при инциденте. Журнал доступа может доказать, что `mcp-prod-role` прочитала `database/creds/orders`. Цепочка причин связывает это чтение с одобренным вызовом `get_monthly_total` пользователя 482, решением брокера 9137, принципалом базы данных `v_mcp_7f2` и точным классом запроса. Без этой связи следователь видит активность, но не может определить, была ли она ожидаемой.

## Чаще всего секрет утекает через журнал или ответ инструмента

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

Считайте, что любая строка, возвращенная на уровень MCP, может попасть в контекст модели и системы наблюдения. Инструмент базы данных должен возвращать строки или категорию ошибки, но не строку подключения. HTTP-инструмент должен удалить заголовки авторизации и cookie до создания успешного ответа или ошибки. Инструмент развертывания должен вернуть ID релиза, цель и состояние. Если инструменту нужно упомянуть учетные данные, используйте несекретный accessor, ID аренды или последние четыре символа, которые специально выбраны для показа.

Редактирования по имени поля недостаточно. Секреты встречаются во вложенном JSON, командных строках, URL, трассировках стека и тексте ошибки поставщика. Удаляйте известные значения на границе исполнителя до сериализации. Ограничивайте размер ответа, а поиск строк с высокой энтропией используйте как дополнительный сигнал, а не основную защиту. Такой поиск пропускает короткие пароли и помечает безобидные идентификаторы.

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

1. Заставьте внешний сервис отклонить учетные данные и вернуть подробную ошибку.
2. Аварийно завершите исполнитель во время создания клиента.
3. Запросите у диагностического инструмента сведения о среде и процессе.
4. Верните большой вложенный ответ инструмента с приманкой на нескольких уровнях.
5. Откройте записи трассировки, агрегации журналов, диалога с моделью, экспорта для поддержки и очереди необработанных сообщений.

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

Инъекция в промпт меняет того, кто выбирает вызов инструмента, но не правила операционной системы для секретов. Считайте вывод модели недоверенными входными данными для политики. Брокер должен проверять операции из закрытого списка, типизированные ресурсы, состояние одобрения и личность рабочей нагрузки. Он должен отклонять произвольные пути к секретам и внешние URL, даже если модель предлагает их уверенно.

## Одобрение должно находиться на границе полномочий

Одобрение человеком снижает риск лишь тогда, когда одобренная формулировка совпадает с учетными данными и операцией, которые использует исполнитель. Общее подтверждение наподобие `Allow this tool?` сообщает человеку слишком мало, а реализации оставляет возможность подменить цель после нажатия.

Брокер должен строить запрос на одобрение из проверенных полей, а не из текста модели. Покажите операцию, продакшен-аккаунт или среду, ресурс, эффект, запрашивающую личность и срок действия. Для развертывания это может быть релиз 184, продакшен, сервис `billing-api`, окно изменений 9137, запрос пользователя 482, одно выполнение в течение десяти минут. Человеку не нужно видеть путь к секрету, а в записи одобрения не должно быть самого секрета.

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

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

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

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

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

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

## Выбирайте схему по радиусу ущерба

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

Используйте прямую передачу через переменные среды, только если соблюдены все условия:

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

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

Для команд, где Vault уже работает, продакшен-путь выглядит просто: личность рабочей нагрузки аутентифицирует отдельный брокер, политика фиксирует одну разрешенную роль, Vault выдает арендованные учетные данные или обернутый ответ, ограниченный исполнитель использует их, а запись внешнего аудита несет correlation ID. MCP-процесс получает только типизированный результат. Команды без Vault могут провести ту же границу с помощью облачного менеджера секретов, личности рабочей нагрузки и небольшого брокера операций. Не развертывайте отдельную платформу секретов лишь ради еще одного HTTP-вызова.

Team & AI Audit от oleg.is может составить карту этих путей полномочий при проверке инженерной среды с ИИ, но ближайшее техническое решение не должно ждать аудита. Уберите родительские учетные данные из MCP-процесса, выберите один продакшен-инструмент и докажите с помощью приманки, что его секрет не появляется в ответе инструмента или журналах. Если доказать это не удалось, агент еще не готов к доступу в продакшен.
