В лабораторном workflow на n8n, DeepSeek и HubSpot ИИ-агенту запретили запись в CRM. Модель не имела учётных данных HubSpot и не могла выполнить write напрямую. Тем не менее в контрольном сценарии CRM изменилась: downstream-узел n8n использовал собственный credential и выполнил PATCH для сделки LAB-043, хотя исходный запрос относился к LAB-042.
Это не гипотетический сценарий, а воспроизводимый класс ошибок. В классической security-логике он близок к confused deputy: компонент с полномочиями выполняет действие по параметрам, которые не проверены независимо. В агентных цепочках исполнения проблема проявляется иначе, чем в обычных API-интеграциях, потому что между моделью и внешней системой появляется оркестратор. Он принимает структурированное предложение модели и может выполнить его без отдельной проверки. Если у оркестратора есть credential на запись, система в целом остаётся способной изменить CRM, даже когда сама модель работает в режиме read-only.
| Сценарий | Запрос | Фактическая цель | Результат |
|---|---|---|---|
| Нормальный | LAB-042 | LAB-042 | Запись выполнена |
| Wrong-object без gateway | LAB-042 | LAB-043 | PATCH выполнен, LAB-043 изменена |
| Wrong-object с gateway | LAB-042 | LAB-043 | PATCH заблокирован, состояние не изменилось |
В тесте использовались две синтетические сделки: LAB-042 и LAB-043. В нормальном сценарии запрос, предложение и фактическая запись относились к LAB-042. Затем автор намеренно создал несовпадение: человекочитаемый запрос указывал на LAB-042, а структурированная цель — на LAB-043. Это не моделировало «злую модель», а проверяло контролируемый wrong-object case: остановит ли архитектура предложение с другим target до записи в CRM. В первой конфигурации независимой границы не было. n8n получил предложение, использовал собственный HubSpot credential и выполнил PATCH для LAB-043. Отдельное чтение после прогона подтвердило: LAB-043 изменилась, LAB-042 осталась в исходном состоянии.
Во второй конфигурации между предложением модели и HubSpot PATCH появился отдельный deterministic gateway. Его задача была узкой: перед разрешением записи проверить параметры, которые определяют допустимое последствие, — целевую систему, идентификатор объекта, ожидаемое исходное состояние и разрешённый переход. В лабораторном сценарии ожидаемый target был зафиксирован отдельно от результата генерации модели и использовался как источник проверки перед внешним вызовом. Учётные данные никуда не исчезли: n8n всё ещё мог писать в HubSpot. Изменилось другое — доступ к этому полномочию стал зависеть от отдельной проверки непосредственно перед внешним действием. Нормальный сценарий с LAB-042 получил allow и завершился записью. Wrong-object proposal с LAB-043 получил deny: HubSpot PATCH не запускался, а новое чтение подтвердило, что состояние сделки не изменилось.
Для CTO, product owner или security lead это практический вопрос. Формулировка «модель работает в read-only» может попасть в архитектурное описание, security review, клиентский опросник или решение о production-запуске. Но для такого решения важнее другое: какой компонент всей execution chain реально способен вызвать внешнее последствие — и что ограничивает его непосредственно перед действием. Ограничение полномочий модели само по себе не устраняет write-capability всей системы. Результат меняется, когда контроль появляется на границе исполнения.
Тот же класс wrong-object proposal, который в первой архитектуре привёл к изменению CRM, во второй был остановлен до записи. Это меняет не только оценку риска, но и порядок работ: перед расширением автономии агента и передачей решения клиенту имеет смысл проверить, где именно находится write и какой компонент может его инициировать. Если ответ «модель не может», этого недостаточно. Нужно понимать, что происходит на уровне оркестратора и какие проверки стоят между предложением и внешним вызовом.

