@@ -70,12 +70,30 @@ async function ensureKernel(): Promise<ObjectKernel> {
7070 await kernel . use ( new AppPlugin ( studioConfig ) ) ;
7171
7272 // Auth plugin — uses better-auth for real authentication
73- const vercelUrl = process . env . VERCEL_URL
74- ? `https://${ process . env . VERCEL_URL } `
75- : 'http://localhost:3000' ;
73+ // Prefer VERCEL_PROJECT_PRODUCTION_URL (stable across deployments)
74+ // over VERCEL_URL (unique per deployment, causes origin mismatch).
75+ const vercelUrl = process . env . VERCEL_PROJECT_PRODUCTION_URL
76+ ? `https://${ process . env . VERCEL_PROJECT_PRODUCTION_URL } `
77+ : process . env . VERCEL_URL
78+ ? `https://${ process . env . VERCEL_URL } `
79+ : 'http://localhost:3000' ;
80+
81+ // Collect all Vercel URL variants so better-auth trusts each one
82+ const trustedOrigins : string [ ] = [ ] ;
83+ if ( process . env . VERCEL_URL ) {
84+ trustedOrigins . push ( `https://${ process . env . VERCEL_URL } ` ) ;
85+ }
86+ if ( process . env . VERCEL_BRANCH_URL ) {
87+ trustedOrigins . push ( `https://${ process . env . VERCEL_BRANCH_URL } ` ) ;
88+ }
89+ if ( process . env . VERCEL_PROJECT_PRODUCTION_URL ) {
90+ trustedOrigins . push ( `https://${ process . env . VERCEL_PROJECT_PRODUCTION_URL } ` ) ;
91+ }
92+
7693 await kernel . use ( new AuthPlugin ( {
7794 secret : process . env . AUTH_SECRET || 'dev-secret-please-change-in-production-min-32-chars' ,
7895 baseUrl : vercelUrl ,
96+ ...( trustedOrigins . length > 0 ? { trustedOrigins } : { } ) ,
7997 } ) ) ;
8098
8199 // Broker shim — bridges HttpDispatcher → ObjectQL engine
0 commit comments