Сервис развивается: тестируем формат, собираем идеи, улучшаем сервис. Есть идеи?

Написать
Войти
Дайджесты новостей
Архитектура корпоративного ИИ-агента с модулями защиты и управления секретами

Постмортем ИИ-агента Smith в daily.dev: утечки секретов, зависания Node.js и защита от сбоев в проде

daily.dev запустила Slack-агента Smith с доступом к базам данных и деплою, столкнувшись с утечками секретов, зависанием Node.js и блокировкой памяти при сложных запросах. Разбор инженерных решений показывает, как многоуровневая изоляция и кэширование инструментов превращают прототип в стабильную систему.

Постмортем ИИ-агента Smith в daily.dev: утечки секретов, зависания Node.js и защита от сбоев в проде

Внедрение автономных ИИ-агентов во внутренние инженерные процессы часто начинается как эксперимент по устранению организационных задержек. В daily.dev инженеры регулярно тратили время на написание связующего кода для логов и метрик, а отдел продаж обращался к аналитикам за каждой промежуточной выгрузкой. Чтобы убрать эти барьеры, команда отказалась от создания очередного набора дашбордов и форм, разработав автономного Slack-агента Smith. Агент получил прямой доступ к хранилищам ClickHouse, BigQuery, транзакционной базе PostgreSQL, системе GitHub и серверам деплоя.

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

Архитектура агента и предпосылки запуска

Разработка Smith стартовала 8 марта 2026 года, а внутренний запуск состоялся уже 12 марта. За четыре дня два разработчика написали 29 000 строк кода на TypeScript и покрыли систему 10 000 строк тестов (118 коммитов). Выбор Slack в качестве единственного интерфейса избавил сотрудников от настройки доступов: достаточно отправить запрос в тред, чтобы агент обратился к базам данных и вернул расчеты.

Очень быстро агент взял на себя задачи, которые ранее не выполнялись вручную из-за нехватки времени. В три часа ночи Smith запускает регламентные процедуры: анализирует паттерны спама в ClickHouse, сверяет пользовательские профили и автоматически модерирует контент через внутренний API. Раз в неделю агент сопоставляет конфигурации фиче-флагов с экспериментами на платформе GrowthBook, генерирует ежемесячные отчеты и выполняет задачи по расписанию. Но вместе с полезными сценариями вскрылись серьезные уязвимости выполнения кода и работы с приватными данными.

Управление секретами и санитайзер вывода

Главная опасность предоставления агенту прав на запуск консольных команд — компрометация конфиденциальных ключей и паролей. В архитектуре Smith используется схема разрешения секретов через облачный сервис управления криптографическими ключами GCP KMS (Google Cloud Key Management Service). Пользователь регистрирует секрет со списком контроля доступа (ACL). Когда агенту требуется выполнить команду, резолвер проверяет права владельца, группу и политики, расшифровывает значение через KMS и передает его исключительно как переменную окружения в изолированный процесс.

Чтобы секрет не утек обратно в диалог через ответ языковой модели, вывод каждой утилиты проходит санирование. Санитайзер заменяет все известные значения ключей на заглушку [REDACTED]. При этом список секретов предварительно сортируется по длине от самых длинных к коротким: это исключает ошибку, при которой замена короткого префикса оставляет незамаскированным хвост длинного токена.

На практике возникли неочевидные граничные случаи. В одном из инцидентов агент пытался записать конфигурационный файл через heredoc-блок в Bash, содержащий литералы правил самого санитайзера. Защитный механизм распознал фрагмент собственного правила как утечку и заблокировал системную команду. Другая сложность возникла при экранировании строковых литералов в Python.

Разграничение затронуло и доступ к GitHub. Вместо одного универсального токена система разделила сущности по принципу наименьших привилегий:

  • общий сервисный токен с правами только на чтение общедоступного кода;
  • отдельный токен на запись, ограниченный исключительно служебным репозиторием памяти агента;
  • персональные пользовательские токены OAuth, требующие явной авторизации сотрудника для действий от его имени.

«Тихая смерть» процесса и изоляция Node.js

Для безопасного выполнения Bash-командам выделили изолированный Docker-контейнер smith-exec на базе Ubuntu 24.04. Внутри контейнера работа ведется от непривилегированного пользователя без прав root, а в систему установлены только клиенты ClickHouse, PostgreSQL, Python 3 с библиотекой matplotlib, git и jq.

Вскоре разработчики столкнулись с феноменом «тихой смерти» сервиса. В среде Node.js обработка сетевых запросов и операций ввода-вывода управляется единым циклом событий — Event Loop. Когда агент запускал тяжелые синхронные вычисления, Event Loop намертво блокировался. При этом системный процесс операционной системы не падал с ошибкой, а продолжал висеть в памяти. В результате стандартный механизм перезапуска Restart=on-failure в менеджере служб systemd не срабатывал, а пользователи в Slack переставали получать ответы.

Для устранения зависаний была спроектирована многоуровневая система контроля живучести:

  • независимый сторожевой поток (watchdog), периодически проверяющий отзывчивость Event Loop;
  • жесткие таймауты обработки HTTP-запросов на уровне веб-фреймворка Fastify;
  • внешние проверки работоспособности через прокси Caddy, перезапускающие воркер при отсутствии ответа на контрольный эндпоинт.

Экстремальная нагрузка и изоляция памяти через cgroups

Один из показательных сбоев произошел во время аналитической сессии. Диалог превысил 170 сообщений, а аналитик запросил обработку результатов, вернувших структуры SQL MERGE объемом по 25 КБ каждая. Накопление контекста в оперативной памяти обошло механизм сжатия истории (compaction). Процесс Node.js стал лавинообразно потреблять оперативную память, что привело к заморозке виртуальной машины на 15 ГБ без файла подкачки swap.

В качестве защиты команда применила механизм контрольных групп ядра Linux (cgroups) через профили systemd. Ресурсы хоста жестко разделили на непересекающиеся квоты:

  • 6 ГБ выделено на обслуживание основного веб-интерфейса и API;
  • 4 ГБ зафиксировано за планировщиками фоновых задач;
  • 2 ГБ отдано на изолированное выполнение пользовательских скриптов.

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

Прогрессивное раскрытие инструментов и память агента

Изначально Smith имел в арсенале около 60 инструментов: 15 для браузера, 6 для BigQuery, 10 для секретов и служебные утилиты. Передача всех 60 описаний функций в системный промпт раздувала контекстное окно, увеличивала стоимость вызовов LLM и провоцировала ошибки выбора действий.

Решением стал подход прогрессивного раскрытия инструментов (Progressive Tool Disclosure). Базовый контекст каждого диалога содержит всего 18 постоянных утилит. Остальные возможности сгруппированы в специализированные пакеты (браузер, задачи cron, BigQuery, модификация данных, управление политиками секретов). Агент подключает эти пакеты динамически через мета-инструмент только тогда, когда запрос явно требует соответствующего функционала.

Долговременная память агента (Brain) организована в виде отдельного Git-репозитория со структурой docs/, skills/ и scripts/. Около 25 прикладных навыков были созданы и сохранены агентом самостоятельно. Версионирование в Git обеспечивает прозрачную историю изменений и откат некорректных правок. Дополнительно команда реализовала поддержку Model Context Protocol (MCP) через эндпоинт ask_smith, что позволило локальным средам разработки вроде Claude Code безопасно обращаться к внутренним сервисам через единую точку авторизации.

Архитектурные уроки и остающиеся риски

Опыт daily.dev показывает, что создание корпоративного ИИ-агента требует независимых, дублирующих слоев изоляции. Ни один отдельный компонент — будь то Docker-контейнер, шифрование KMS или ограничения cgroups — не гарантирует абсолютной безопасности сам по себе.

При этом разработчики открыто фиксируют компромиссы системы:

  • Аналитические запросы повышенной сложности вызывают сбой воркера примерно раз в неделю; благодаря автоматическому перезапуску восстановление занимает секунды, но первопричина обхода алгоритма сжатия контекста пока не устранена.
  • Сгенерированные агентом навыки в Brain не проходят регулярный ручной аудит безопасности, а их самоисправление в диалоге остается недоказанной гипотезой.
  • В системе отсутствует строгое доказательство невозможности повышения привилегий через косвенные промпт-инъекции.

Главный вывод кейса: надежное внедрение ИИ-агентов требует смещения фокуса с генерации промптов на классическую системную инженерию — управление правами доступа, жесткие лимиты ресурсов ОС, мониторинг живучести рантайма и изоляцию окружения выполнения.