Эфир 18.11 · Поток 318 ноября в 19:00 МСК — бесплатный практический эфир по ИИ-агентам · Живой Поток 3 стартует 23.11Эфир 18 ноября →Поток 3 (23.11)
Безопасность и правоРазбор · На радарAWS Machine Learning Blog→ оригинал

AWS показал, как не дать LLM-агенту читать чужие документы: userContext подставляет шлюз

Если корпоративный агент ходит в общую базу знаний, то «от чьего имени искать» часто передаётся аргументом инструмента — и значение придумывает LLM. Одна prompt injection, и сотрудник отдела A получает план отдела B. AWS предлагает не доверять модели: шлюз AgentCore перезаписывает userContext из проверенного JWT, а база знаний фильтрует документы по ACL.

AI-обработка оригинала AWS Machine Learning Blog; редакция Hamidun News
AWS показал, как не дать LLM-агенту читать чужие документы: userContext подставляет шлюз
Источник: AWS Machine Learning Blog. Коллаж: Hamidun News.
Слушать статью
Паспорт материала и цифры
ПараметрДанные
ПервоисточникAWS Machine Learning Blog ↗
Главный редактор
Ключевой факт #1Перехватчик запросов в Lambda всегда затирает userContext из токена
Ключевой факт #2Политика Cedar блокирует запрос, если userId не совпадает с email в JWT
Ошибки в ACL не дают ошибокдокументы молча пропадают из выдачи

Представьте внутреннего ассистента, которым пользуется вся компания. Сотрудник отдела A просит: «Сравни план моего отдела с общим уведомлением и покажи отстающие инициативы». Агент сам формулирует поисковые запросы и копает по документам, пока не наберёт достаточно информации. Тот же вопрос задаёт сотрудник отдела B. Если поиск не привязан к конкретному человеку, бизнес-план одного отдела легко окажется в ответе другому. В мультиарендном SaaS то же самое случается с клиентскими компаниями, и цена ошибки там выше.

AWS Machine Learning Blog выпустил разбор, как закрыть эту дыру в связке Amazon Bedrock Managed Knowledge Base и AgentCore Gateway.

Почему с агентами сложнее, чем с обычным приложением

В классическом приложении код сам знает, кто вошёл в систему, и ищет с правами этого пользователя. В агенте инструмент вызывает LLM, и аргументы тоже выбирает она. Если у поискового инструмента есть параметр «от чьего имени искать», его заполнит модель. Хватит фразы пользователя «поищи как user-b», ошибки модели или косвенной prompt injection в найденном документе, и агент ищет под чужой личностью.

У Managed Knowledge Base есть режим ACL awareness. При загрузке данных база запоминает права на документы, а при поиске отдаёт только то, что разрешено пользователю из userContext.userId (это его email). Но сама база пользователей не аутентифицирует, она верит тому, что пришло. А когда её публикуют как MCP-инструмент через AgentCore Gateway, userContext становится обычным аргументом, который строит модель. Ни шлюз, ни база не проверяют, что значение принадлежит вошедшему человеку.

Четыре слоя: два основных и два страховочных

Принцип простой: LLM не решает, кто пользователь. Это решает доверенный код на основе данных, которые проверил провайдер идентификации. Запрос проходит так:

  • Пользователь входит через Amazon Cognito и получает JWT. Lambda-триггер pre token generation добавляет в токен claim с email.
  • Агент пересылает токен в заголовке Authorization, а авторизатор шлюза проверяет подпись, срок действия и client ID.
  • Request interceptor, то есть Lambda на шлюзе, достаёт email из проверенного токена и перезаписывает userContext в каждом вызове tools/call. Что бы ни прислал клиент или модель, база получит email реального пользователя. Батчи и невалидные тела запросов отклоняются по принципу fail-closed.
  • Policy in AgentCore проверяет Cedar-политикой, что userContext.userId совпадает с email из JWT. Если нет, запрос отклоняется.
  • Resource-based policy базы знаний запрещает поиск всем, кроме роли выполнения шлюза.

Первые два слоя (перехватчик и ACL) — основная защита. Для запросов через шлюз их достаточно, если больше никто не может обратиться к базе напрямую. Cedar-политика и resource-based policy нужны на случай бага в перехватчике или постороннего принципала с правом bedrock:Retrieve в том же аккаунте. Сам агент на Strands Agents логики доступа не содержит: он просто пробрасывает токен дальше.

Подводные камни

  • ACL для S3 задаются глобальным файлом на префикс или метафайлом на документ. Документ без ACL просто не попадёт в индекс.
  • Изменения прав применяются только после следующей синхронизации: проверки в реальном времени у S3 нет.
  • Ошибки в ACL не вызывают исключений, документы тихо исчезают из выдачи. Проверяйте это тестами.
  • Запрос без userContext не вернёт документы из источника с включёнными ACL, зато документы из источника без ACL увидят все.
  • Для кастомизации access token в Cognito нужен план Essentials или Plus. На Lite email в токене не появится.
  • Чтобы перехватчик мог записать userContext, его нужно открыть в схеме инструмента через parameterOverrides, даже если клиенты его не задают.

Что с этим делать

Вывод шире, чем один продукт AWS. Любой параметр, определяющий идентичность или права, не должен быть аргументом, который заполняет модель. Подставляйте его на уровне шлюза или сервера инструментов из проверенного токена, а поверх добавляйте независимую проверку. Если вы делаете мультиарендного агента, посмотрите, не отдаёте ли вы модели tenant_id или user_id.

Готовый пример на CDK лежит в репозитории sample-managed-knowledge-base-patterns, в каталоге agentcore-access-control. Оговорка: это схема для стека AWS, и на других платформах её придётся воспроизводить самостоятельно.

Сюжет

Вопросы и ответы по материалу

Что известно по теме: почему с агентами сложнее, чем с обычным приложением?

В классическом приложении код сам знает, кто вошёл в систему, и ищет с правами этого пользователя. В агенте инструмент вызывает LLM, и аргументы тоже выбирает она. Если у поискового инструмента есть параметр «от чьего имени искать», его заполнит модель. Хватит фразы пользователя «поищи как user-b», ошибки модели или косвенной prompt injection в найденном документе, и агент ищет под чужой личностью. У Managed Knowledge Base есть режим ACL awareness.

Что известно по теме: четыре слоя: два основных и два страховочных?

Принцип простой: LLM не решает, кто пользователь. Это решает доверенный код на основе данных, которые проверил провайдер идентификации. Запрос проходит так: Пользователь входит через Amazon Cognito и получает JWT. Lambda-триггер pre token generation добавляет в токен claim с email. Агент пересылает токен в заголовке Authorization, а авторизатор шлюза проверяет подпись, срок действия и client ID.

Что известно по теме: подводные камни?

ACL для S3 задаются глобальным файлом на префикс или метафайлом на документ. Документ без ACL просто не попадёт в индекс. Изменения прав применяются только после следующей синхронизации: проверки в реальном времени у S3 нет. Ошибки в ACL не вызывают исключений, документы тихо исчезают из выдачи. Проверяйте это тестами. Запрос без userContext не вернёт документы из источника с включёнными ACL, зато документы из источника без ACL увидят все. Для кастомизации access token в Cognito нужен план Essentials или Plus.

ЖХ
Жемал Хамидун — CPO Alpina Digital, продакт-менеджер AlpinaGPT. Делает AI-продукты с 2019 года. Hamidun News — pet project, который вырос в production-агрегатор с 6000+ читателей.
✦ Закрытый клуб практиков · Vibe Club

Внедряйте ИИ быстрее рынка вместе с инженерами и фаундерами

Внутри Vibe Club (hamidun.com/club): еженедельные живые мастермайнды и разборы архитектуры с Жемалом Хамидуном, закрытый Tech Radar, LMS и обновляемая база из 370+ боевых скиллов.

Вступить в Vibe Club →Тест-драйв Академии (72ч)
Что вы думаете?
Загружаем комментарии…