Production Deploy
Setup production keys
Set provider secrets
Deploy
Checklist
SITE_URLis set to your production domain (notlocalhost)JWT_PRIVATE_KEY,JWKS, andAUTH_SECRET_ENCRYPTION_KEYare set (the CLI handles this)- Provider secrets (
AUTH_*_ID,AUTH_*_SECRET) are configured CONVEX_SITE_URLis auto-provided by Convexconvex/auth.config.tstrustsprocess.env.CONVEX_SITE_URLwithapplicationID: "convex"- OAuth callback URLs are registered with your providers pointing to
CONVEX_SITE_URL
Cross-platform .well-known files
Apps using passkeys, password managers, or native iOS/Android sign-in should serve these from the frontend host. See the .well-known reference and the native apps guide.
- For native iOS passkeys:
IOS_APP_IDSset,apple-app-site-associationreachable at the RP ID host with no redirects, no.jsonextension - For native Android passkeys:
ANDROID_APP_LINKSset,assetlinks.jsonreachable at the RP ID host - For password manager UX:
CHANGE_PASSWORD_URLset (302 from/.well-known/change-password) - For multi-origin passkeys:
WEBAUTHN_ALT_ORIGINSset (orSECONDARY_URL) - For security disclosure:
SECURITY_CONTACTset with unexpiredExpires:(refreshes everySECURITY_TXT_EXPIRES_DAYS, default 365)
Auth refresh and Convex logs
Convex Auth refreshes stored browser sessions when the Convex client asks for a
fresh access token. In logs this can show up as an auth:signIn action followed
by an auth:store mutation. That pair is expected on page load, token refresh,
and across multiple tabs or visitors.
Each refresh mutation can cause active Convex subscriptions to re-evaluate. If your logs show a burst of many cached query evaluations after auth refresh, first look for duplicate or unnecessary subscriptions in the app:
- avoid subscribing to the same query in both a page and child component;
- pass already-loaded data as props when possible;
- use
"skip"for queries that are disabled by config or route state; - only run auth-dependent queries on pages that actually need them.
Treat refresh as suspicious when a single tab with one auth client refreshes in a tight loop. Common causes are duplicate auth clients, unavailable storage, corrupted refresh-token storage, or proxy retry failures.