Keycloak GitHub Login: Add GitHub as an Identity Provider

Guilliano MolaireGuilliano MolaireUpdated 10 min read

To use GitHub as a Keycloak identity provider, register a GitHub OAuth App whose authorization callback URL is https://your-keycloak.example.com/realms/your-realm/broker/github/endpoint, then open Identity providers in the Keycloak admin console, add GitHub, and paste in the app’s Client ID and Client Secret. Keycloak’s GitHub provider speaks GitHub’s plain OAuth 2.0 API rather than OpenID Connect, and it asks for the user:email scope by default so it can still find the address of users who keep their email private.

This guide walks through those steps on the current GitHub Developer settings and the Keycloak 26 admin console, explains what the scopes and the first login settings actually do, and ends with fixes for the errors people hit most often. It assumes you already have a realm and an application client in it. If you want Google and Apple alongside GitHub, see our Keycloak social login guide; this post goes deeper on GitHub alone.

Key Takeaways

  • The GitHub OAuth App’s callback URL is the Redirect URI Keycloak shows for the provider (Keycloak admin guide).
  • Keycloak’s GitHub provider uses GitHub’s OAuth 2.0 endpoints and REST API, not OIDC (source).
  • The GitHub provider’s default scope is user:email (source); if you set your own scopes, keep user:email in the list.
  • Leave Trust Email off unless you accept GitHub’s primary address as proof of ownership.

How does Keycloak GitHub login work?

Keycloak acts as an identity broker here: your application only ever talks to Keycloak, and Keycloak delegates the actual sign-in to GitHub. Your app keeps its normal OIDC or SAML client in Keycloak, and it receives Keycloak’s tokens whether the user typed a password or clicked GitHub. Nothing about GitHub’s OAuth flow ends up in your application code.

Keycloak’s GitHub provider does not read an OIDC discovery document. Its source hard-codes GitHub’s endpoints instead: it sends the user to https://github.com/login/oauth/authorize, exchanges the code at https://github.com/login/oauth/access_token (both described in GitHub’s authorization guide), and then calls the REST API at https://api.github.com/user to learn who the user is.

Keycloak GitHub login flow: the app sends the user to Keycloak, Keycloak brokers the sign-in through GitHub, reads the GitHub profile and returns its own tokens

Your app sends the user to Keycloak (1), Keycloak redirects them to GitHub to authorize (2), GitHub returns a code to the Keycloak callback (3), Keycloak trades it for a GitHub access token (4) and reads the user’s profile and emails from the GitHub API (5), the first login flow creates or links the local user (6), and Keycloak gives your app its own tokens (7).

Because Keycloak builds the user from that API response, the mapping is simple: GitHub’s numeric id becomes the identity’s ID, login becomes the username, name becomes the name, and email becomes the email. When the profile’s email is empty, Keycloak calls https://api.github.com/user/emails and takes the entry marked as primary (source). That second call is the reason the user:email scope matters.

Step 1: Copy the redirect URI from Keycloak

Start in Keycloak, because it tells you the exact callback URL GitHub needs. The Keycloak server administration guide describes the same order.

  1. Sign in to the Keycloak admin console and switch to your realm (not master, unless that is really where your users live).
  2. Click Identity providers in the left menu.
  3. Select GitHub from the Add provider list, as the admin guide describes.
  4. Copy the value of Redirect URI. Leave this tab open.

With the default github alias, the redirect URI should look like this:

https://your-keycloak.example.com/realms/your-realm/broker/github/endpoint

The github part is the provider’s alias. If you change the alias (for example to github-staff because you want two GitHub providers in one realm), the path changes with it, so copy the URI after you settle on the alias.

Step 2: Register a GitHub OAuth App

GitHub’s guide to creating an OAuth app gives the current path: click your profile picture, then Settings, then Developer settings at the bottom of the left sidebar, then OAuth Apps, then New OAuth App. If you have never made one, the button says Register a new application instead. GitHub says you can register an OAuth app under your personal account or under any organization you have administrative access to.

Fill in the form:

Field What to enter
Application name A name your users will recognise, such as “Acme login”; GitHub asks you to put only public information in an OAuth app
Homepage URL Your application’s public URL
Application description Optional; GitHub calls it a description of your app that users will see
Authorization callback URL The Keycloak redirect URI you copied in step 1
Enable Device Flow Leave it unchecked; Keycloak’s broker uses the browser flow

Click Register application. On the app’s page, copy the Client ID, then click Generate a new client secret and copy the secret right away.

Keep one OAuth App per Keycloak environment. A staging realm and a production realm have different redirect URIs, so giving each its own app keeps each callback URL matched to its realm and each secret separate.

Step 3: Add the GitHub provider in Keycloak

Back in the Keycloak tab:

  1. Paste the GitHub Client ID into Client ID.
  2. Paste the secret into Client Secret.
  3. Click Add.

That is enough for a working login button, and the options below are on the provider’s settings. The provider also has base URL and API URL settings, which default to https://github.com and https://api.github.com (source).

If you manage Keycloak as code, our Keycloak Config Generator can help you scaffold the realm configuration around the provider.

Which GitHub scopes does Keycloak need?

The GitHub provider’s source sets its default scope to user:email (GitHub provider source), and Keycloak’s OAuth 2.0 broker code stores that default in the provider’s Scopes setting when the setting is empty, then sends the setting’s value as the scope of the authorization request (OAuth 2.0 broker source). For most realms that default is right, and you can leave the field alone.

The scopes you are likely to care about, as GitHub’s scopes reference defines them:

Scope What GitHub grants When you need it
(no scope) Read-only access to public information, including the user’s profile Never on its own for Keycloak, since private emails stay hidden
user:email Read access to the user’s email addresses When the profile email is empty: Keycloak then calls the emails API to find the primary address
read:user Read access to the user’s profile data Rarely; the public profile is already readable
read:org Read-only access to organization and team membership Only if you check organization membership yourself (see troubleshooting)

Since the broker code only fills in the default when the setting is empty and sends the setting’s value (source), a value you type, for example to add read:org, is what GitHub receives, so write user:email read:org rather than read:org alone. Without user:email (or the broader user scope), the emails call Keycloak makes for users without a public email can fail.

Somewhere to run this that stays patched

Everything above works the same on Skycloak, because it is real upstream Keycloak rather than a fork. What changes is who handles the upgrades, backups and security patches afterwards.

What do Trust Email and the first login flow do?

Two settings on the provider decide what happens the first time a GitHub user reaches your realm.

Trust Email. The Keycloak admin guide says that when this is on, Keycloak trusts email addresses from the identity provider, so it does not ask the user to verify the address again. Be careful with GitHub here. Keycloak picks the email marked as primary in GitHub’s list and does not check GitHub’s verified flag on it (source). Leave Trust Email off unless you are comfortable accepting GitHub’s primary address as proof of ownership, especially in a realm where local accounts with passwords also exist.

First login flow. This is the authentication flow Keycloak runs when someone signs in through this provider for the first time, and the default is the built-in first broker login flow, described in the admin guide’s first login flow section. In short, it shows a Review Profile page when required details such as the email are missing, creates a new Keycloak user if no existing user has the same username or email, and otherwise asks the user to confirm linking the GitHub identity to the existing account, after proving they own it by email or by signing in to it. You can copy that flow and change it; see our guide to custom authentication flows.

Sync mode decides whether Keycloak copies GitHub’s profile onto the user only at first login (import) or on every login (force). If you want the user’s name to follow changes on GitHub, choose force, and use mappers to decide which fields are copied. For more on mappers, see our post on attribute mapping during identity brokering.

Step 4: Test the GitHub login

To test without your own application, use the realm’s Account Console, where Keycloak users sign in to manage their accounts. The admin guide gives its URL in this format:

https://your-keycloak.example.com/realms/your-realm/account
  1. Open that URL in a private browser window.
  2. On the Keycloak login page, click GitHub.
  3. Sign in to GitHub if you are not already, and approve the app on GitHub’s consent screen. It lists the scopes Keycloak asked for.
  4. GitHub returns you to Keycloak. On a first login you may see the Review Profile page; then you land in the Account Console, signed in.
  5. In the admin console, open Users and find the new user, whose username comes from the GitHub login.

If you would rather send users straight to GitHub without the Keycloak login page, add kc_idp_hint=github to the authorization request; see our post on using kc_idp_hint to choose an identity provider. To check the tokens your app receives after the GitHub login, paste them into the JWT Decoder.

Troubleshooting Keycloak GitHub login errors

GitHub shows “The redirect_uri MUST match the registered callback URL for this application”

This is GitHub’s redirect_uri_mismatch error. GitHub’s troubleshooting page says it happens when the redirect_uri in the request does not match what is registered on the OAuth App. With Keycloak, compare the realm name, the alias, the hostname and the scheme (http or https) of both URLs. Copy the redirect URI from the Keycloak provider page again and paste it into the GitHub app, character for character.

This error comes from GitHub’s side. If the error page is Keycloak’s own rather than GitHub’s, see our redirect URI mismatch troubleshooting guide.

Users land on an “Update account information” page asking for an email

That is the Review Profile step of the first login flow. In the GitHub provider source, when the profile has no email, Keycloak calls the emails API and either takes the primary address or fails the login with an error that the primary email could not be retrieved, so check the flow’s Review Profile setting and the profile attributes your realm requires. If the login fails with that primary email error instead, check the Scopes field: if it is set, it should include user:email or user, the scopes GitHub’s scopes reference lists for reading email addresses.

“User with email … already exists. How do you want to continue?”

A Keycloak user with the same email or username already exists, so the first login flow will not create a second one. The user can link the GitHub identity to the existing account after confirming they own it. See our post on the Keycloak “account already exists” error.

GitHub returns access_denied when the user clicks cancel on the consent screen, and its troubleshooting page notes there is nothing to fix on your side. The same page covers application_suspended, which means GitHub has suspended the OAuth App and you need to contact GitHub Support.

Only members of our GitHub organization should be able to sign in

The GitHub steps in the admin guide include no organization setting, so restricting login to an organization means writing your own check. If you take that route, request user:email read:org as the provider’s scopes, since GitHub’s scopes reference says read:org grants read-only access to organization and team membership.

The check itself can call GitHub’s organization membership endpoint for the authenticated user with the user’s GitHub access token:

GET https://api.github.com/user/memberships/orgs/your-org
Accept: application/vnd.github+json
Authorization: Bearer GITHUB_ACCESS_TOKEN

GitHub’s REST reference says this returns the user’s membership, with a state of active or pending and a role such as member or admin, when the user is an active or pending member, and a 404 when the user is not affiliated with the organization. Your code would let the login continue only for an active state.

To run that check, you would package it as a custom authenticator and bind it as the provider’s post login flow:

  1. In the admin console, open Authentication and create a flow that contains your authenticator.
  2. Open Identity providers, then the GitHub provider.
  3. In the provider’s settings, choose that flow as Post login flow and save.

The admin guide describes the post login flow as “the authentication flow Keycloak triggers when a user finishes logging in with the external identity provider”. Writing and deploying the authenticator is custom development; our guide to custom authentication flows covers building flows in the admin console.

Should I use a GitHub App instead of an OAuth App?

Keycloak works with both. GitHub itself suggests considering a GitHub App, which uses fine-grained permissions instead of scopes and can act on its own as well as for a user, while an OAuth App can only act for a user. The Keycloak admin guide mentions the provider’s JSON Format option, which retrieves the GitHub tokens in JSON format and which it says is required for tokens to be refreshed. GitHub compares the two in differences between GitHub Apps and OAuth apps.

Next steps

You now have GitHub as a login option in your realm: an OAuth App on GitHub with the Keycloak redirect URI, a GitHub provider in Keycloak with the user:email scope, and a first login flow that creates or links users. Before you roll it out, decide whether Trust Email should stay off, whether you need an organization check, and how existing users will link their GitHub identity. See also our social login implementation guide.

If you would rather not run Keycloak yourself, you can set up GitHub login on a managed Keycloak cluster with Skycloak, and our identity providers page shows the providers and settings you can configure there.

Sources

All retrieved on 2026-11-04.

Somewhere to run this that stays patched

Everything above works the same on Skycloak, because it is real upstream Keycloak rather than a fork. What changes is who handles the upgrades, backups and security patches afterwards.

Guilliano Molaire
Written by
Founder, Skycloak

Guilliano is the founder of Skycloak and a cloud infrastructure specialist with deep expertise in product development and scaling SaaS products. He discovered Keycloak while consulting on enterprise IAM and built Skycloak to make managed Keycloak accessible to teams of every size.

© 2026 Skycloak. All Rights Reserved. Design by Yasser SolimanKeycloak™ is a trademark of the Linux Foundation. Skycloak is not affiliated with the Keycloak project.