Docs /setup/GITHUB_OAUTH

GitHub OAuth Setup Guide

This guide walks you through creating a GitHub OAuth App and configuring it for izri.


1. Create a GitHub OAuth App

  1. Go to GitHub Developer Settings → OAuth Apps
  2. Click "New OAuth App"
  3. Fill in the form:
Field Value
Application name izri (dev) (or any name)
Homepage URL http://localhost:5173
Authorization callback URL http://localhost:4000/api/auth/callback/github
  1. Click "Register application"
  2. Copy your Client ID
  3. Click "Generate a new client secret" and copy the Client Secret

⚠️ The client secret is only shown once. Store it safely.


2. Configure Environment Variables

In your .env.shared file (copy from .env.shared.example if it doesn't exist):

# GitHub OAuth
GITHUB_CLIENT_ID=your_client_id_here
GITHUB_CLIENT_SECRET=your_client_secret_here

Then regenerate app env files:

pnpm env:generate

3. Callback URL Reference

Environment Callback URL
Development http://localhost:4000/api/auth/callback/github
Production https://your-domain.com/api/auth/callback/github

The path /api/auth/callback/github is automatically handled by Better Auth's GitHub social provider.


4. Required Scopes

Better Auth requests these scopes by default when using the GitHub provider:

Scope Purpose
read:user Read user profile (name, avatar, email)
user:email Read user's email address

For GitHub repository integration (repo analysis features), additional scopes are needed:

Scope Purpose
repo Read access to repositories
read:org Read organization membership

To request additional scopes, configure the GitHub provider in packages/auth/src/better-auth.ts:

socialProviders: {
  github: {
    clientId: env.GITHUB_CLIENT_ID,
    clientSecret: env.GITHUB_CLIENT_SECRET,
    scope: ['read:user', 'user:email', 'repo', 'read:org'],
  },
},

5. How OAuth Flow Works

User clicks "Sign in with GitHub"
  → Frontend redirects to /api/auth/signin/github
    → Better Auth redirects to GitHub OAuth page
      → User authorizes
        → GitHub redirects to /api/auth/callback/github
          → Better Auth validates code, fetches user info
            → Creates/updates user in DB (users table)
            → Creates account record (accounts table) with accessToken
            → Creates session (sessions table)
              → Frontend receives session cookie

6. Token Storage

After successful OAuth, Better Auth stores:

  • account table: accessToken, accessTokenExpiresAt, scope, providerId = "github", accountId = github_user_id
  • session table: Session token and expiry
  • user table: User profile data (name, email, image)

To retrieve a user's GitHub access token:

import { db, accounts } from '@izri/database'
import { eq, and } from 'drizzle-orm'

const githubAccount = await db.query.accounts.findFirst({
  where: and(
    eq(accounts.userId, userId),
    eq(accounts.providerId, 'github')
  ),
})

const githubToken = githubAccount?.accessToken

7. Testing the OAuth Flow Locally

  1. Start all services: pnpm dev
  2. Navigate to http://localhost:5173/auth/login
  3. Click "Sign in with GitHub"
  4. Authorize the app on GitHub
  5. You should be redirected back and logged in

8. Production Setup

For production, create a separate GitHub OAuth App with:

  • Homepage URL: https://your-domain.com
  • Callback URL: https://your-domain.com/api/auth/callback/github

Update environment variables in your production environment accordingly.


Staging OAuth App

Create a separate GitHub OAuth App for the staging environment:

Field Value
Application name izri (staging)
Homepage URL https://<staging-web-public-domain>
Authorization callback URL https://<staging-api-public-domain>/api/auth/callback/github

Set GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET on the staging Railway services.


Troubleshooting

"redirect_uri_mismatch" error

The callback URL in your GitHub OAuth App settings doesn't match what Better Auth is sending. Verify API_URL in your .env.shared matches the registered callback URL host.

"Bad credentials" error

Your GITHUB_CLIENT_ID or GITHUB_CLIENT_SECRET is incorrect. Double-check the values in GitHub Developer Settings.

User not created in database

Check DATABASE_URL is correct and migrations have been run (pnpm db:migrate).

Reading this with an agent? /docs/setup/GITHUB_OAUTH.md serves the raw markdown.

All docs