Skip to main content

Isolation Boundaries

Understanding Cortex's multi-layered isolation model for security, privacy, and compliance.

Overview

Cortex provides four layers of isolation that work together to ensure data security, enable multi-tenancy, and maintain privacy boundaries:

Isolation Hierarchy
1. Tenant Isolation

tenantId • Multi-tenant SaaS separation • Auto-injected via AuthContext

2. Memory Space Isolation

memorySpaceId • Fundamental data boundary • Hive or Collaboration Mode

3. User Isolation

userId • GDPR compliance • Enables cascade deletion

4. Participant Tracking

participantId • Hive Mode attribution • Audit trail

Four layers of data isolation
Key Principle

Each layer serves a distinct purpose and can be used independently or combined.


1. Tenant Isolation (Multi-Tenant SaaS)

Complete data separation for SaaS platforms serving multiple organizations.

const cortex = new Cortex({
convexUrl: process.env.CONVEX_URL!,
auth: createAuthContext({
tenantId: "customer-acme", // All operations scoped to this tenant
userId: "user-123",
}),
});

// All operations automatically include tenantId
await cortex.memory.remember({
memorySpaceId: "user-123-personal",
// tenantId: "customer-acme" ← Auto-injected!
userMessage: "Hello",
agentResponse: "Hi!",
userId: "user-123",
userName: "Alice",
});
Tenant Guarantees
  • Tenant A cannot query Tenant B's data
  • Tenant A cannot access Tenant B's memory spaces
  • GDPR deletion respects tenant boundaries
  • Complete isolation at database level

2. Memory Space Isolation

Core data isolation boundary for organizing memories, conversations, and facts.

FeatureHive ModeCollaboration Mode
SpacesOne shared spaceSeparate spaces per agent
Data AccessAll participants see all dataAgents only see their own
Cross-AccessAutomaticVia A2A or Context Chains
Use CasePersonal AI toolsEnterprise workflows

All AI tools share user's personal space:

const memorySpaceId = "user-123-personal";

// Cursor stores
await cortex.memory.remember({
memorySpaceId,
participantId: "cursor",
userMessage: "I prefer TypeScript",
agentResponse: "Noted!",
userId: "user-123",
userName: "Alice",
});

// Claude reads same space — sees Cursor's memories
const memories = await cortex.memory.search(memorySpaceId, "preferences");

3. User Data Isolation (GDPR)

Right to Be Forgotten

Link data to users via userId to enable cascade deletion across ALL layers with a single API call.

// Link data to user
await cortex.memory.remember({
memorySpaceId: "support-bot-space",
userId: "user-123", // ← GDPR link
userMessage: "My account issue",
agentResponse: "Let me help",
userName: "Alice",
});

// One API call deletes from ALL layers
const result = await cortex.users.delete("user-123", {
cascade: true,
verify: true,
});

Deleted from: Conversations • Memories • Facts • Sessions • User Profile


4. Participant Tracking

Not Isolation — Attribution

participantId tracks which tool stored data. It does NOT isolate data — all participants can still see all memories in the space.

// Track which tool stored what
await cortex.memory.remember({
memorySpaceId: "shared-space",
participantId: "cursor", // Attribution
userMessage: "User message",
agentResponse: "Response",
userId: "user-123",
userName: "Alice",
});

// Filter by participant for debugging
const cursorMemories = await cortex.memory.list({
memorySpaceId: "shared-space",
participantId: "cursor",
});

Isolation Matrix

How each data type is scoped by isolation layer:

Data TypetenantIdmemorySpaceIduserIdparticipantId
ConversationsOptionalOptional
Vector MemoriesOptionalOptional
FactsOptionalOptional
User ProfilesSharedN/AN/A
Immutable StoreSharedOptionalN/A
Mutable StoreSharedOptionalN/A

Best Practices

Always Use tenantId for SaaS
const cortex = new Cortex({
auth: createAuthContext({
tenantId: req.tenant.id, // REQUIRED for multi-tenant
userId: req.user.id,
}),
});
Always Set userId for GDPR
await cortex.memory.remember({
memorySpaceId: "bot-space",
userId: "user-123", // Required for cascade deletion
// ...
});
Use participantId in Hive Mode
await cortex.memory.remember({
memorySpaceId: "shared-space",
participantId: "my-bot", // Track attribution
// ...
});

Next Steps