{"title":"Multi-Tenancy & Isolation","slug":"multi-tenancy","category":"concepts","summary":"How Synapse isolates data between users and minds — security boundaries explained.","audience":["human","llm"],"tags":["concept","multi-tenancy","security","isolation"],"difficulty":"intermediate","updated":"2026-06-27","word_count":519,"read_minutes":3,"lang":"en","translated":true,"requested_lang":"en","content_markdown":"\n# Multi-Tenancy & Isolation\n\nSynapse is multi-tenant: multiple users, each with multiple minds, fully\nisolated from each other. This page explains the isolation model.\n\n## Tenant Hierarchy\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## Isolation Levels\n\n### Level 1: User Isolation\n\nEach user account is isolated. Alice cannot:\n\n- See Bob's minds\n- Access Bob's memories (even with her JWT)\n- List Bob's account info\n\nEnforced by: `user_id` column on all tables, JWT contains `user_id`, all\nqueries filter by `user_id`.\n\n### Level 2: Mind Isolation\n\nWithin a user, each mind is isolated. Mind A cannot:\n\n- See Mind B's memories\n- Access Mind B's tasks, chat, scripts\n\nEnforced by: `mind_id` column on all data tables, Mind Key contains `mind_id`,\nall queries filter by `mind_id`.\n\n> [!CRITICAL]\n> Mind Key isolation is the primary security boundary. A leaked Mind Key\n> grants full access to that mind's data — but ONLY that mind.\n\n## Authentication Tokens\n\n| Token | Scope | What it can access |\n|-------|-------|-------------------|\n| Mind Key | Single mind | That mind's data only |\n| JWT | User account | Account management (create/list/delete minds) |\n| Computer Token | Single computer | That computer's commands |\n\n## Cross-Mind Access\n\n### Within same user\n\nUser can access all their minds via JWT (e.g. `GET /minds` lists all).\nBut to read/write memory data, they need the specific Mind Key.\n\n### Across users\n\nUsers cannot access each other's data — UNLESS they explicitly share a mind\nvia the 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\nAfter sharing, Bob can access Mind A via his JWT (read-only if `role=read`).\n\n## Security Boundaries\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## Common Multi-Tenancy Patterns\n\n### Pattern 1: Single User, Single Mind\n\nMost common for individual LLM agent users.\n\n- 1 user account\n- 1 mind\n- 1 Mind Key\n- All memories in one scope\n\n### Pattern 2: Single User, Multiple Minds\n\nFor users with multiple contexts (work, personal, projects).\n\n- 1 user account\n- N minds (e.g. \"work\", \"personal\", \"project-x\")\n- N Mind Keys\n- Each LLM session uses one Mind Key\n\n### Pattern 3: Team Shared Mind\n\nFor teams collaborating on a project.\n\n- 1 user creates the mind (gets Mind Key)\n- Creator shares with team members via JWT\n- All team members access via JWT (or shared Mind Key)\n\n> [!WARNING]\n> Sharing a Mind Key gives full read/write access. For team collaboration,\n> prefer the Sharing API (JWT-based) over sharing Mind Keys directly.\n\n### Pattern 4: SaaS Provider\n\nFor apps that embed Synapse as their memory layer.\n\n- Each customer = 1 user account\n- Each customer project = 1 mind\n- App stores Mind Keys per customer/project\n- Full isolation between customers\n\n## Isolation Verification\n\n### Test: Mind Key cannot access other minds\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### Test: JWT cannot read memory data directly\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## Best Practices\n\n> [!TIP]\n> - **Use one mind per project/context** — isolation is your friend\n> - **Never share Mind Keys** — use the Sharing API instead\n> - **Rotate Mind Keys** if compromised (delete mind, create new)\n> - **Audit shared minds** — review `GET /sharing` periodically\n> - **Use JWT for human UI** — never expose Mind Keys to end users\n\n## Next Steps\n\n- [Authentication](/docs/getting-started/authentication)\n- [Mind Key vs JWT](/docs/getting-started/mind-key-vs-jwt)\n- [Architecture](/docs/concepts/architecture)\n","content_html":"<h1>Multi-Tenancy &amp; Isolation</h1>\n<p>Synapse is multi-tenant: multiple users, each with multiple minds, fully\nisolated from each other. This page explains the isolation model.</p>\n<h2>Tenant Hierarchy</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>Isolation Levels</h2>\n<h3>Level 1: User Isolation</h3>\n<p>Each user account is isolated. Alice cannot:</p>\n<ul>\n<li>See Bob&#39;s minds</li>\n<li>Access Bob&#39;s memories (even with her JWT)</li>\n<li>List Bob&#39;s account info</li>\n</ul>\n<p>Enforced by: <code>user_id</code> column on all tables, JWT contains <code>user_id</code>, all\nqueries filter by <code>user_id</code>.</p>\n<h3>Level 2: Mind Isolation</h3>\n<p>Within a user, each mind is isolated. Mind A cannot:</p>\n<ul>\n<li>See Mind B&#39;s memories</li>\n<li>Access Mind B&#39;s tasks, chat, scripts</li>\n</ul>\n<p>Enforced by: <code>mind_id</code> column on all data tables, Mind Key contains <code>mind_id</code>,\nall queries filter by <code>mind_id</code>.</p>\n<div class=\"callout callout-critical\">Mind Key isolation is the primary security boundary. A leaked Mind Key\ngrants full access to that mind's data — but ONLY that mind.</div><h2>Authentication Tokens</h2>\n<table>\n<thead>\n<tr>\n<th>Token</th>\n<th>Scope</th>\n<th>What it can access</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Mind Key</td>\n<td>Single mind</td>\n<td>That mind&#39;s data only</td>\n</tr>\n<tr>\n<td>JWT</td>\n<td>User account</td>\n<td>Account management (create/list/delete minds)</td>\n</tr>\n<tr>\n<td>Computer Token</td>\n<td>Single computer</td>\n<td>That computer&#39;s commands</td>\n</tr>\n</tbody></table>\n<h2>Cross-Mind Access</h2>\n<h3>Within same user</h3>\n<p>User can access all their minds via JWT (e.g. <code>GET /minds</code> lists all).\nBut to read/write memory data, they need the specific Mind Key.</p>\n<h3>Across users</h3>\n<p>Users cannot access each other&#39;s data — UNLESS they explicitly share a mind\nvia the 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>After sharing, Bob can access Mind A via his JWT (read-only if <code>role=read</code>).</p>\n<h2>Security Boundaries</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>Common Multi-Tenancy Patterns</h2>\n<h3>Pattern 1: Single User, Single Mind</h3>\n<p>Most common for individual LLM agent users.</p>\n<ul>\n<li>1 user account</li>\n<li>1 mind</li>\n<li>1 Mind Key</li>\n<li>All memories in one scope</li>\n</ul>\n<h3>Pattern 2: Single User, Multiple Minds</h3>\n<p>For users with multiple contexts (work, personal, projects).</p>\n<ul>\n<li>1 user account</li>\n<li>N minds (e.g. &quot;work&quot;, &quot;personal&quot;, &quot;project-x&quot;)</li>\n<li>N Mind Keys</li>\n<li>Each LLM session uses one Mind Key</li>\n</ul>\n<h3>Pattern 3: Team Shared Mind</h3>\n<p>For teams collaborating on a project.</p>\n<ul>\n<li>1 user creates the mind (gets Mind Key)</li>\n<li>Creator shares with team members via JWT</li>\n<li>All team members access via JWT (or shared Mind Key)</li>\n</ul>\n<div class=\"callout callout-warn\">Sharing a Mind Key gives full read/write access. For team collaboration,\nprefer the Sharing API (JWT-based) over sharing Mind Keys directly.</div><h3>Pattern 4: SaaS Provider</h3>\n<p>For apps that embed Synapse as their memory layer.</p>\n<ul>\n<li>Each customer = 1 user account</li>\n<li>Each customer project = 1 mind</li>\n<li>App stores Mind Keys per customer/project</li>\n<li>Full isolation between customers</li>\n</ul>\n<h2>Isolation Verification</h2>\n<h3>Test: Mind Key cannot access other minds</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>Test: JWT cannot read memory data directly</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>Best Practices</h2>\n<div class=\"callout callout-ok\"></div><h2>Next Steps</h2>\n<ul>\n<li><a href=\"/docs/getting-started/authentication\">Authentication</a></li>\n<li><a href=\"/docs/getting-started/mind-key-vs-jwt\">Mind Key vs JWT</a></li>\n<li><a href=\"/docs/concepts/architecture\">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"]}