Auth
Supabase Auth with GitHub OAuth (PKCE flow), cookie-based sessions.
Flow
- User clicks “Sign in with GitHub” →
/login - Supabase redirects to GitHub, back to
/auth/callback?code=... - Callback exchanges code for session server-side (
exchangeCodeForSession) - Session stored in cookies, available on both server and client
Files
src/hooks.server.ts— creates server Supabase client with cookie access, exposessafeGetSession()src/routes/+layout.server.ts— loads session viasafeGetSession()src/routes/+layout.ts— creates browser Supabase client (@supabase/ssr)src/routes/+layout.svelte—onAuthStateChangeinvalidates server loadsrc/routes/login/+page.svelte— GitHub + magic link sign-in, parses OAuth errors from hash fragmentsrc/routes/auth/callback/+server.ts— PKCE code exchange, error forwardingsrc/lib/supabase.ts— browser client factory
DB trigger
On auth.users INSERT, handle_new_user() creates an agent record in public.records matching the user’s ID.
Important: All trigger/helper functions must use public.-qualified table names and set search_path = public. The supabase_auth_admin role has search_path=auth, so unqualified references fail silently.
API key auth
For API-key-authenticated requests (CLI, agents), hooks.server.ts resolves the key via the resolve_api_key RPC, then mints a short-lived JWT using mintAgentJwt from @arbe/core/mint-jwt. This JWT is passed to the Supabase client so PostgREST runs queries as the agent identity with RLS enforced.
SUPABASE_JWT_SECRET must be the raw HS256 signing secret from Supabase dashboard → Settings → API → JWT Secret. It is a short random string — not a JWT and not the service role key. Setting it to the wrong value causes PostgREST to reject all minted tokens with “No suitable key or wrong key type”.
Set it in packages/www/.env.local for local dev and as a wrangler secret for production:
bunx wrangler secret put SUPABASE_JWT_SECRET --config packages/www/wrangler.jsoncMigrations
20260209191703_auth_agent_trigger.sql— trigger + function