Security Considerations for Supermemory: Authentication Architecture and Threat Mitigation
Supermemory implements a defense-in-depth security model using Better-Auth plugins for session management, edge middleware for request validation, and centralized token verification for MCP server access, ensuring credentials never leak to the client.
Supermemory is an open-source personal knowledge management system that handles sensitive user data through a multi-layered security architecture. Understanding the security considerations for Supermemory is essential for developers deploying self-hosted instances or integrating with the MCP (Model Context Protocol) server. The platform isolates authentication concerns between the Next.js frontend, API gateway, and MCP server using token-based authentication and fine-grained middleware validation.
Authentication Architecture Overview
Supermemory’s security model spans three distinct layers: the frontend client, server-side middleware, and the MCP server. Each layer implements specific validation mechanisms defined in separate modules to ensure only authorized requests reach protected resources.
Frontend Authentication (packages/lib/auth.ts)
The web interface uses a unified authentication client defined in packages/lib/auth.ts (lines 12–26). This client wraps Better-Auth plugins supporting username-password, magic links, email OTP, API keys, admin roles, organization multi-tenancy, and anonymous sessions.
The client always sends credentials using credentials: "include" to enable cookie-based session handling. The base URL for authentication requests defaults to the production API but can be overridden via the NEXT_PUBLIC_BACKEND_URL environment variable:
// packages/lib/auth.ts
import { createAuthClient } from "better-auth/client"
export const authClient = createAuthClient({
baseURL: process.env.NEXT_PUBLIC_BACKEND_URL || "https://api.supermemory.ai",
fetchOptions: {
credentials: "include",
},
})
Server-Side Auth Middleware (packages/lib/auth.middleware.ts)
For server-only routes such as the MCP server, the codebase uses packages/lib/auth.middleware.ts (lines 12–26). This exports the same Better-Auth plugin suite but runs without the credentials: "include" flag because it executes in a server context where cookie handling differs from browser environments.
Edge Middleware Protection (apps/web/middleware.ts)
The Next.js application employs edge middleware in apps/web/middleware.ts (lines 11–42) to intercept every request before it reaches protected resources. The middleware checks for valid session cookies using getSessionCookie and implements differentiated access control:
- Public routes (
/login,/login/new) bypass authentication checks - API routes return a 401 JSON response for missing or invalid sessions
- Protected pages trigger a redirect to the login page when no valid cookie exists
This ensures that no server-side code executes without an authenticated session, creating a hard boundary at the network edge.
MCP Server Token Validation (apps/mcp/src/auth.ts)
The Model-Context-Protocol (MCP) server handles external clients such as browser extensions and CLI tools through a separate authentication flow defined in apps/mcp/src/auth.ts (lines 14–62 and 92–160). It accepts two credential types:
- API keys: Must start with the
sm_prefix and are validated against the main API's/v3/sessionendpoint via thevalidateApiKeyfunction (lines 30–60) - OAuth tokens: Validated via the
/v3/mcp/session-with-keyendpoint using thevalidateOAuthTokenfunction (lines 108–130)
Both flows return a normalized AuthUser object containing the user ID, API key, email, and display name. The validation functions implement extensive error handling that returns null on failure while logging only HTTP status codes—never the token values themselves.
// apps/mcp/src/auth.ts
export async function validateApiKey(
apiKey: string,
baseUrl: string
): Promise<AuthUser | null> {
if (!apiKey.startsWith("sm_")) return null
const response = await fetch(`${baseUrl}/v3/session`, {
headers: { Authorization: `Bearer ${apiKey}` }
})
if (!response.ok) {
console.error(`API key validation failed: ${response.status}`)
return null
}
return response.json()
}
Threat Model and Mitigations
Supermemory addresses specific attack vectors through architectural safeguards and strict validation protocols.
Replay Attack Prevention
Session cookies are scoped strictly to the supermemory.ai domain and transmitted exclusively over HTTPS connections enforced by Cloudflare Workers. The combination of domain scoping and transport layer security prevents credential theft via man-in-the-middle attacks and ensures intercepted requests cannot be replayed from unauthorized domains.
Credential Leakage Protection
The platform implements a "secrets never touch the client" policy. API keys and OAuth tokens remain server-side only, with validation occurring through central API endpoints. Error logging explicitly avoids capturing token values—only HTTP status codes and generic failure reasons are recorded. This prevents accidental exposure of credentials in log aggregation systems or debugging outputs.
Cross-Site Request Forgery (CSRF) Defense
The Better-Auth library configures cookies with appropriate SameSite attributes to prevent cross-origin transmission. Combined with the frontend's use of credentials: "include" restricted to same-origin requests, the architecture effectively blocks CSRF attacks that attempt to leverage authenticated sessions from malicious third-party sites.
Privilege Escalation Controls
Administrative and organization-level permissions are managed through dedicated Better-Auth plugins that enforce server-side verification. Elevated permissions are never granted based on client-side assertions; instead, the middleware and API endpoints revalidate user roles against the canonical session store on every request.
Implementation Examples
Signing In from a React Component
The frontend auth client provides a unified API for initiating authentication flows:
import { signIn } from "@lib/auth"
function LoginButton() {
const handleLogin = async () => {
await signIn({
provider: "email",
email: "user@example.com",
// OTP or magic-link flow handled by Better-Auth
})
}
return <button onClick={handleLogin}>Log in with Email</button>
}
Validating API Keys in MCP Handlers
When building custom MCP tools, validate credentials using the centralized auth utilities:
import { validateApiKey, isApiKey } from "./auth"
export async function handler(request: Request) {
const authHeader = request.headers.get("Authorization") ?? ""
const token = authHeader.replace(/^Bearer\s+/i, "")
const authUser = token && isApiKey(token)
? await validateApiKey(token, process.env.NEXT_PUBLIC_BACKEND_URL!)
: null
if (!authUser) {
return new Response("Unauthorized", { status: 401 })
}
// Proceed with authenticated request using authUser.userId
return new Response(JSON.stringify({ userId: authUser.userId }))
}
Accessing Session Data in Hooks
Retrieve current user information using the React hook wrapper:
import { useSession } from "@lib/auth"
export function useCurrentUser() {
const { data: session, isLoading } = useSession()
return { user: session?.user, isLoading }
}
Summary
Supermemory's security architecture implements defense-in-depth across multiple layers:
- Token-based authentication using Better-Auth plugins supports multiple identity providers while maintaining session consistency
- Edge middleware validation in
apps/web/middleware.tsrejects unauthorized requests before they reach application code - Centralized credential verification ensures API keys and OAuth tokens are validated against canonical session stores
- Strict logging policies prevent credential leakage by recording only HTTP status codes, never token values
- Environment isolation keeps sensitive secrets server-side, exposing only the public backend URL to client bundles
Frequently Asked Questions
How does Supermemory validate user sessions?
Supermemory validates sessions through Next.js edge middleware defined in apps/web/middleware.ts (lines 11–42). The middleware checks for valid session cookies using getSessionCookie on every request. API routes receive a 401 response for invalid sessions, while browser requests redirect to the login page. This validation occurs before any application logic executes, ensuring a fail-closed security posture.
What authentication methods does the MCP server support?
The MCP server in apps/mcp/src/auth.ts supports two authentication methods: API keys (prefixed with sm_) and OAuth tokens. API keys validate against the /v3/session endpoint, while OAuth tokens use /v3/mcp/session-with-key. Both methods return a normalized AuthUser object containing the user ID, email, and API key, ensuring consistent identity representation across authentication flows.
How does Supermemory prevent credential leakage in logs?
Supermemory implements strict logging policies in the MCP authentication module. The validateApiKey and validateOAuthToken functions return null on validation failures while logging only the HTTP status code (e.g., 401, 403) and generic error categories. Token values, user emails, and specific credential identifiers are explicitly excluded from log output, preventing accidental exposure through log aggregation or debugging tools.
Can the authentication base URL be customized for self-hosted deployments?
Yes. The frontend authentication client in packages/lib/auth.ts reads the NEXT_PUBLIC_BACKEND_URL environment variable to determine the API endpoint. If not specified, it defaults to the production URL. This allows self-hosted instances to redirect authentication requests to custom backends without modifying source code, though all authentication secrets remain server-side and are never exposed through this public variable.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →