# Auth Proxy — Production Ingress Requirement The application uses **same-origin authentication**: the browser and React Router SSR both hit `/api/auth/*` on the public application domain. This keeps cookies first-party, avoids cross-origin credentials, and gives development and production the same API surface. ## Required production route At the public application domain, route: | Prefix | Target | |---|---| | `/api/auth/*` | Convex HTTP site | | `/*` | React Router frontend | ### Caddy ```caddy zopu.example.com { handle /api/auth/* { reverse_proxy https://befitting-dalmatian-161.convex.site { header_up Host befitting-dalmatian-161.convex.site } } handle { reverse_proxy frontend:3000 } } ``` ### Dokploy / Traefik Create a higher-priority path router for `/api/auth` that forwards to the external Convex site URL. Ensure it: - Preserves the original browser `Cookie` header - Passes `Set-Cookie` responses back (rewrite domain if Convex emits an explicit one) - Preserves the original method and body - Forwards `X-Forwarded-Host` and `X-Forwarded-Proto` - Passes the full path unchanged (e.g. `/api/auth/convex/token`) - Does not cache auth responses - Allows OAuth callback routes under the same prefix ## Convex environment The Convex deployment `SITE_URL` must match the public origin users visit, not the Convex site URL: ```bash # Production npx convex env set SITE_URL 'https://zopu.example.com' # Local npx convex env set SITE_URL 'http://100.101.157.28:5173' # Staging npx convex env set SITE_URL 'https://zopu.cheaptricks.puter.wtf' ``` This value populates Better Auth's `trustedOrigins`. The Convex deployment also uses `CONVEX_SITE_URL` as the internal `baseURL` for route registration; that value is the HTTP site URL (e.g. `https://befitting-dalmatian-161.convex.site`). ## Why same-origin 1. **First-party cookies.** No `SameSite=None`, no third-party cookie restrictions. 2. **SSR consistency.** The React Router server uses the same auth surface the browser sees; no cross-host credential translation. 3. **No CORS complexity.** The browser talks only to its own origin. 4. **The reverse proxy handles the cross-host hop server-side.** ## Related - [Better Auth: Trusted Origins](https://github.com/better-auth/better-auth/blob/main/docs/content/docs/reference/security.mdx) - `apps/web/vite.config.ts` — Vite dev proxy (`/api/auth` → Convex site) - `packages/auth/src/web/auth-client.ts` — `window.location.origin` - `apps/web/src/lib/auth.server.ts` — SSR token loader via request origin