Setting Up OAuth Providers for Self-Hosted Supabase

Complete guide to configuring Google, GitHub, Discord, and Apple OAuth for self-hosted Supabase with environment variables and docker-compose.

Cover Image for Setting Up OAuth Providers for Self-Hosted Supabase

One of the first things developers notice after deploying self-hosted Supabase is the missing Authentication settings in the dashboard. On Supabase Cloud, you click a few buttons to enable Google or GitHub login. On self-hosted instances, those buttons don't exist.

The Auth configuration panel is disabled for self-hosted deployments. Instead, you configure OAuth providers through environment variables in your docker-compose.yml file. This guide walks you through setting up the most popular OAuth providers—Google, GitHub, Discord, and Apple—so your users can sign in with their existing accounts.

If you're new to self-hosting Supabase, start with our step-by-step deployment guide first, then return here to configure authentication.

Why OAuth Configuration Is Different for Self-Hosted

Supabase uses GoTrue, an open-source authentication server written in Go, to handle user registration and authentication. On Supabase Cloud, the dashboard writes configuration changes directly to the managed GoTrue instance. Self-hosted deployments don't have this integration—the dashboard runs in "studio mode" with platform features disabled.

This means OAuth provider configuration requires:

  1. Creating OAuth applications with each provider (Google, GitHub, etc.)
  2. Adding environment variables to your docker-compose.yml
  3. Restarting your Supabase containers

The process is straightforward once you understand the pattern. Every provider follows the same structure: enable it, add the client ID, add the client secret, and set the redirect URI.

Understanding the Environment Variable Pattern

All OAuth providers use the same naming convention:

GOTRUE_EXTERNAL_{PROVIDER}_ENABLED=true
GOTRUE_EXTERNAL_{PROVIDER}_CLIENT_ID=your-client-id
GOTRUE_EXTERNAL_{PROVIDER}_SECRET=your-client-secret
GOTRUE_EXTERNAL_{PROVIDER}_REDIRECT_URI=https://your-domain.com/auth/v1/callback

Replace {PROVIDER} with the uppercase provider name: GOOGLE, GITHUB, DISCORD, APPLE, etc.

The redirect URI is critical. It must match exactly what you configure in each provider's developer console. For self-hosted Supabase, this is your Kong API gateway URL followed by /auth/v1/callback.

Setting Up Google OAuth

Google OAuth is the most common provider. Here's how to configure it.

Step 1: Create a Google Cloud Project

  1. Go to the Google Cloud Console
  2. Create a new project or select an existing one
  3. Navigate to APIs & ServicesOAuth consent screen
  4. Choose External user type and complete the consent screen setup
  5. Add your domain to the authorized domains list

Step 2: Create OAuth Credentials

  1. Go to APIs & ServicesCredentials
  2. Click Create CredentialsOAuth client ID
  3. Select Web application
  4. Add your callback URL to Authorized redirect URIs:
    https://your-supabase-domain.com/auth/v1/callback
    
  5. Copy the Client ID and Client Secret

Step 3: Add Environment Variables

Add these variables to the auth service in your docker-compose.yml:

auth:
  environment:
    GOTRUE_EXTERNAL_GOOGLE_ENABLED: "true"
    GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID: "your-google-client-id.apps.googleusercontent.com"
    GOTRUE_EXTERNAL_GOOGLE_SECRET: "your-google-client-secret"
    GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI: "https://your-supabase-domain.com/auth/v1/callback"

Alternatively, reference variables from your .env file:

auth:
  environment:
    GOTRUE_EXTERNAL_GOOGLE_ENABLED: ${ENABLE_GOOGLE_SIGNUP}
    GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
    GOTRUE_EXTERNAL_GOOGLE_SECRET: ${GOOGLE_CLIENT_SECRET}
    GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI: ${SUPABASE_PUBLIC_URL}/auth/v1/callback

For tips on making Google OAuth look professional (showing your app name instead of a random subdomain), see our guide on fixing Google OAuth branding.

Setting Up GitHub OAuth

GitHub OAuth is popular for developer-focused applications. The setup is simpler than Google.

Step 1: Create a GitHub OAuth App

  1. Go to GitHub SettingsDeveloper settingsOAuth Apps
  2. Click New OAuth App
  3. Fill in the application details:
    • Application name: Your app name
    • Homepage URL: Your application URL
    • Authorization callback URL: https://your-supabase-domain.com/auth/v1/callback
  4. Click Register application
  5. Generate a new client secret and copy both the Client ID and Client Secret

Step 2: Add Environment Variables

auth:
  environment:
    GOTRUE_EXTERNAL_GITHUB_ENABLED: "true"
    GOTRUE_EXTERNAL_GITHUB_CLIENT_ID: "your-github-client-id"
    GOTRUE_EXTERNAL_GITHUB_SECRET: "your-github-client-secret"
    GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI: "https://your-supabase-domain.com/auth/v1/callback"

GitHub OAuth is straightforward—no consent screen configuration or domain verification required.

Setting Up Discord OAuth

Discord OAuth is common for gaming applications and community platforms.

Step 1: Create a Discord Application

  1. Go to the Discord Developer Portal
  2. Click New Application and give it a name
  3. Navigate to OAuth2General
  4. Copy the Client ID
  5. Click Reset Secret to generate a client secret and copy it
  6. Add your redirect URL under Redirects:
    https://your-supabase-domain.com/auth/v1/callback
    

Step 2: Add Environment Variables

auth:
  environment:
    GOTRUE_EXTERNAL_DISCORD_ENABLED: "true"
    GOTRUE_EXTERNAL_DISCORD_CLIENT_ID: "your-discord-client-id"
    GOTRUE_EXTERNAL_DISCORD_SECRET: "your-discord-client-secret"
    GOTRUE_EXTERNAL_DISCORD_REDIRECT_URI: "https://your-supabase-domain.com/auth/v1/callback"

Setting Up Apple Sign-In

Apple Sign-In requires more setup than other providers but is essential for iOS applications (Apple requires it if you offer any social login).

Step 1: Apple Developer Account Setup

  1. Sign in to the Apple Developer Portal
  2. Go to Certificates, Identifiers & Profiles
  3. Create an App ID with Sign in with Apple capability enabled
  4. Create a Services ID (this becomes your client ID)
  5. Configure the Services ID:
    • Enable Sign in with Apple
    • Add your domain and return URL: https://your-supabase-domain.com/auth/v1/callback
  6. Create a Key with Sign in with Apple enabled
  7. Download the key file (you can only download it once)

Step 2: Generate the Client Secret

Apple uses a JWT as the client secret, which you generate using your private key. The JWT must be regenerated periodically (maximum 6 months validity).

Create the secret using a tool or script:

# Example using Ruby (Apple's recommended approach)
require 'jwt'

key_file = 'AuthKey_XXXXXXXXXX.p8'
team_id = 'YOUR_TEAM_ID'
client_id = 'YOUR_SERVICES_ID'
key_id = 'YOUR_KEY_ID'

ecdsa_key = OpenSSL::PKey::EC.new(File.read(key_file))

headers = {
  'kid' => key_id
}

claims = {
  'iss' => team_id,
  'iat' => Time.now.to_i,
  'exp' => Time.now.to_i + 86400 * 180, # 180 days
  'aud' => 'https://appleid.apple.com',
  'sub' => client_id
}

token = JWT.encode(claims, ecdsa_key, 'ES256', headers)
puts token

Step 3: Add Environment Variables

auth:
  environment:
    GOTRUE_EXTERNAL_APPLE_ENABLED: "true"
    GOTRUE_EXTERNAL_APPLE_CLIENT_ID: "your-services-id"
    GOTRUE_EXTERNAL_APPLE_SECRET: "your-generated-jwt-secret"
    GOTRUE_EXTERNAL_APPLE_REDIRECT_URI: "https://your-supabase-domain.com/auth/v1/callback"

Remember: The Apple client secret expires. You'll need to regenerate it before expiration and update your configuration.

Applying Configuration Changes

After adding environment variables, restart your Supabase containers:

docker-compose down
docker-compose up -d

The auth service reads configuration on startup, so a full restart is required for changes to take effect.

Verify the configuration by checking the auth container logs:

docker-compose logs auth | grep -i "external"

You should see log entries indicating which external providers are enabled.

Testing Your OAuth Setup

Test each provider with a simple sign-in flow:

import { createClient } from '@supabase/supabase-js'

const supabase = createClient('https://your-supabase-domain.com', 'your-anon-key')

// Test Google OAuth
const { data, error } = await supabase.auth.signInWithOAuth({
  provider: 'google',
  options: {
    redirectTo: 'https://your-app.com/auth/callback'
  }
})

Common issues to check:

  • Redirect URI mismatch: The callback URL must match exactly in both your provider console and environment variables
  • Missing protocol: URLs must include https://
  • Trailing slashes: Some providers are sensitive to trailing slashes—be consistent

Troubleshooting Common Problems

"Invalid redirect URI" Error

This almost always means the callback URL in your provider's developer console doesn't match your GOTRUE_EXTERNAL_{PROVIDER}_REDIRECT_URI exactly. Check for:

  • Protocol differences (http vs https)
  • Trailing slashes
  • Port numbers
  • Typos in the domain

OAuth Works Locally but Not in Production

Check that your production domain is:

  • Added to authorized domains in your provider console
  • Using HTTPS (most providers require it)
  • Correctly set in your SITE_URL environment variable

Users Get Redirected to the Wrong URL After Login

The SITE_URL environment variable controls where users land after authentication. Set it to your application's URL:

auth:
  environment:
    GOTRUE_SITE_URL: "https://your-app.com"

Provider Not Appearing in Sign-In Options

Ensure the ENABLED variable is set to "true" (as a string, not a boolean in YAML). Restart your containers after any configuration change.

Managing Multiple OAuth Providers

You can enable any combination of providers. Here's a complete example with all four providers configured:

auth:
  environment:
    # Site configuration
    GOTRUE_SITE_URL: "https://your-app.com"
    
    # Google
    GOTRUE_EXTERNAL_GOOGLE_ENABLED: "true"
    GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
    GOTRUE_EXTERNAL_GOOGLE_SECRET: ${GOOGLE_CLIENT_SECRET}
    GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI: ${SUPABASE_PUBLIC_URL}/auth/v1/callback
    
    # GitHub
    GOTRUE_EXTERNAL_GITHUB_ENABLED: "true"
    GOTRUE_EXTERNAL_GITHUB_CLIENT_ID: ${GITHUB_CLIENT_ID}
    GOTRUE_EXTERNAL_GITHUB_SECRET: ${GITHUB_CLIENT_SECRET}
    GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI: ${SUPABASE_PUBLIC_URL}/auth/v1/callback
    
    # Discord
    GOTRUE_EXTERNAL_DISCORD_ENABLED: "true"
    GOTRUE_EXTERNAL_DISCORD_CLIENT_ID: ${DISCORD_CLIENT_ID}
    GOTRUE_EXTERNAL_DISCORD_SECRET: ${DISCORD_CLIENT_SECRET}
    GOTRUE_EXTERNAL_DISCORD_REDIRECT_URI: ${SUPABASE_PUBLIC_URL}/auth/v1/callback
    
    # Apple
    GOTRUE_EXTERNAL_APPLE_ENABLED: "true"
    GOTRUE_EXTERNAL_APPLE_CLIENT_ID: ${APPLE_CLIENT_ID}
    GOTRUE_EXTERNAL_APPLE_SECRET: ${APPLE_CLIENT_SECRET}
    GOTRUE_EXTERNAL_APPLE_REDIRECT_URI: ${SUPABASE_PUBLIC_URL}/auth/v1/callback

Keep secrets in your .env file and reference them using ${VARIABLE_NAME} syntax to avoid committing credentials to version control.

The Easier Way: Using Supascale

Manually editing environment variables and restarting containers works, but it's tedious—especially when managing multiple projects or making frequent changes.

Supascale provides a UI for OAuth configuration that works like the Supabase Cloud dashboard. Add your client credentials through a web interface, and Supascale handles the environment variable updates and container restarts automatically.

You get:

  • Visual OAuth configuration: No more editing YAML files
  • Multiple projects: Configure different providers for different projects
  • Instant updates: Changes apply without manual container restarts
  • Credential validation: Catch configuration errors before they break authentication

For teams running multiple self-hosted Supabase instances, this eliminates a significant operational burden. Check out our documentation on configuring auth providers for details.

Additional Providers

Supabase supports many more OAuth providers beyond the four covered here:

  • Azure AD
  • Bitbucket
  • Facebook
  • Figma
  • GitLab
  • Keycloak
  • LinkedIn
  • Notion
  • Slack
  • Spotify
  • Twitch
  • Twitter
  • WorkOS

Each follows the same pattern: enable it, set the client ID, secret, and redirect URI. Check the Supabase auth configuration documentation for provider-specific environment variable names.

Summary

Setting up OAuth for self-hosted Supabase requires manual configuration through environment variables, but the process is consistent across all providers:

  1. Create an OAuth application in the provider's developer console
  2. Set the callback URL to https://your-supabase-domain.com/auth/v1/callback
  3. Add the GOTRUE_EXTERNAL_{PROVIDER}_* environment variables to your docker-compose.yml
  4. Restart your Supabase containers

The lack of a dashboard UI for OAuth configuration is one of the most common complaints about self-hosted Supabase. Understanding the environment variable pattern makes it manageable, and tools like Supascale can automate the process entirely.

Further Reading