Безопасность

AWS показала multi-tenant чат по документам без собственного vector store

Amazon Bedrock Managed Knowledge Base принимает пользовательские файлы, индексирует их асинхронно и применяет фильтр tenant на каждом шаге agentic retrieval. Граница доступа строится из проверенного JWT, а не из данных клиента.

AWS показала multi-tenant чат по документам без собственного vector store

AWS опубликовала референсную архитектуру multi-tenant document chat на Amazon Bedrock Managed Knowledge Base. Пользователь загружает договор, отчёт или руководство, ждёт появления документа в индексе и задаёт вопросы в том же приложении. Managed Knowledge Base выполняет parsing, embedding, indexing, ranking и agentic retrieval, а продуктовая команда сохраняет контроль над authentication, upload UX, chat UI, tenant isolation и собственной бизнес-логикой.

Критическая граница проекта — `user_id`. Amazon API Gateway проверяет JWT от Amazon Cognito, после чего сервер берёт идентификатор `sub` из валидированного токена. Этот ID передаётся в ingestion job и записывается в metadata документа. При каждом запросе приложение снова получает значение из проверенной identity и формирует явный equals filter для `AgenticRetrieveStream`; клиент не может прислать tenant ID в body и выбрать чужую область поиска.

Два маршрута загрузки и асинхронный индекс

Upload endpoint не ждёт обработки файла. Он помещает задание в Amazon SQS и сразу отвечает браузеру, а Lambda worker вызывает `IngestKnowledgeBaseDocuments`. Документы размером до 6 MB можно передать inline. Более крупный текстовый файл — до 50 MB в описанной схеме — сначала попадает в Amazon S3, а worker передаёт сервису его S3 URI. Повторная загрузка с тем же document ID обновляет объект вместо создания дубля.

Indexing проходит через состояния `STARTING`, `PENDING`, `IN_PROGRESS`, `TEXT_INDEXED` и `INDEXED`. Текст уже доступен для поиска на стадии `TEXT_INDEXED`, тогда как `INDEXED` означает завершение multimodal processing, включая изображения и таблицы в PDF. В собственном тесте AWS небольшие plain-text документы становились полностью доступны за 2–3 секунды, PDF — searchable по тексту за 5–30 секунд и полностью `INDEXED` примерно за 90 секунд. Компания подчёркивает, что это ориентиры, а не SLA.

Статус каждого документа хранится в DynamoDB, а браузер опрашивает status endpoint и показывает переход от received к processing и ready. Это не косметическая деталь: если считать ответ `STARTING` доказательством готовности, первый вопрос пользователя может вернуть пустой результат. Для текстового поиска UI разумно открывать на `TEXT_INDEXED`, явно отделяя его от полной готовности multimodal content.

Изоляция применяется на каждом retrieval hop

Сложный вопрос `AgenticRetrieveStream` разбивает на подзапросы и выполняет несколько retrieval operations. Явный metadata filter должен сопровождать каждый такой hop. AWS называет server-side derivation из проверенного JWT самой границей безопасности: вывод фильтра из текста запроса может помогать релевантности, но не является access control. В reference implementation результат дополнительно проверяется, и chunk с несовпадающим `user_id` отбрасывается.

Для большого числа индивидуальных пользователей AWS предпочитает одну shared knowledge base с обязательным фильтром: это снижает baseline cost, provisioning latency и давление на account quotas. Отдельная база на tenant остаётся вариантом для небольшого числа крупных клиентов с жёсткими требованиями изоляции. Возможность искать сразу по нескольким knowledge bases предназначена для объединения тематических доменов одного пользователя, а не для разделения арендаторов.

Неавторизованный запрос в примере получает HTTP 401, а валидный запрос без доступного `sub` — HTTP 403. Для регулируемых систем Managed Knowledge Base также поддерживает document-level ACL, которые сервис оценивает через `userContext` во время запроса. Это переносит enforcement из application code на уровень сервиса и может использоваться как более сильная граница.

Очередь защищает ingestion от всплесков

Один вызов `IngestKnowledgeBaseDocuments` принимает до десяти документов. Поэтому Lambda worker может объединять jobs: пример с 500 одновременными загрузками превращается примерно в 50 API calls. Неудачные сообщения уходят в dead-letter queue, а upload endpoint остаётся отзывчивым при backpressure. Для bulk migration AWS советует использовать S3 connector с scheduled sync, чтобы массовая загрузка не конкурировала с интерактивными пользовательскими файлами.

Есть неочевидная операционная ловушка: превышение concurrency limit возвращает `ValidationException`, а не `ThrottlingException`. Если retry policy повторяет только throttling errors, документ будет ошибочно признан безвозвратно неудачным. AWS рекомендует следить за ingestion success rate, P50 и P99 времени до `INDEXED`, а также retrieval latency; рост времени индексирования служит ранним сигналом приближения к пределу.

Retrieval управляемый, история диалога — нет

`AgenticRetrieveStream` может провести полный chat turn: декомпозировать вопрос, применить per-user filter к подзапросам и потоково вернуть grounded answer с цитатами. Если нужен собственный prompt или конкретная модель, AWS предлагает вызвать `Retrieve`, а затем `Converse`, не забыв тот же tenant filter. `GetDocumentContent` возвращает исходный файл, чтобы пользователь мог открыть источник ответа.

При этом API не хранит историю между вызовами. Предыдущие turns можно передать в параметре `messages`, но приложение должно сохранять conversation history самостоятельно, например в DynamoDB, и изолировать её по тем же правилам, что и документы. Managed retrieval снимает эксплуатацию vector stack, но не превращается в готовую систему identities, sessions и product permissions.

Почему это важно

Главный урок этой архитектуры — tenant isolation нельзя оставлять на усмотрение модели. Prompt, inferred filter и client-supplied ID не являются надёжной границей. Проверенная identity должна на сервере превращаться в неизменяемую metadata при ingestion и в обязательный фильтр при каждом retrieval. Защита усиливается проверкой возвращённых chunks и, где требуется, service-enforced ACL.

Практический вывод — тестировать не только удачный вопрос, но и весь lifecycle. Нужны отрицательные проверки чужого `user_id`, повторная загрузка того же document ID, запросы во время `STARTING`, переход к `TEXT_INDEXED`, очередь при burst, dead-letter path и retry на `ValidationException`. Отдельно следует убедиться, что история чата, source previews и удаление файлов следуют той же tenant boundary. Только тогда удобный «загрузил и спросил» перестаёт быть демонстрацией и становится безопасной multi-tenant функцией.

Первоисточники

  1. Build multi-tenant agentic chat applications on enterprise data with Amazon Bedrock Managed Knowledge Base