Skip to main content

Multi-Tenancy & Isolation

How Synapse isolates data between users and minds — security boundaries explained.


Multi-Tenancy & Isolation

Synapse is multi-tenant: multiple users, each with multiple minds, fully isolated from each other. This page explains the isolation model.

Tenant Hierarchy

Synapse Instance
  │
  ├── User Account 1 (email: alice@example.com)
  │   ├── Mind A (Mind Key mk_aaa...)
  │   │   ├── Memories (only accessible via mk_aaa...)
  │   │   ├── Tasks
  │   │   └── Chat
  │   └── Mind B (Mind Key mk_bbb...)
  │       └── ... (isolated from Mind A)
  │
  ├── User Account 2 (email: bob@example.com)
  │   └── Mind C (Mind Key mk_ccc...)
  │       └── ... (isolated from Alice's minds)
  │
  └── ... (more users)

Isolation Levels

Level 1: User Isolation

Each user account is isolated. Alice cannot:

  • See Bob's minds
  • Access Bob's memories (even with her JWT)
  • List Bob's account info

Enforced by: user_id column on all tables, JWT contains user_id, all queries filter by user_id.

Level 2: Mind Isolation

Within a user, each mind is isolated. Mind A cannot:

  • See Mind B's memories
  • Access Mind B's tasks, chat, scripts

Enforced by: mind_id column on all data tables, Mind Key contains mind_id, all queries filter by mind_id.

Mind Key isolation is the primary security boundary. A leaked Mind Key grants full access to that mind's data — but ONLY that mind.

Authentication Tokens

Token Scope What it can access
Mind Key Single mind That mind's data only
JWT User account Account management (create/list/delete minds)
Computer Token Single computer That computer's commands

Cross-Mind Access

Within same user

User can access all their minds via JWT (e.g. GET /minds lists all). But to read/write memory data, they need the specific Mind Key.

Across users

Users cannot access each other's data — UNLESS they explicitly share a mind via the Sharing API:

# Alice shares Mind A with Bob
curl -X POST https://synapse.schaefer.zone/sharing \
  -H "Authorization: Bearer ALICE_JWT" \
  -d '{"mind_id": "m_aaa", "email": "bob@example.com", "role": "read"}'

After sharing, Bob can access Mind A via his JWT (read-only if role=read).

Security Boundaries

┌─────────────────────────────────────────────────┐
│              Synapse Instance                    │
│  ┌─────────────────────────────────────────┐    │
│  │         User Account Boundary           │    │
│  │  ┌──────────────┐  ┌──────────────┐    │    │
│  │  │  Mind Bound. │  │  Mind Bound. │    │    │
│  │  │  (Mind Key)  │  │  (Mind Key)  │    │    │
│  │  │              │  │              │    │    │
│  │  │  Memories    │  │  Memories    │    │    │
│  │  │  Tasks       │  │  Tasks       │    │    │
│  │  │  Chat        │  │  Chat        │    │    │
│  │  │  Scripts     │  │  Scripts     │    │    │
│  │  └──────────────┘  └──────────────┘    │    │
│  └─────────────────────────────────────────┘    │
└─────────────────────────────────────────────────┘

Common Multi-Tenancy Patterns

Pattern 1: Single User, Single Mind

Most common for individual LLM agent users.

  • 1 user account
  • 1 mind
  • 1 Mind Key
  • All memories in one scope

Pattern 2: Single User, Multiple Minds

For users with multiple contexts (work, personal, projects).

  • 1 user account
  • N minds (e.g. "work", "personal", "project-x")
  • N Mind Keys
  • Each LLM session uses one Mind Key

Pattern 3: Team Shared Mind

For teams collaborating on a project.

  • 1 user creates the mind (gets Mind Key)
  • Creator shares with team members via JWT
  • All team members access via JWT (or shared Mind Key)
Sharing a Mind Key gives full read/write access. For team collaboration, prefer the Sharing API (JWT-based) over sharing Mind Keys directly.

Pattern 4: SaaS Provider

For apps that embed Synapse as their memory layer.

  • Each customer = 1 user account
  • Each customer project = 1 mind
  • App stores Mind Keys per customer/project
  • Full isolation between customers

Isolation Verification

Test: Mind Key cannot access other minds

# Mind A's key cannot read Mind B's memories
curl -H "Authorization: Bearer mk_aaa..." \
     "https://synapse.schaefer.zone/memory/search?q=test"
# Returns only Mind A's memories

curl -H "Authorization: Bearer mk_bbb..." \
     "https://synapse.schaefer.zone/memory/search?q=test"
# Returns only Mind B's memories (different results)

Test: JWT cannot read memory data directly

# JWT can list minds
curl -H "Authorization: Bearer YOUR_JWT" \
     https://synapse.schaefer.zone/minds
# Returns: list of minds

# JWT CANNOT read memories (need Mind Key)
curl -H "Authorization: Bearer YOUR_JWT" \
     https://synapse.schaefer.zone/memory/recall
# Returns: 401 Unauthorized

Best Practices

Next Steps