feat(auth): Auth0 SSO sign-in - #26
Merged
Merged
Conversation
Add Auth0 as a third login provider through Better Auth's genericOAuth plugin, enabled by AUTH0_DOMAIN/CLIENT_ID/CLIENT_SECRET. Auth0 users skip the allowlist; a roles claim in the ID token (AUTH0_ROLES_CLAIM) maps AUTH0_ADMIN_ROLE_NAME to admin and AUTH0_USER_ROLE_NAME to student and is re-read at every sign-in. No role means denied: new users in user.create.before, returning users in session.create.before so no session or cookie is issued. CODERUNNER_ADMIN_EMAIL still grants admin. Decision 044; setup guide in docs/deploying/oauth-credentials.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # AGENTS.md # apps/control/src/auth/auth.ts
…s on GCE
- seedBootstrapAdmins no longer promotes users with an auth0 account. Auth0
sets the role at every sign-in (admin only for a verified address), and a
matching row may be an unverified self-sign-up that a later GitHub sign-in
links onto, so promoting it at startup bypassed the email_verified check.
- render-env.sh reads optional coderunner-auth0-{domain,client-id,
client-secret} secrets and writes AUTH0_* when all three are set, so Auth0
config survives reboots on the GCE deployment.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mathewdunne
marked this pull request as ready for review
October 1, 2026 17:27
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #24.
What
Adds Auth0 as a third sign-in option alongside GitHub and Google. Auth0 users don't need to be on the CodeRunner allowlist. Instead, their CodeRunner role comes from their Auth0 roles:
AUTH0_ADMIN_ROLE_NAME, defaultadmin)AUTH0_USER_ROLE_NAME, defaultuser)CODERUNNER_ADMIN_EMAILstill grants admin.AUTH0_DOMAIN,AUTH0_CLIENT_IDandAUTH0_CLIENT_SECRETare all set.AUTH0_ROLES_CLAIM, defaulthttps://coderunner/roles) and both role names are configurable, so they can match an existing tenant.How
genericOAuthplugin, using itsauth0()helper. The callback is/api/auth/oauth2/callback/auth0.user.create.before, so no user row is created.session.create.before, so no session or cookie is issued. The after-login hook doesn't work for this: Better Auth keeps the callback's 302 redirect and its cookies when that hook throws, and its 5-minute session cookie cache keeps the user signed in after the session row is deleted. Details in decision 044.mapProfileToUserwrites the role on every sign-in, so the session cookie carries the current role.Setup
See the new "Set up Auth0" section in
docs/deploying/oauth-credentials.md. It covers the Regular Web Application, the callback URL, the two roles, and the Post-Login Action that puts the roles in the ID token.Testing
bun run verifypasses: 463 control-plane tests, 141 web, 76 E2E and 12 security.auth0.test.tsruns the real Better Auth sign-in and callback against a fake Auth0 (discovery and token endpoints stubbed viafetch). It covers:/login?error=…and no session🤖 Generated with Claude Code