Security

Authentication

How Clerk sessions flow into Convex identity, and how public and protected routes are separated.

Sign-in providers

The app uses Clerk for authentication with Google and GitHub as social sign-in providers. Clerk handles OAuth flows, session management, and issues JWTs that Convex can verify.

Clerk

Manages Google and GitHub OAuth, issues signed JWTs, and provides the sign-in UI components.

Convex integration

Convex verifies Clerk JWTs using the configured JWT issuer domain. The verified identity becomes the server-side owner token.

JWT template required

In your Clerk dashboard, create a JWT template named convex. Set the audience to your Convex deployment URL. The CLERK_JWT_ISSUER_DOMAIN env var must point to this template’s issuer so Convex can verify tokens.

Route boundaries

Public

Landing page, sign-in, sign-up, and documentation are reachable without a session.

Protected

The dashboard and all document data require a valid Clerk session. Unauthenticated requests are redirected to sign-in.

Rendering diagram…
The auth boundary. Clerk issues a JWT; Convex verifies it and derives the owner token used to scope every data read.

Convex identity

When a signed-in user calls a Convex function, the Clerk JWT is verified by Convex against the configured issuer domain. Convex derives a tokenIdentifier from the verified claims and passes it as the server-side identity. Every Convex query and mutation that touches document data filters on ownerTokenIdentifier — so users can only read and write their own documents.

The backend is the source of truth

Client-side redirects improve the experience but are not the security layer. The Convex backend re-checks the authenticated identity on every request. Even if a client-side redirect is bypassed, the backend rejects unauthorized data access.

SSO callback

The /sso-callback route handles the OAuth redirect from Clerk after a social sign-in. Once Clerk completes the handshake, the user is forwarded to the dashboard. No additional configuration is needed beyond the Clerk callback URL matching your site URL.