The most surprising thing about Supabase OAuth providers is that they don’t actually manage your users; they just authenticate them and give you a token.
Let’s see how this plays out with GitHub. Imagine a new user signs up for your app using their GitHub account.
First, your frontend client redirects the user to GitHub’s authorization server. They log in and grant your app permission to access their GitHub profile.
<a href="https://github.com/login/oauth/authorize?client_id=YOUR_GITHUB_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=read:user">Login with GitHub</a>
GitHub then redirects the user back to your redirect_uri with a temporary code.
Your backend receives this code and exchanges it with GitHub for an access_token.
curl -X POST \
-H "Accept: application/json" \
-d '{
"client_id": "YOUR_GITHUB_CLIENT_ID",
"client_secret": "YOUR_GITHUB_CLIENT_SECRET",
"code": "THE_RECEIVED_CODE",
"redirect_uri": "YOUR_REDIRECT_URI"
}' \
https://github.com/login/oauth/access_token
This access_token is what you use to fetch user information from GitHub’s API.
curl -H "Authorization: token YOUR_GITHUB_ACCESS_TOKEN" \
https://api.github.com/user
Supabase’s role here is to take that access_token (or the user info directly) and create a corresponding user record in your Supabase auth.users table. You’ll have a provider column set to github and a raw_user_data JSONB column containing the GitHub profile details.
The critical piece is that Supabase doesn’t store your GitHub secrets. You configure your GitHub client_id and client_secret in the Supabase dashboard under Authentication > OAuth.
Supabase Dashboard Configuration:
- Navigate to Authentication > OAuth providers.
- Click on GitHub.
- Enter your Client ID and Client Secret obtained from the GitHub Developer Applications settings.
- Ensure your Redirect URL in GitHub matches exactly what you’ve configured in Supabase (e.g.,
https://your-project-ref.supabase.co/auth/v1/callback).
Now, when a user successfully authenticates with GitHub and your backend exchanges the code for a token, you’ll use the Supabase client library to sign them in.
// Using supabase-js
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'github',
options: {
// You can optionally pass the access token directly if you've already obtained it
// accessToken: 'YOUR_GITHUB_ACCESS_TOKEN'
}
});
If you pass the accessToken, Supabase will use it to fetch user data and create/link the user. If you don’t, Supabase will initiate its own OAuth flow to get the token. The key is that Supabase itself doesn’t need to know your GitHub client_secret; it only needs the access_token to identify the user.
The raw_user_data column in auth.users is a treasure trove. It contains all the profile information returned by the OAuth provider. This often includes id, email, name, avatar_url, and more, depending on the scopes you requested. You can leverage this data directly in your application logic without needing to make additional API calls to the provider after the initial sign-in.
The actual user management — creating profiles, setting up row-level security policies based on auth.uid(), managing sessions — all happens within Supabase, using the identity information provided by the OAuth flow. The OAuth provider is just the initial gatekeeper.
The next concept you’ll likely grapple with is how to handle users who have accounts with multiple OAuth providers, or how to link existing Supabase users to new OAuth accounts.