Skip to main content
Convex functions run in Convex’s own runtime against Convex’s own database. theAuth needs a SQL database, so theAuth does not run inside Convex. The two sit side by side instead: theAuth stays on your server and Convex trusts the tokens it issues. This is the same shape as using Clerk or Auth0 with Convex. Convex supports custom JWT providers: it fetches a JWKS from a URL you give it and checks the signature, issuer, audience and expiry of every token the client sends. There is no Convex package for theAuth. You add one token route to your theAuth server.
This page covers Convex verifying theAuth sessions. It does not run the theAuth routes (sign in, agents, audit) inside Convex HTTP actions, because those need a SQL database that Convex does not offer.

Install

Serve a JWKS and a token route

Any server that already runs createTheAuthHandler works. This example uses node:http so it stands alone. The signing key is generated at startup for the example. In production load a persistent private key, or tokens stop verifying on every restart.
server.ts
yourAuthAdapter is whatever resolves your signed-in user from a request, for example a Better Auth session lookup or your own cookie check. The token route refuses callers it cannot resolve, so only signed-in users get a Convex token. Keep the lifetime short: Convex does not call back to theAuth, so a token stays valid until it expires even if the user signs out.

Tell Convex to trust it

convex/auth.config.ts
issuer and applicationID must match the iss and aud of the tokens exactly. Convex fetches the JWKS from the deployment, so the URL must be reachable from Convex, not only from your machine.

Read the user in a function

convex/me.ts
identity.subject is the theAuth user id. On the client, give Convex a token fetcher that calls your token route. With the React client:
The token route issues a fresh token on every call, so forceRefreshToken needs no special handling.

What was run

Run against the local Convex backend that npx convex dev starts in anonymous agent mode (convex 1.47.0), with @glinr/theauth from a packed tarball and the server above using http://localhost:4545 as the issuer. With no token, whoami returned null. With a token from /api/convex/token for user alice, it returned her subject, email and the issuer. A token with a damaged signature was rejected by Convex with an InvalidAuthHeader error. The token route answered 401 without a session. The ConvexProviderWithAuth snippet was not run, since it needs a browser.
Last modified on October 19, 2026