Не давайте ИИ-агенту прямой доступ к базе. Как я проектировал безопасный контур действий на FastAPI и PostgreSQL

Не давайте ИИ-агенту прямой доступ к базе. Как я проектировал безопасный контур действий на FastAPI и PostgreSQL — Cybersecurity | Versia.media

Последнее время я всё чаще замечаю одну и ту же идею: бизнес никогда не предоставит ИИ-агенту доступ к клиентской базе, заявкам, платежам, CRM или внутренним документам. На первый взгляд это кажется логичным. Если агент ошибётся, перепутает контекст или выполнит не то действие, ущерб может быть вполне реальным. Однако, на мой взгляд, здесь часто смешивают два разных понятия.

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

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

В чём проблема прямого доступа

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

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

найти нужного клиента по описанию,

собрать краткую сводку по сделке,

предложить следующий шаг,

создать задачу менеджеру,

обновить комментарий в карточке клиента,

подготовить письмо,

проверить, какие заявки давно не обрабатывались.

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

Что помешает агенту прочитать лишние записи?

Что помешает ему изменить поле не у того клиента?

Что будет, если пользователь попросит выгрузить всю базу?

Как потом понять, кто инициировал действие?

Как отличить предложение агента от реально выполненной операции?

Как откатить ошибочное действие?

Где будет храниться лог рассуждения, если оно вообще нужно?

Кто несёт ответственность за мутацию данных?

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

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

Главный принцип: агент предлагает, система исполняет

Я для себя разделил всю схему на три слоя.

Первый слой — пользовательский запрос. Человек пишет: «Покажи мне клиентов, по которым давно не было контакта», или «Сформируй краткую сводку по Иванову», или «Добавь комментарий в карточку клиента».

Второй слой — непосредственно сам агент. Он анализирует намерение пользователя и преобразует его не в SQL-запрос, а в структурированное описание действия. Например: нужно получить карточку клиента, нужно создать комментарий, нужно поставить задачу, нужно запросить подтверждение.

Третий слой — это уже доверенный backend. Именно он проверяет права, применяет политики, решает, можно ли выполнить действие автоматически, нужно ли подтверждение, или действие нужно запретить.

Упрощённо схема будет выглядеть примерно так:

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

Почему prompt не является защитой

Частое упущение заключается в неправильном порядке и вообще в том, что кто-то пытается решить безопасность с помощью «некой» текстовой инструкции:

Такая инструкция полезна как дополнительный слой, но она не должна быть единственной защитой. Prompt можно неправильно составить, обойти, случайно получить конфликт инструкций или просто не учесть конкретный кейс.

Для backend-разработчика это должно звучать знакомо. Мы же не пишем в комментарии к API: «пожалуйста, не отправляйте чужой user_id». Мы проверяем права на сервере.

С агентами логика такая же. Модель может быть удобным интерфейсом к действиям, но проверка прав должна жить в обычном коде.

Минимальный формат действия

Я начал бы не с большой агентской платформы, а с маленького формата действия. Например, так:

Это не финальная промышленная модель, а идея. Агент должен вернуть не «выполни вот такой SQL», а объект:

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

Policy Gateway

Следующий слой — шлюз политик. Его задача не в том, чтобы быть умным. Его задача — быть скучным и предсказуемым.

Пример простого набора правил:

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

Важно, что allowed=True ещё не означает «сразу выполнить». Для части действий можно включить подтверждение: показать пользователю diff, текст комментария, список затронутых объектов и кнопку «Подтвердить».

Не генерировать SQL, а вызывать заранее описанные операции

Самое опасное место, как мне кажется, — это соблазн разрешить агенту писать SQL. Кажется, удобно: пользователь спрашивает, агент генерирует запрос, база отвечает. Но для бизнес-контура это слишком рискованно.

Я бы вообще не давал агенту возможность писать произвольный SQL. Вместо этого лучше создать каталог разрешённых операций.

Например, агент может запросить:

А backend уже сам вызывает безопасную функцию:

Даже если агент попросит чужого клиента, backend ограничит выборку по department_id. Даже если пользователь попробует обмануть агента, backend всё равно проверит область доступа.

Журналирование важнее красивого ответа

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

Я бы хранил минимум такие сущности:

Статусы могут быть простыми:

Главное — отделить то, что агент предложил, от того, что реально было выполнено. Это важная разница. В спорной ситуации нужно иметь возможность ответить на вопросы:

кто был пользователем,

какое действие предложил агент,

какая политика сработала,

было ли подтверждение,

что именно изменилось,

когда это произошло.

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

Пример endpoint на FastAPI

В минимальном варианте можно сделать endpoint, который принимает действие, проверяет политику и либо отклоняет его, либо отправляет на подтверждение, либо выполняет.

Здесь важно не то, что код идеален. В реальном проекте появятся транзакции, outbox, retries, фоновые задачи, роли, scopes, rate limits, idempotency keys и нормальная обработка ошибок. Важно другое: агент не исполняет действие напрямую. Между агентом и базой всегда стоит слой обычного backend-кода.

Почему подтверждение должно быть предметным

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

Лучше показывать конкретный diff!

Например, не так:

А так:

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

Что делать с персональными данными

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

Например, backend может сформировать безопасный контекст:

И уже этот ограниченный объект передать агенту. Модель не должна получать больше данных, чем нужно для конкретной операции.

Ошибки, которые я бы не закладывал в архитектуру

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

Вторая ошибка — свободный доступ к инструментам. Если агент может вызвать любой HTTP endpoint, любую shell-команду или любой SQL, это уже не помощник, а неконтролируемая точка входа во внутреннюю инфраструктуру.

Третья ошибка — отсутствие режима read-only. Для первого запуска агенту лучше дать только чтение и генерацию черновиков. Мутации можно добавлять позже, по одной операции, с подтверждениями и логами.

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

Пятая ошибка — не тестировать политики отдельно. Policy Gateway должен быть покрыт тестами так же, как любая критичная бизнес-логика.

Минимальный набор тестов

Даже для маленького прототипа я бы написал тесты на политики:

Такие тесты выглядят скучно, но именно они превращают разговор об ИИ-безопасности из философии в инженерную практику.

Что получается в итоге

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

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

Для меня базовая формула будет такая:

агент предлагает действие,

backend проверяет права,

политики решают уровень риска,

пользователь подтверждает мутации,

исполнительный слой вызывает только заранее разрешённые операции,

все действия пишутся в аудит.

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

← Cybersecurity