Auth cookie current state
A current-state snapshot of cookie, domain, and auth relationships in today-platform-web. No target design, no migration plan.
Verified at commit a553ab705d8b7735d97e908e3a67dc17fe1842e1.
This note documents the current cookie, domain, and auth relationship in today-platform-web only. It is intentionally current-state only: no target-state design, no migration plan, and no new domains.
Current domain relationship in this repo
today.ai: main web app (apps/web)admin.today.ai: admin app (apps/admin)auth.today.ai: auth service origin resolved byresolveAuthBaseUrl()api.today.ai: API origin resolved byresolveApiBaseUrl()
The same shape is used in dev docs with todayai.dev equivalents. The web repo treats auth and API as separate origins, then adds app-origin proxy routes where needed.
Main web app: session cookie is still foundational
The main web app uses Better Auth against the app origin, not directly against auth.today.ai from the browser:
apps/web/src/lib/better-auth-client.ts:createAuthClient({ baseURL: betterAuthConfig.baseURL, fetchOptions: { credentials: 'include' } })apps/web/src/lib/session-auth-client.ts: lightweight session client also points atbetterAuthConfig.baseURLapps/web/src/data/user/session-query.ts: session reads callauthClient.getSession()
That app-origin auth traffic is proxied server-side to the auth service:
apps/web/src/app/api/auth/[...all]/route.ts: proxies/api/auth/*to${AUTH_BASE_URL}/api/auth/*apps/web/src/app/api/auth/[...all]/utils.ts: forwards incomingcookie,authorization,content-type,accept,user-agent,accept-language, andorigin
/api/token also depends on the browser cookie being available on the app origin:
apps/web/src/hooks/use-session.ts: callsfetch('/api/token', { credentials: 'include' })apps/web/src/app/api/token/route.ts: readsrequest.headers.get('cookie')andrequest.headers.get('authorization'), then forwards them to${AUTH_BASE_URL}/api/token
In other words, the current apps/web flow assumes:
- The browser has a valid session cookie.
- That cookie is sent on requests to
today.ai. - The web app forwards that cookie to
auth.today.aithrough/api/auth/*and/api/token.
Why shared parent-domain cookie is assumed today
The current docs in this repo explicitly describe the shared-cookie assumption:
- Auth interaction architecture: the social login callback lands on the auth origin, and even with a BFF proxy the session must remain visible after redirecting back to the app
- Local development: documents the concrete dev flow where Google redirects to
auth.todayai.dev, the auth server sets a cookie on.todayai.dev, and the browser later sends that cookie on app requests - Environment variables: repeats the same constraint and calls out cookie-domain alignment as required for login to keep working
This means the current web login flow is not purely "same-origin BFF only". The browser still visits the auth origin during social/OIDC redirects, and the repo documentation assumes the resulting session remains usable when the browser returns to the app origin.
Admin app: OIDC bearer flow first, cookie forwarding still exists
The admin app mixes OIDC bearer tokens with the same app-origin proxy pattern:
apps/admin/src/lib/oidc-config.tsauthorityisresolveAuthBaseUrl()authorization_endpointpoints directly to${authority}/api/auth/oauth2/authorizetoken_endpointis proxied through${appOrigin}/api/auth/tokenuserinfo_endpointis proxied through${appOrigin}/api/auth/oauth2/userinfo
apps/admin/src/data/user/session-query.ts: fetches/api/auth/oauth2/userinfowithAuthorization: Bearer <access_token>
Admin proxy routes still forward cookies when present:
apps/admin/src/app/api/auth/[...all]/route.ts: proxies/api/auth/*to the auth serviceapps/admin/src/app/api/auth/[...all]/utils.ts: forwards incomingcookieandauthorizationapps/admin/src/app/api/token/route.ts: forwards incomingcookieandauthorizationto${AUTH_BASE_URL}/api/tokenapps/admin/src/hooks/use-session.ts: callsfetch('/api/token', { credentials: 'include', headers: { Authorization: ... } })
So the current admin picture is:
- interactive login starts with OIDC redirects against the auth origin
- user/session reads are bearer-token based
- app-origin proxy routes still preserve cookie forwarding behavior instead of assuming a cookie-free model
Current-state conclusion
In the current web repo, /api/auth/* and /api/token are implemented as thin app-origin proxies to the auth service, and both preserve browser cookies when available. The main web app still depends directly on that session cookie path. The admin app is more bearer-token-oriented, but it has not removed cookie forwarding from the same proxy surface.
Auth interaction architecture
The headless auth server pattern — OAuth2 / OIDC server delegates login, consent, and account selection to a web app via HTTP redirects.
Better-Auth quirks
The `oauthProviderClient` plugin auto-injects `oauth_query` into non-GET request bodies. What that means in practice and the workaround for calls that shouldn't progress the OAuth flow.