MAATRIX / Блог / Утечка данных через ИИ-ассистента: сценарии и защита

Утечка данных через ИИ-ассистента: сценарии и защита

MAATRIX

Корпоративный ИИ-ассистент подключили ко всем удобным источникам — почте, вики, тикетам, базе данных, — и через месяц кто-то из отдела продаж случайно узнаёт зарплату коллеги, потому что спросил ассистента «какие у нас в компании оклады» и получил честный агрегированный ответ. Это не гипотетика и не баг конкретного вендора — это системная особенность того, как устроены RAG и MCP-подключения, и её нужно закрывать инженерными мерами, а не надеждой на то, что ассистент «сам разберётся». Ниже — четыре реалистичных сценария утечки и конкретные технические меры против каждого.

Агрегация знаний ломает права доступа исходных систем

Самый частый и самый незаметный сценарий: ИИ-ассистент строит единый поисковый индекс поверх нескольких источников — Confluence, Google Drive, тикет-система, внутренняя вики, — и на этапе индексации права доступа исходных систем просто не переносятся. Документ, который в Confluence был виден только HR-группе, попадает в общий векторный индекс наравне с публичным регламентом отпусков. Дальше любой сотрудник, у которого есть доступ к самому ассистенту, может — не имея злого умысла, а просто задав обычный рабочий вопрос — получить в ответе выдержку из документа, к которому у него никогда не было прав в исходной системе.

Механизм всегда один: пайплайн источник → эмбеддинги → векторная база → поиск в базовой реализации не тащит за собой ACL (access control list) исходного документа. Разработчики RAG-пайплайна фокусируются на релевантности поиска и забывают, что у эмбеддинга нет метаданных «кому можно это показывать». Это ровно та проблема, которую подробно разбирает статья про права доступа в RAG — там же и конкретные схемы реализации document-level и row-level фильтрации на уровне векторной базы.

Практически это чинится тремя способами, и их стоит комбинировать, а не выбирать один:

  • Фильтрация на этапе retrieval по метаданным. При индексации каждому чанку присваивается тег allowed_groups (или owner_id), скопированный из исходной системы прав. Запрос к векторной базе всегда идёт с фильтром по группам текущего пользователя — не постфактум, отфильтровывая уже найденные документы, а как часть самого запроса (WHERE allowed_groups && current_user_groups), иначе релевантные, но недоступные документы просто не попадут в top-k и не «утекут» через ранжирование.
  • Раздельные индексы вместо одного общего. Для источников с принципиально разными уровнями чувствительности (HR, финансы, обычная документация) проще держать отдельные коллекции в векторной базе и на уровне приложения решать, к каким коллекциям у текущего запроса вообще есть доступ, чем городить сложную ACL-логику внутри одной большой коллекции.
  • Синхронизация прав, а не разовый импорт. Права в исходных системах меняются — сотрудник уволился, поменял отдел, потерял доступ к проекту. Если индексация ACL — разовое событие при первой загрузке документа, то через полгода индекс будет врать. Нужен периодический пересчёт (или вебхук на изменение прав в источнике), который перестраивает allowed_groups для существующих чанков.

Слишком широкие права у самого подключения к источнику данных

Второй сценарий — не про агрегацию нескольких систем, а про то, что связка «ассистент → один конкретный источник» изначально настроена с избыточными правами. Классика — MCP-сервер, подключающий ассистента к рабочей базе данных, использует единую учётную запись с правами на все таблицы и схемы, хотя функционально ассистенту нужен SELECT по трём таблицам для одной конкретной задачи (например, отвечать на вопросы про статус заказа). Формально ассистент «работает как надо» — до тех пор, пока кто-то не задаст ему запрос, который заставит модель сформировать SQL-запрос за пределами предполагаемого сценария использования, и в ответе не окажутся данные из таблицы с персональными данными клиентов или платёжными реквизитами, к которым по смыслу задачи обращаться было не нужно.

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

Минимизация прав подключения — это не общая рекомендация, а конкретная настройка на стороне СУБД:

-- Отдельная роль для MCP-подключения, не пересекающаяся с ролью приложения
CREATE ROLE mcp_assistant_ro LOGIN PASSWORD '...';

-- Доступ только к нужным таблицам, только на чтение
GRANT SELECT ON orders, order_items, order_status_history TO mcp_assistant_ro;

-- Явный запрет на таблицы с чувствительными данными,
-- даже если они попадают в ту же схему
REVOKE ALL ON customers, payment_methods, employee_salaries FROM mcp_assistant_ro;

-- Ограничение по столбцам там, где нужна не вся таблица целиком
GRANT SELECT (id, status, updated_at) ON orders TO mcp_assistant_ro;

Если СУБД поддерживает row-level security (Postgres, начиная с 9.5), это даёт дополнительный уровень — ограничение не по столбцам, а по строкам, в зависимости от того, от чьего имени сейчас работает ассистент:

ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

CREATE POLICY orders_own_department ON orders
  USING (department_id = current_setting('app.current_department')::int);

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

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

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

Развернуть ИИ на сервере

Данные покидают периметр компании вместе с промптом к облачному API

Третий сценарий возникает в гибридных схемах, где часть логики (например, оркестрация MCP-подключений и агрегация контекста) работает на собственном сервере, а сама генерация ответа идёт через облачный API — OpenAI, Anthropic, любой другой провайдер модели. В этот момент данные, которые ассистент собрал из внутренних источников для формирования контекста запроса, физически покидают периметр компании и отправляются на серверы стороннего провайдера как часть промпта.

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

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

Промпт-инъекция как канал активной эксфильтрации

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

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

Систематизированный набор защитных мер

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

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

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

2026-08-27T11:14:02Z user=ivanov.a source=mcp:orders_db
  query="SELECT status FROM orders WHERE id=42112"
  rows_returned=1 columns=[status,updated_at]
  action=reply_to_user

Без такого лога расследование инцидента («что именно узнал ассистент и кому это передал») превращается в гадание по логам самой модели, которые часто недостаточно структурированы для этого.

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

Регулярный пересмотр реально предоставленных прав. Права доступа, которые казались разумными при подключении первого источника, часто перестают быть разумными к десятому. Ассистент, который начинался с доступа только к базе знаний, через год оброс подключениями к CRM, тикет-системе, внутреннему мессенджеру, календарю — и никто не пересматривал, действительно ли каждое из этих подключений всё ещё нужно с тем объёмом прав, с которым оно было выдано изначально. Стоит завести регулярный (например, ежеквартальный) обзор: список всех активных MCP-подключений ассистента, для каждого — реально используемый объём прав против выданного, и явное решение оставить/сузить/отключить. Отправная точка для новых подключений — принцип «начинать с малого», описанный в статье про выбор MCP-серверов: подключать по одному источнику, проверять реальную пользу и реальные риски, и только потом расширять набор, а не подключать сразу весь доступный каталог интеграций.

Практический вывод: взвешивайте каждую новую интеграцию

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

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

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

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

Развернуть ИИ на сервере

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

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

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

Достаточно ли обычного RBAC (ролевой модели доступа) в самой компании, чтобы закрыть все эти риски?

Нет — RBAC определяет, кто в принципе имеет право видеть данные в исходной системе, но не гарантирует, что RAG-индекс или MCP-подключение унаследуют эти правила автоматически. Их нужно явно синхронизировать с ACL источника, как описано в разделе про агрегацию знаний.

Можно ли просто запретить ассистенту доступ к чувствительным данным вообще?

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

Как понять, какой объём прав у MCP-подключения избыточен?

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

Нужно ли логировать вообще все запросы к ассистенту, даже те, что не касаются чувствительных данных?

Разумный минимум — логировать все запросы к источникам, помеченным как чувствительные, и все действия, которые отправляют данные за пределы системы (письма, вебхуки, внешние API). Логирование каждого обращения к общедоступной базе знаний обычно избыточно и просто раздувает объём логов без пользы для аудита.

Локальная модель полностью решает проблему утечки во внешний API?

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

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

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

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