Skip to content

Sign in locally without the IdP under DEV_AUTH=true - #18

Open
kamath wants to merge 2 commits into
mainfrom
thimphu
Open

Sign in locally without the IdP under DEV_AUTH=true#18
kamath wants to merge 2 commits into
mainfrom
thimphu

Conversation

@kamath

@kamath kamath commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Exercising anything behind a session — the rail chip, /api/me, AUTH_REQUIRED, the identity a run executes as — used to mean registering an OIDC client on Arcade's IdP and doing the redirect dance; DEV_AUTH=true now hands /api/auth/* to src/dev-auth.ts, which answers in Better Auth's own shapes, so authClient and everything that reads a session need no dev branch. Signed in is the default, signing out is a cookie and signing back in clears it, so there is no session store — nothing to migrate, no rows in the auth tables, no BETTER_AUTH_URL to get right. It runs as DEV_AUTH_USER (defaulting to ARCADE_USER_ID, so it does not quietly move which Arcade account tools execute as), wins over oidc because a machine with credentials in .env is exactly the one that wants to skip the dance, and refuses when NODE_ENV=production — nothing here authenticates anybody, so that check is the whole security model. /api/me returns mode: "oidc" | "dev" | "off" in place of configured: boolean, one field for the one question the login page and every route actually ask now that "login works" and "OIDC is configured" have come apart.

Verified through the frontend host, not just tests: /api/memode: dev with the user, get-session → a session payload, sign-out → the cookie, get-session with it → null, sign-in/oauth2{redirect:true,url:"/"} clearing it; src/dev-auth.test.ts covers those paths plus the production refusal and that an absolute callbackURL cannot turn sign-in into an open redirect, and is the one suite needing no API key.

🤖 Generated with Claude Code

Exercising anything behind a session — the rail chip, `/api/me`, `AUTH_REQUIRED`,
the identity a run executes as — meant registering an OIDC client on Arcade's IdP
and doing the redirect dance. `DEV_AUTH=true` now hands `/api/auth/*` to
`src/dev-auth.ts`, which answers in Better Auth's own shapes: signed in by
default, signing out is a cookie, and signing back in clears it. So `authClient`
and everything that reads a session need no dev branch, and there is no session
store — nothing to migrate, no rows in the auth tables, no `BETTER_AUTH_URL` to
get right.

It runs as `DEV_AUTH_USER`, defaulting to `ARCADE_USER_ID` so turning it on does
not quietly move which Arcade account tools execute as. It wins over `oidc`,
because a machine with credentials in `.env` is exactly the one that wants to
skip the dance, and it refuses when `NODE_ENV=production` — nothing here
authenticates anybody, so that check is the whole security model.

`/api/me` returns `mode: "oidc" | "dev" | "off"` in place of
`configured: boolean`: one field for the one question the login page and every
route actually ask, now that "login works" and "OIDC is configured" have come
apart.

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
abilities-frontend Ready Ready Preview, Comment Jul 28, 2026 4:52pm

Request Review

…v auth

Two reasons login could not complete on a Vercel preview.

`authBaseURL()` fell through to `http://localhost:3000` for anything without
`BETTER_AUTH_URL` or `PORTLESS_URL`, and that is the host Better Auth puts in the
`redirect_uri` it hands the IdP. It does not fail loudly: the IdP rejects an
unregistered URI, or the browser is sent to a machine that isn't there. Production
sets `BETTER_AUTH_URL` and works; previews did not, so every preview asked Ory to
redirect to localhost. A deployment now names itself from Vercel's env, preferring
`VERCEL_BRANCH_URL` over `VERCEL_URL` because an OIDC client registers exact
redirect URIs and a per-deployment host is one nobody can register.

Which is also why a preview wants dev auth: no preview URL can be registered
ahead of time, so real login there is a dead end. `DEV_AUTH=true` was refused
anyway, because it checked `NODE_ENV` and Vercel builds previews with
`NODE_ENV=production`. It now checks the production *deployment* — `VERCEL_ENV`
where that exists, `NODE_ENV` otherwise.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant