MAATRIX / Блог / Антипаттерн: ИИ-агент с полным доступом к продакшену

Антипаттерн: ИИ-агент с полным доступом к продакшену

MAATRIX

К концу лета 2026 года агентные инструменты на базе LLM закрепились в повседневной работе: они читают тикеты, пишут код, деплоят изменения и всё чаще получают SSH-доступ прямо к боевым серверам. Соблазн понятен — агент сам чинит инцидент в три ночи, пока вы спите. Проблема в том, что «сам чинит» на практике нередко означает «сам решает, что удалить», а разбираться с последствиями приходится уже вам. Разберём, почему полный доступ агента к продакшену — это не удобство, а отложенный инцидент, и как выстроить контур, в котором агент полезен, но не опасен.

Как это выглядит на практике

Антипаттерн редко формулируется как осознанное решение «дадим ИИ root на прод». Обычно он собирается из нескольких удобных на вид шагов.

Шаг первый — агенту выдают SSH-ключ «для скорости». Кто-то настраивает CLI-агента или бота в чате, подключает его к серверу через ключ с полным доступом, потому что настраивать отдельного пользователя с урезанными правами дольше, чем добавить строчку в authorized_keys:

# быстрый вариант, который потом никто не пересматривает
ssh-copy-id -i ~/.ssh/agent_key.pub deploy@prod-server
# deploy состоит в группе sudo без ограничений в sudoers

Шаг второй — агенту дают доступ к API с правами администратора. Вместо отдельного сервисного токена с правами «читать логи» или «перезапустить один контейнер» агент подключается тем же ключом, что использует человек-администратор — в панели облака, в Kubernetes, в CI/CD.

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

Шаг четвёртый — agentic-режим без подтверждения на каждый шаг. Многие агентные CLI по умолчанию просят подтверждение перед выполнением команды, но при первом же неудобстве («хватит нажимать Enter, пусть работает сам») этот флаг отключают ради скорости — и тогда деструктивная команда выполнится ровно так же легко, как безобидная.

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

Непредсказуемость модели: почему «ИИ разберётся» — это не стратегия

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

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

Модель может галлюцинировать — уверенно выдать неверный факт или несуществующую команду как достоверную. Применительно к инфраструктуре это означает: агент может «вспомнить» несуществующий флаг у утилиты, перепутать синтаксис между похожими инструментами (например, применить логику docker-compose down -v там, где нужно было просто перезапустить один сервис) или интерпретировать вывод ошибки неправильно и попытаться «исправить» её ещё более разрушительным действием.

Модель не имеет встроенного чувства необратимости. Для инженера разница между systemctl restart nginx и DROP DATABASE production интуитивно огромна — вторая команда необратима без бэкапа. Для языковой модели обе команды — просто следующий токен в последовательности, наиболее вероятный исходя из обучения на похожих задачах. Ничего в архитектуре LLM не гарантирует, что модель «прочувствует» тяжесть деструктивной операции сильнее, чем безобидной, если это ограничение не выстроено отдельно, вне самой модели.

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Деструктивная команда без ревью человека

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

Условный пример: агенту с доступом к серверу и к панели облачного провайдера ставят задачу «оптимизировать расходы на инфраструктуру». Задача звучит разумно, но у неё нет чётких границ — что можно трогать, а что нет. Агент видит несколько неиспользуемых на первый взгляд дисков и снапшотов и удаляет их для экономии. Проблема в том, что один из «неиспользуемых» дисков на самом деле — отключённый резервный том с последним рабочим бэкапом, который просто не был смонтирован в момент проверки. Ни один шаг не выглядел подозрительным по отдельности: агент действовал строго в рамках выданных прав, просто оценка «нужности» ресурса у него и у человека, знающего контекст бизнеса, оказалась разной.

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

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

Prompt injection: чужие данные как источник команд

Третий риск сложнее для интуитивного понимания, потому что он не связан с ошибкой самой модели — модель ведёт себя ровно так, как её просят, просто просьба исходит не от вас.

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

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

Практический вывод — не «не используйте агентов с внешними данными», а разделение зон ответственности: агент, который читает недоверенный ввод, не должен в той же сессии иметь прямой путь к деструктивным операциям на проде без промежуточного подтверждения. Совмещение «читает что угодно» и «может сделать что угодно» в одном контуре — это и есть сама уязвимость, а не то, что можно залатать аккуратной формулировкой промпта.

Принцип наименьших привилегий для агента

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

На практике это означает:

  • Отдельный сервисный аккаунт под агента, а не переиспользование ключа администратора: собственный пользователь, собственный API-токен, собственная роль в IAM облака.
  • Точечные права вместо sudo ALL. Если задача агента — перезапускать один сервис и читать его логи, sudoers должен разрешать ровно systemctl restart myapp и journalctl -u myapp, а не безусловный sudo.
  • Read-only доступ там, где не требуется запись — для диагностических задач агенту нужны только права на чтение логов и метрик.
  • Раздельные роли под разные типы задач. Агент, анализирующий инциденты, не должен по умолчанию иметь права на удаление ресурсов, даже если технически это один и тот же агент.
  • Токены с истекающим сроком действия, а не бессрочные ключи, вписанные в конфиг один раз и забытые на месяцы.

Пример ограничения через sudoers для сервисного пользователя агента:

# /etc/sudoers.d/agent-deploy
agent-deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart myapp
agent-deploy ALL=(root) NOPASSWD: /usr/bin/systemctl status myapp
agent-deploy ALL=(root) NOPASSWD: /usr/bin/journalctl -u myapp --no-pager -n 200

Такой список явно перечисляет, что агенту разрешено, и всё, что в него не входит, — например rm, dd, изменение файрвола или работа с базой данных — агент выполнить физически не сможет, даже если модель «решит», что это правильный следующий шаг.

Human-in-the-loop для деструктивных операций

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

Практический подход — разделить действия агента на две категории уже на уровне архитектуры, а не полагаться на то, что модель сама «поймёт», что нужно быть осторожнее:

Обратимые, низкорисковые операции агент может выполнять автономно: перезапуск сервиса, чтение логов, сбор метрик, применение уже проверенного и согласованного патча из pull request.

Деструктивные или необратимые операции должны требовать явного подтверждения человека перед выполнением — не «агент сообщил, что собирается сделать» постфактум, а пауза до выполнения с описанием конкретной команды и её ожидаемого эффекта, и явным «да» от человека. Технически это можно реализовать через:

  • режим агента, при котором каждая команда из списка деструктивных (rm, DROP, terminate-instance, delete-volume и аналоги) требует интерактивного подтверждения, даже если в целом агент работает автономно;
  • очередь на approval — агент формирует план действия и кладёт его в тикет или в чат, человек подтверждает конкретный шаг, только после этого выполнение продолжается;
  • отдельный «сухой прогон» (dry-run) перед реальным выполнением для команд, которые это поддерживают, с выводом результата человеку на проверку.

Это не отменяет пользу от автономности агента — рутинные, обратимые задачи по-прежнему решаются без участия человека, экономя реальное время. Human-in-the-loop добавляется точечно, там, где цена ошибки высока, а не превращает агента обратно в ручной процесс целиком.

Изолированная среда и аудит-логирование

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

Изолированная среда для тестирования и первого прогона. Прежде чем выдавать агенту доступ к продакшену вообще, его поведение стоит проверить там, где ошибка ничего не стоит — на копии инфраструктуры, в отдельном контейнере или staging-окружении с собственной базой данных. Подробный разбор уровней изоляции для агентов — сетевой, файловой, вплоть до VM-уровня через gVisor или Kata Containers — приводится в статье про песочницу для ИИ-агента. Правило простое: если вы не наблюдали, как агент ведёт себя на десятках реальных задач в изолированной среде, доверять ему прямой доступ к продакшену преждевременно.

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

# логировать каждую команду сервисного пользователя агента через auditd
auditctl -a always,exit -F arch=b64 -F euid=<uid-агента> -S execve -k agent_actions

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

Ни изоляция, ни логирование не предотвращают ошибку агента сами по себе — первая ограничивает её последствия рамками тестовой среды, второе даёт возможность быстро понять, что произошло, и откатить эффект. В сочетании с наименьшими привилегиями и human-in-the-loop для деструктивных операций это и есть тот минимальный контур, без которого доступ агента к продакшену остаётся антипаттерном независимо от того, насколько «умна» конкретная модель.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

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

Можно ли вообще безопасно дать агенту прямой SSH-доступ к продакшену?

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

Достаточно ли просто попросить агента «быть осторожным» в системном промпте?

Нет. Инструкция в промпте — пожелание модели, а не техническое ограничение: она снижает вероятность нежелательного действия, но не исключает его и не защищает от prompt injection, где «инструкция быть осторожным» конкурирует с инструкцией, подсунутой во входных данных. Реальная защита — на уровне прав доступа и подтверждений.

Как быстро понять, что агенту дали слишком много прав?

Проверить, какие команды реально разрешены сервисному пользователю (sudo -l -U <агент>, права API-ключа в панели облака), и сравнить со списком задач, которые агент реально решает. Если разрешённых прав заметно больше — это и есть избыточный доступ.

Нужен ли human-in-the-loop для всех операций агента?

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

Где тестировать поведение нового агента, если своей staging-инфраструктуры пока нет?

На отдельном сервере, изолированном от продакшена на сетевом уровне, с копией данных, которую не жалко потерять.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →