{"title":"Multi-tenancy и изоляция","slug":"multi-tenancy","category":"concepts","summary":"Как Synapse изолирует данные между пользователями и minds — разбор границ безопасности.","audience":["human","llm"],"tags":["concept","multi-tenancy","security","isolation"],"difficulty":"intermediate","updated":"2026-06-27","word_count":528,"read_minutes":3,"lang":"ru","translated":true,"requested_lang":"ru","content_markdown":"\n# Multi-tenancy и изоляция\n\nSynapse — multi-tenant-система: несколько пользователей, у каждого — несколько\nmind, полностью изолированных друг от друга. На этой странице описана модель\nизоляции.\n\n## Иерархия арендаторов\n\n```\nSynapse Instance\n  │\n  ├── User Account 1 (email: alice@example.com)\n  │   ├── Mind A (Mind Key mk_aaa...)\n  │   │   ├── Memories (only accessible via mk_aaa...)\n  │   │   ├── Tasks\n  │   │   └── Chat\n  │   └── Mind B (Mind Key mk_bbb...)\n  │       └── ... (isolated from Mind A)\n  │\n  ├── User Account 2 (email: bob@example.com)\n  │   └── Mind C (Mind Key mk_ccc...)\n  │       └── ... (isolated from Alice's minds)\n  │\n  └── ... (more users)\n```\n\n## Уровни изоляции\n\n### Уровень 1: изоляция пользователей\n\nКаждый аккаунт пользователя изолирован. Alice не может:\n\n- Видеть mind пользователя Bob\n- Получать доступ к воспоминаниям Bob (даже со своим JWT)\n- Просматривать данные аккаунта Bob\n\nОбеспечивается: колонкой `user_id` во всех таблицах, JWT содержит `user_id`,\nвсе запросы фильтруются по `user_id`.\n\n### Уровень 2: изоляция mind\n\nВ рамках пользователя каждый mind изолирован. Mind A не может:\n\n- Видеть воспоминания Mind B\n- Получать доступ к задачам, чату, скриптам Mind B\n\nОбеспечивается: колонкой `mind_id` во всех таблицах данных, Mind Key содержит\n`mind_id`, все запросы фильтруются по `mind_id`.\n\n> [!CRITICAL]\n> Изоляция Mind Key — основная граница безопасности. Утёкший Mind Key даёт\n> полный доступ к данным этого mind — но ТОЛЬКО этого mind.\n\n## Токены аутентификации\n\n| Токен | Область | Что может получить |\n|-------|-------|-------------------|\n| Mind Key | Один mind | Только данные этого mind |\n| JWT | Аккаунт пользователя | Управление аккаунтом (создание/список/удаление mind) |\n| Computer Token | Один компьютер | Команды этого компьютера |\n\n## Доступ между mind\n\n### В рамках одного пользователя\n\nПользователь может получить доступ ко всем своим mind через JWT (например,\n`GET /minds` возвращает список всех). Но для чтения/записи данных памяти требуется\nконкретный Mind Key.\n\n### Между пользователями\n\nПользователи не могут получать доступ к данным друг друга — КРОМЕ случая,\nкогда они явно поделились mind через Sharing API:\n\n```bash\n# Alice shares Mind A with Bob\ncurl -X POST https://synapse.schaefer.zone/sharing \\\n  -H \"Authorization: Bearer ALICE_JWT\" \\\n  -d '{\"mind_id\": \"m_aaa\", \"email\": \"bob@example.com\", \"role\": \"read\"}'\n```\n\nПосле этого Bob может получить доступ к Mind A через свой JWT\n(только для чтения, если `role=read`).\n\n## Границы безопасности\n\n```\n┌─────────────────────────────────────────────────┐\n│              Synapse Instance                    │\n│  ┌─────────────────────────────────────────┐    │\n│  │         User Account Boundary           │    │\n│  │  ┌──────────────┐  ┌──────────────┐    │    │\n│  │  │  Mind Bound. │  │  Mind Bound. │    │    │\n│  │  │  (Mind Key)  │  │  (Mind Key)  │    │    │\n│  │  │              │  │              │    │    │\n│  │  │  Memories    │  │  Memories    │    │    │\n│  │  │  Tasks       │  │  Tasks       │    │    │\n│  │  │  Chat        │  │  Chat        │    │    │\n│  │  │  Scripts     │  │  Scripts     │    │    │\n│  │  └──────────────┘  └──────────────┘    │    │\n│  └─────────────────────────────────────────┘    │\n└─────────────────────────────────────────────────┘\n```\n\n## Типовые паттерны multi-tenancy\n\n### Паттерн 1: один пользователь, один mind\n\nНаиболее распространён у индивидуальных пользователей LLM-агентов.\n\n- 1 аккаунт пользователя\n- 1 mind\n- 1 Mind Key\n- Все воспоминания в одной области\n\n### Паттерн 2: один пользователь, несколько mind\n\nДля пользователей с несколькими контекстами (работа, личное, проекты).\n\n- 1 аккаунт пользователя\n- N mind (например, «work», «personal», «project-x»)\n- N Mind Key\n- Каждая LLM-сессия использует один Mind Key\n\n### Паттерн 3: командный общий mind\n\nДля команд, сотрудничающих над проектом.\n\n- 1 пользователь создаёт mind (получает Mind Key)\n- Создатель делится с участниками команды через JWT\n- Все участники получают доступ через JWT (или общий Mind Key)\n\n> [!WARNING]\n> Передача Mind Key даёт полный доступ на чтение/запись. Для командной работы\n> предпочтительнее Sharing API (на основе JWT), а не прямой обмен Mind Key.\n\n### Паттерн 4: SaaS-провайдер\n\nДля приложений, встраивающих Synapse как слой памяти.\n\n- Каждый клиент = 1 аккаунт пользователя\n- Каждый проект клиента = 1 mind\n- Приложение хранит Mind Key по каждому клиенту/проекту\n- Полная изоляция между клиентами\n\n## Проверка изоляции\n\n### Тест: Mind Key не может получить доступ к другим mind\n\n```bash\n# Mind A's key cannot read Mind B's memories\ncurl -H \"Authorization: Bearer mk_aaa...\" \\\n     \"https://synapse.schaefer.zone/memory/search?q=test\"\n# Returns only Mind A's memories\n\ncurl -H \"Authorization: Bearer mk_bbb...\" \\\n     \"https://synapse.schaefer.zone/memory/search?q=test\"\n# Returns only Mind B's memories (different results)\n```\n\n### Тест: JWT не может читать данные памяти напрямую\n\n```bash\n# JWT can list minds\ncurl -H \"Authorization: Bearer YOUR_JWT\" \\\n     https://synapse.schaefer.zone/minds\n# Returns: list of minds\n\n# JWT CANNOT read memories (need Mind Key)\ncurl -H \"Authorization: Bearer YOUR_JWT\" \\\n     https://synapse.schaefer.zone/memory/recall\n# Returns: 401 Unauthorized\n```\n\n## Лучшие практики\n\n> [!TIP]\n> - **Используйте один mind на проект/контекст** — изоляция вам помогает\n> - **Никогда не передавайте Mind Key** — используйте Sharing API\n> - **Ротируйте Mind Key** при компрометации (удалите mind, создайте новый)\n> - **Аудит общих mind** — периодически проверяйте `GET /sharing`\n> - **Используйте JWT для человеко-ориентированного UI** — никогда не показывайте Mind Key конечным пользователям\n\n## Следующие шаги\n\n- [Аутентификация](/docs/getting-started/authentication)\n- [Mind Key против JWT](/docs/getting-started/mind-key-vs-jwt)\n- [Архитектура](/docs/concepts/architecture)\n","content_html":"<h1>Multi-tenancy и изоляция</h1>\n<p>Synapse — multi-tenant-система: несколько пользователей, у каждого — несколько\nmind, полностью изолированных друг от друга. На этой странице описана модель\nизоляции.</p>\n<h2>Иерархия арендаторов</h2>\n<pre><code class=\"hljs language-plaintext\">Synapse Instance\n  │\n  ├── User Account 1 (email: alice@example.com)\n  │   ├── Mind A (Mind Key mk_aaa...)\n  │   │   ├── Memories (only accessible via mk_aaa...)\n  │   │   ├── Tasks\n  │   │   └── Chat\n  │   └── Mind B (Mind Key mk_bbb...)\n  │       └── ... (isolated from Mind A)\n  │\n  ├── User Account 2 (email: bob@example.com)\n  │   └── Mind C (Mind Key mk_ccc...)\n  │       └── ... (isolated from Alice&#x27;s minds)\n  │\n  └── ... (more users)</code></pre><h2>Уровни изоляции</h2>\n<h3>Уровень 1: изоляция пользователей</h3>\n<p>Каждый аккаунт пользователя изолирован. Alice не может:</p>\n<ul>\n<li>Видеть mind пользователя Bob</li>\n<li>Получать доступ к воспоминаниям Bob (даже со своим JWT)</li>\n<li>Просматривать данные аккаунта Bob</li>\n</ul>\n<p>Обеспечивается: колонкой <code>user_id</code> во всех таблицах, JWT содержит <code>user_id</code>,\nвсе запросы фильтруются по <code>user_id</code>.</p>\n<h3>Уровень 2: изоляция mind</h3>\n<p>В рамках пользователя каждый mind изолирован. Mind A не может:</p>\n<ul>\n<li>Видеть воспоминания Mind B</li>\n<li>Получать доступ к задачам, чату, скриптам Mind B</li>\n</ul>\n<p>Обеспечивается: колонкой <code>mind_id</code> во всех таблицах данных, Mind Key содержит\n<code>mind_id</code>, все запросы фильтруются по <code>mind_id</code>.</p>\n<div class=\"callout callout-critical\">Изоляция Mind Key — основная граница безопасности. Утёкший Mind Key даёт\nполный доступ к данным этого mind — но ТОЛЬКО этого mind.</div><h2>Токены аутентификации</h2>\n<table>\n<thead>\n<tr>\n<th>Токен</th>\n<th>Область</th>\n<th>Что может получить</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Mind Key</td>\n<td>Один mind</td>\n<td>Только данные этого mind</td>\n</tr>\n<tr>\n<td>JWT</td>\n<td>Аккаунт пользователя</td>\n<td>Управление аккаунтом (создание/список/удаление mind)</td>\n</tr>\n<tr>\n<td>Computer Token</td>\n<td>Один компьютер</td>\n<td>Команды этого компьютера</td>\n</tr>\n</tbody></table>\n<h2>Доступ между mind</h2>\n<h3>В рамках одного пользователя</h3>\n<p>Пользователь может получить доступ ко всем своим mind через JWT (например,\n<code>GET /minds</code> возвращает список всех). Но для чтения/записи данных памяти требуется\nконкретный Mind Key.</p>\n<h3>Между пользователями</h3>\n<p>Пользователи не могут получать доступ к данным друг друга — КРОМЕ случая,\nкогда они явно поделились mind через Sharing API:</p>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># Alice shares Mind A with Bob</span>\ncurl -X POST https://synapse.schaefer.zone/sharing \\\n  -H <span class=\"hljs-string\">&quot;Authorization: Bearer ALICE_JWT&quot;</span> \\\n  -d <span class=\"hljs-string\">&#x27;{&quot;mind_id&quot;: &quot;m_aaa&quot;, &quot;email&quot;: &quot;bob@example.com&quot;, &quot;role&quot;: &quot;read&quot;}&#x27;</span></code></pre><p>После этого Bob может получить доступ к Mind A через свой JWT\n(только для чтения, если <code>role=read</code>).</p>\n<h2>Границы безопасности</h2>\n<pre><code class=\"hljs language-plaintext\">┌─────────────────────────────────────────────────┐\n│              Synapse Instance                    │\n│  ┌─────────────────────────────────────────┐    │\n│  │         User Account Boundary           │    │\n│  │  ┌──────────────┐  ┌──────────────┐    │    │\n│  │  │  Mind Bound. │  │  Mind Bound. │    │    │\n│  │  │  (Mind Key)  │  │  (Mind Key)  │    │    │\n│  │  │              │  │              │    │    │\n│  │  │  Memories    │  │  Memories    │    │    │\n│  │  │  Tasks       │  │  Tasks       │    │    │\n│  │  │  Chat        │  │  Chat        │    │    │\n│  │  │  Scripts     │  │  Scripts     │    │    │\n│  │  └──────────────┘  └──────────────┘    │    │\n│  └─────────────────────────────────────────┘    │\n└─────────────────────────────────────────────────┘</code></pre><h2>Типовые паттерны multi-tenancy</h2>\n<h3>Паттерн 1: один пользователь, один mind</h3>\n<p>Наиболее распространён у индивидуальных пользователей LLM-агентов.</p>\n<ul>\n<li>1 аккаунт пользователя</li>\n<li>1 mind</li>\n<li>1 Mind Key</li>\n<li>Все воспоминания в одной области</li>\n</ul>\n<h3>Паттерн 2: один пользователь, несколько mind</h3>\n<p>Для пользователей с несколькими контекстами (работа, личное, проекты).</p>\n<ul>\n<li>1 аккаунт пользователя</li>\n<li>N mind (например, «work», «personal», «project-x»)</li>\n<li>N Mind Key</li>\n<li>Каждая LLM-сессия использует один Mind Key</li>\n</ul>\n<h3>Паттерн 3: командный общий mind</h3>\n<p>Для команд, сотрудничающих над проектом.</p>\n<ul>\n<li>1 пользователь создаёт mind (получает Mind Key)</li>\n<li>Создатель делится с участниками команды через JWT</li>\n<li>Все участники получают доступ через JWT (или общий Mind Key)</li>\n</ul>\n<div class=\"callout callout-warn\">Передача Mind Key даёт полный доступ на чтение/запись. Для командной работы\nпредпочтительнее Sharing API (на основе JWT), а не прямой обмен Mind Key.</div><h3>Паттерн 4: SaaS-провайдер</h3>\n<p>Для приложений, встраивающих Synapse как слой памяти.</p>\n<ul>\n<li>Каждый клиент = 1 аккаунт пользователя</li>\n<li>Каждый проект клиента = 1 mind</li>\n<li>Приложение хранит Mind Key по каждому клиенту/проекту</li>\n<li>Полная изоляция между клиентами</li>\n</ul>\n<h2>Проверка изоляции</h2>\n<h3>Тест: Mind Key не может получить доступ к другим mind</h3>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># Mind A&#x27;s key cannot read Mind B&#x27;s memories</span>\ncurl -H <span class=\"hljs-string\">&quot;Authorization: Bearer mk_aaa...&quot;</span> \\\n     <span class=\"hljs-string\">&quot;https://synapse.schaefer.zone/memory/search?q=test&quot;</span>\n<span class=\"hljs-comment\"># Returns only Mind A&#x27;s memories</span>\n\ncurl -H <span class=\"hljs-string\">&quot;Authorization: Bearer mk_bbb...&quot;</span> \\\n     <span class=\"hljs-string\">&quot;https://synapse.schaefer.zone/memory/search?q=test&quot;</span>\n<span class=\"hljs-comment\"># Returns only Mind B&#x27;s memories (different results)</span></code></pre><h3>Тест: JWT не может читать данные памяти напрямую</h3>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># JWT can list minds</span>\ncurl -H <span class=\"hljs-string\">&quot;Authorization: Bearer YOUR_JWT&quot;</span> \\\n     https://synapse.schaefer.zone/minds\n<span class=\"hljs-comment\"># Returns: list of minds</span>\n\n<span class=\"hljs-comment\"># JWT CANNOT read memories (need Mind Key)</span>\ncurl -H <span class=\"hljs-string\">&quot;Authorization: Bearer YOUR_JWT&quot;</span> \\\n     https://synapse.schaefer.zone/memory/recall\n<span class=\"hljs-comment\"># Returns: 401 Unauthorized</span></code></pre><h2>Лучшие практики</h2>\n<div class=\"callout callout-ok\"></div><h2>Следующие шаги</h2>\n<ul>\n<li><a href=\"/docs/getting-started/authentication\">Аутентификация</a></li>\n<li><a href=\"/docs/getting-started/mind-key-vs-jwt\">Mind Key против JWT</a></li>\n<li><a href=\"/docs/concepts/architecture\">Архитектура</a></li>\n</ul>\n","urls":{"html":"/docs/concepts/multi-tenancy","text":"/docs/concepts/multi-tenancy?format=text","json":"/docs/concepts/multi-tenancy?format=json","llm":"/docs/concepts/multi-tenancy?format=llm"},"translations_available":["en","zh","hi","es","fr","ar","pt","ru","ja","de","it","ko","nl","pl","tr","sv","vi","th","id","uk"]}