Add a Github IdP

On this page
Note

GitHub users must have a public email address to allow FusionAuth to link their account on an email address. If they do not, you will get an error message stating An email address was not provided for the user. This account cannot be used to login, unable to complete this login request. You have two options:

  • Require all users who use GitHub to log in have a public email address. This is configured on a per-user basis under Public Profile -> Public Email . This is done on GitHub.
  • Link on username or create an anonymous link. Using these strategies ensure the configured GitHub OIDC connection works for every user, no matter their GitHub privacy settings, but means you won't have access to their email address.

Once you have completed this configuration you may enable an OpenID Connect Login with GitHub button for one or more FusionAuth Applications. See GitHub - Creating an OAuth App for an additional reference.

Login with GitHub

Here's a diagram of the login flow between:

  • the user
  • your application
  • FusionAuth and
  • a remote identity provider
ProviderFusionAuthAppUser/BrowserProviderFusionAuthAppUser/BrowserUser Is Logged In And App Can ProceedDelivering Data And FunctionalityView Initial PageClick LoginDisplays Login PageIncluding Link To 'Login With Provider'Clicks On 'Login With Provider'Redirect To Provider Authorization URLEnters CredentialsValidate CredentialsRedirect to App With Authorization CodeRequests Page, Has Authorization CodeCalls Complete LoginWith Code And Redirect URIExchanges Code AndRedirect URI For Provider TokenReturns Provider TokenStores Provivider Token, Calls Lambda, Creates User And Registrations (If Needed), Generates FusionAuth TokensReturn FusionAuth TokensCreate Session OrOtherwise Log User In

Although this looks complex, the user only sees a few screens, such as the FusionAuth login screen, the provider login screen, and your application.

Register a GitHub OAuth2 Application#

You will first need to log in to GitHub.

Once logged in, navigate to Settings -> Developer settings -> OAuth Apps -> Register a new application to create a new GitHub OAuth Application.

Register a new GitHub OAuth Application

Register a new GitHub OAuth Application

Here we have configured our application Authorization callback URL. If FusionAuth is running at login.piedpiper.com, this value should be https://login.piedpiper.com/oauth2/callback.

GitHub Client ID and Secret

GitHub Client ID and Secret

Once the application has been created, note the Client ID and the Client Secret. These will be used respectively as the Client Id value and the Client secret value in your FusionAuth OpenID Connect Identity Providers configuration. Please note that you may have to click on "Generate a new client secret".

Configure a New FusionAuth OpenID Connect Identity Provider#

To create a GitHub Identity Provider return to FusionAuth and navigate to Settings -> Identity Providers and click Add provider and select OpenID Connect from the dialog.

This will take you to the Add OpenID Connect panel, and you'll fill out the required fields.

You will need to set Client authentication method to HTTP Basic authentication (client_secret_basic).

Client Id and Client secret values reference the previously noted GitHub OAuth Application's Client ID and Client Secret. The Redirect URL is read only and generated for you based upon the URL of FusionAuth, this value should match the one you configured in your GitHub application.

GitHub has not implemented a well-known configuration endpoint, so you will need to disable the Discover endpoints field and specify the endpoints manually. The values for these fields are:

  • Authorization endpoint - https://github.com/login/oauth/authorize
  • Token endpoint - https://github.com/login/oauth/access_token
  • Userinfo endpoint - https://api.github.com/user

You will need to specify user:email as a Scope for your application.

In the following screenshot you will see that we have enabled this login provider for the Pied Piper application and enabled Create registration.

GitHub does not implement OpenID Connect to spec. In order to pull in some additional data for populating the user profile (GitHub shortname, Image URL, etc.) you can enable a Reconcile lambda. This example lambda below is based on a GitHub use case. This is optional.

Example lambda#

The following lambda reconciles a user after a GitHub login. The lambda copies the GitHub avatar and name to the user, and sets the registration username to the GitHub login. The lambda stores the company and location in user.data, and removes the @ that GitHub adds to organization names in the company field.

The lambda also calls the GitHub API with the access token from the tokens argument to list the user's GitHub organizations. The lambda maps each organization to a role with orgRoles, and drops organizations with no mapping. The call needs the read:org scope in the identity provider configuration. When the call fails, the lambda logs the error and keeps the current roles, so the login still succeeds. Calling an API from a lambda requires the Essentials plan or higher. See Lambda HTTP Connect.

A lambda that saves the GitHub profile and assigns roles from GitHub organizations.
// fills in the profile from GitHub and assigns roles based on the user's GitHub organizations
function reconcile(user, registration, jwt, id_token, tokens, context) {
  user.imageUrl = jwt.avatar_url || user.imageUrl;
  user.fullName = jwt.name || user.fullName;
  registration.username = jwt.login;

  user.data = user.data || {};
  if (jwt.company) {
    // github prefixes organization names with @
    user.data.company = jwt.company.replace(/^@/, '');
  }
  if (jwt.location) {
    user.data.location = jwt.location;
  }

  // requires the read:org scope
  var response = fetch('https://api.github.com/user/orgs', {
    method: 'GET',
    headers: {
      'Accept': 'application/vnd.github+json',
      'Authorization': 'Bearer ' + tokens.access_token
    }
  });

  // keep the current roles instead of failing the login
  if (response.status !== 200) {
    console.error('Could not read GitHub organizations. GitHub returned status ' + response.status + '.');
    return;
  }

  var orgRoles = { 'piedpiper': 'employee', 'piedpiper-admins': 'admin' };
  registration.roles = JSON.parse(response.body)
    .map(function (org) {
      return orgRoles[org.login];
    })
    .filter(Boolean);
}

To see what your IdP returns in the jwt object while you develop a lambda, print the object to the Event Log. Add the following line to the lambda:

console.info(JSON.stringify(jwt, null, 2));

Options#

The final item to configure is under the Options tab. For GitHub, you will want to configure:

  • Unique Id claim of id
  • Email claim of email
  • Username claim of login

That's it, now the Login with GitHub button will show up on the login page of our Pied Piper application.

FusionAuth GitHub IdP Configuration

Troubleshooting#

GitHub users must have a public email address to allow FusionAuth to link their account on an email address. If they do not, you will get an error message stating An email address was not provided for the user. This account cannot be used to login, unable to complete this login request. You have two options:

  • Require all users who use GitHub to log in have a public email address. This is configured on a per-user basis under Public Profile -> Public Email . This is done on GitHub.
  • Link on username or create an anonymous link. Using these strategies ensure the configured GitHub OIDC connection works for every user, no matter their GitHub privacy settings, but means you won't have access to their email address.