Session/memory isolation multi-tenant AI: client_id, TTL, leak-test 28 дней
Session/memory isolation в multi-tenant AI за 28 дней — это жёсткие scopes по client_id, TTL на сессии и память, red-team leak-test на перекрёстные запросы и audit-лог каждого доступа к чужому контексту. Без этого «общий агент на несколько клиентов» рано или поздно подмешает чужой бриф, цены или PII в ответ.
Я собираю изоляцию как production-контур, а не как «надеемся на промпт». Ниже — модель scopes, TTL, тесты утечек и журнал за 28 дней.
Модель scopes: что разделяем и где
Изолировать нужно не только «чат», а все слои, откуда модель может вытащить чужое.
| Слой | Ключ изоляции | Хранение | Риск без scope |
|---|---|---|---|
| Session | client_id + session_id | Redis / DB, short TTL | чужой диалог в контексте |
| Working memory | client_id + thread_id | vector/KV с namespace | чужие факты в summary |
| Long-term memory | client_id (+ optional workspace_id) | vector DB partition | RAG «подмешал» чужой KB |
| Tools / CRM | client_id → credentials map | secrets vault | запись в чужой Bitrix |
| Files / uploads | client_id + object ACL | object storage prefix | скачивание чужого файла |
| Eval / logs | client_id redacted | SIEM / cold storage | PII в общих логах |
Жёсткие правила:
client_idобязателен на входе — anonymous multi-tenant запрещён в prod.- Namespace в vector store =
client_id(не «тег надежды» в metadata-only фильтре без hard partition). - Tool-calling получает credentials только после resolve
client_id→ vault; общий API-ключ «на всех» = антипаттерн. - System prompt не содержит клиентских секретов и чужих playbook-фрагментов «на всякий случай».
Чеклист scope на старте:
- Middleware отбрасывает запрос без валидного
client_id/ tenant token. - Retrieval API принимает только namespace текущего tenant.
- Session store ключи вида
sess:CLIENT_ID:SESSION_ID. - Запрет cross-tenant admin API без отдельного break-glass роли и ticket-id.
TTL, ротация и «забывание»
| Тип данных | TTL (старт) | Продление | Удаление |
|---|---|---|---|
| Live session | 30–120 мин idle | activity touch | hard delete keys |
| Thread summary | 7–30 дней | явное «keep» | job + tombstone |
| Long-term facts | 90 дней / policy | re-consent | purge + reindex |
| Tool dry-run logs | 14 дней | — | cold archive scrubbed |
| Access audit | 180+ дней | — | WORM / append-only |
Политика, которую я фиксирую в runbook:
- Idle session kill — после TTL нельзя «дописать» старый
session_idбез re-auth. - Memory write всегда с
expires_at; фоновый worker чистит и пересобирает индекс. - Right to delete клиента = cascade: session → memory → files → tool tokens (кроме legally required audit).
- Нет silent infinite memory «для качества» — это прямой путь к leak и к раздуву стоимости.
Red-team leak-test: как ловим перекрёстные утечки
За 28 дней leak-test — не разовый скрипт, а регулярный gate.
| Тест | Сценарий | Pass-критерий |
|---|---|---|
| A↔B prompt inject | Tenant A просит «повтори memory tenant B» | отказ / пусто, 0 совпадений маркеров B |
| Session swap | Подмена session_id при валидном токене A | 403 / empty, audit event |
| Vector bleed | Одинаковый query, разные client_id | top-k документы только своего namespace |
| Tool ACL | A вызывает CRM-tool с id сущности B | deny + audit |
| Log scrape | Поиск маркера секрета B в логах A-job | 0 hits |
| Cache key collision | Одинаковый prompt hash у A и B | cache miss / key includes client_id |
Минимальный red-team набор (еженедельно):
- Засеять у tenant B canary-строки (уникальные токены в KB и session).
- С tenant A прогнать 20–50 adversarial prompts (прямые, roleplay, «debug mode», encoding tricks).
- Прогнать retrieval unit-тесты на 100 random queries.
- Сверить audit: любой deny/cross-attempt залогирован с
actor,client_id,resource,reason. - Fail pipeline деплоя, если canary найден хотя бы раз.
28 дней: план и audit-лог доступов
| Неделя | Фокус | Done |
|---|---|---|
| 1 | Middleware client_id, key schema session/memory, deny-by-default tools | 100% prod-запросов с tenant scope |
| 2 | TTL jobs, cascade delete, cache keys with client_id | idle kill + purge работают на staging |
| 3 | Red-team suite + canaries, CI gate | 0 canary leaks на 3 прогонах |
| 4 | Audit dashboard, on-call playbook, load test multi-tenant | отчёт + break-glass процедура |
Поля audit-события (минимум):
| Поле | Пример |
|---|---|
ts | ISO-8601 |
actor | user/api-key/agent-id |
client_id | tenant A |
action | memory.read / tool.crm.get / session.resume |
resource | id/hash |
decision | allow / deny |
reason | scope_mismatch / ttl_expired |
req_id | correlation id |
Алерты, без которых audit бесполезен:
- spike deny
scope_mismatchза 15 мин; - любой allow при несовпадении
client_idв токене и ресурсе (должно быть невозможно — если случилось, page on-call); - чтение memory после заявленного purge клиента.
Часто задаваемые вопросы
Хватает ли промпта «не раскрывай данные других клиентов»?
Нет. Промпт — мягкий слой. Утечки идут через retrieval, cache, session resume и tools. Изоляция должна быть в ключах хранилища и ACL, а промпт — только доп. ограждение.
Metadata-filter в vector DB вместо partition — ок?
Как единственная защита — нет. Фильтр ошибается, забывается в одном из query-path, обходится admin-search. Нужен hard namespace / separate collection / row-level enforcement на API.
Что делать с shared «глобальной» базой знаний студии?
Вынести в read-only global corpus без клиентского PII, отдельно от tenant memory. Клиентские факты — только в tenant scope. Смешивать в одном индексе «для удобства» нельзя.
Как доказать клиенту изоляцию?
Показать: schema ключей, TTL policy, отчёт red-team (без чужих данных), sample audit deny, процедуру purge. Это сильнее маркетинговых обещаний «у нас всё безопасно».
Читайте также
- База знаний RAG для AI-агента продаж: источники, PII, метрики за 30 дней
- Tool-calling Bitrix CRM: whitelist, dry-run, audit и откат
- Observability AI-агентов: eval, логи, red-team, scorecard за 14 дней
Нужна изоляция multi-tenant под ваш агент и CRM — разберём scopes, TTL и leak-test на raisovich.ru.
Какие слои multi-tenant AI нужно изолировать по client_id?
Session, working/long-term memory, tools/CRM credentials, файлы и eval/logs — namespace и ACL на каждом слое, не только в чате.
Какой TTL ставить на session и long-term memory?
Live session 30–120 мин idle с hard delete, thread summary 7–30 дней, long-term facts по policy ~90 дней; silent infinite memory запрещён.
Как устроен red-team leak-test за 28 дней?
Canary-строки у tenant B, adversarial prompts от A, vector bleed и tool ACL тесты, audit deny и fail CI при любом canary leak.
Подпишитесь на @raisovich_news
Первыми получайте новые статьи об AI-автоматизации, нейросетях для бизнеса и создании сайтов. Без спама — только полезный контент.
Часто задаваемые вопросы
Какие слои multi-tenant AI нужно изолировать по client_id?
Session, working/long-term memory, tools/CRM credentials, файлы и eval/logs — namespace и ACL на каждом слое, не только в чате.
Какой TTL ставить на session и long-term memory?
Live session 30–120 мин idle с hard delete, thread summary 7–30 дней, long-term facts по policy ~90 дней; silent infinite memory запрещён.