Authentication
Understanding authentication context in Cortex for user tracking, multi-tenancy, and session management.
Overview
Key Concept
Auth context is just data — not a protocol or SDK. Extract it from your auth system (whatever that is) and pass it to Cortex.
Authentication Flow
Your Auth System
Auth0 • Clerk • JWT • NextAuth • Custom
Extract & Create Context
userId • tenantId • sessionId • metadata
Cortex SDK
Auto-injects auth to ALL operations
Why Authentication Matters
User Tracking
Link all data to users for personalization and context
Multi-Tenancy
Complete data separation for SaaS platforms
GDPR Compliance
Enable cascade deletion across all layers
Session Management
Track user activity across devices
Quick Start
1
Extract Auth Information
From your auth system (JWT, session, OAuth token):
import jwt from "jsonwebtoken";
function extractAuth(token: string) {
const decoded = jwt.verify(token, process.env.JWT_SECRET!) as {
sub: string;
tenant_id?: string;
session_id?: string;
};
return {
userId: decoded.sub,
tenantId: decoded.tenant_id,
sessionId: decoded.session_id,
};
}
2
Create Auth Context
import { createAuthContext } from "@cortexmemory/sdk";
const auth = createAuthContext({
userId: extracted.userId,
tenantId: extracted.tenantId,
sessionId: extracted.sessionId,
});
3
Initialize Cortex
import { Cortex } from "@cortexmemory/sdk";
const cortex = new Cortex({
convexUrl: process.env.CONVEX_URL!,
auth,
});
4
Use Cortex
All operations automatically include auth context:
await cortex.memory.remember({
memorySpaceId: "user-space",
userMessage: "Hello",
agentResponse: "Hi!",
userName: "User",
// userId, tenantId auto-injected
});
Auth Context Fields
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
userId | string | Yes | — | Identifies the authenticated user. Auto-injected to all entities. |
tenantId | string | No | — | Multi-tenant SaaS isolation. Auto-filters ALL queries by tenant. |
sessionId | string | No | — | Track user sessions across devices. |
claims | object | No | — | Raw data from auth provider (email, iss, aud, etc.) |
metadata | object | No | — | Your application data (role, plan, features, etc.) |
Example with All Fields
const auth = createAuthContext({
userId: "user-123", // Required
tenantId: "customer-acme", // Multi-tenant isolation
sessionId: "session-xyz", // Session tracking
claims: {
email: "user@example.com",
iss: "https://auth.myapp.com",
},
metadata: {
role: "admin",
plan: "enterprise",
},
});
Common Patterns
// Middleware extracts auth
app.use((req, res, next) => {
const token = req.headers.authorization?.replace("Bearer ", "");
if (!token) return res.status(401).send("Unauthorized");
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET!);
req.auth = createAuthContext({
userId: decoded.sub,
tenantId: decoded.tenant_id,
sessionId: decoded.session_id,
});
next();
} catch (err) {
res.status(401).send("Invalid token");
}
});
// Route uses auth
app.post("/chat", (req, res) => {
const cortex = new Cortex({ convexUrl, auth: req.auth });
// Use cortex...
});
// Single-user CLI tool — no tenants needed
const auth = createAuthContext({
userId: "local-user",
metadata: { hostname: os.hostname() },
});
const cortex = new Cortex({ convexUrl, auth });
// Service account for automated tasks
const serviceAuth = createAuthContext({
userId: "service-session-cleanup",
metadata: {
type: "service_account",
purpose: "cleanup",
},
});
const cortex = new Cortex({ convexUrl, auth: serviceAuth });
Security Best Practices
Always Extract tenantId from Secure Token
// GOOD: From signed JWT
const decoded = jwt.verify(token, secret);
const auth = createAuthContext({
userId: decoded.sub,
tenantId: decoded.tenant_id, // From secure source
});
// BAD: From client input — user could change this!
const auth = createAuthContext({
userId: decoded.sub,
tenantId: req.body.tenantId, // NEVER do this
});
Validate Auth Context
async function validateAuth(auth: AuthContext) {
const user = await cortex.users.get(auth.userId);
if (!user) throw new Error("User not found");
return true;
}
Rotate Sessions
// Expire old sessions periodically
await cortex.sessions.expireIdle({
idleTimeout: 30 * 60 * 1000, // 30 minutes
});