Skip to content

Index

This source lets users authenticate with their GitHub credentials by configuring GitHub as a federated identity provider with OAuth 2.0.

Preparation

The following placeholders are used in this guide:

  • authentik.company is the FQDN of the authentik installation.
  • www.my.company is the Homepage URL for your site

GitHub configuration

To integrate GitHub with authentik, you need to create an OAuth application in GitHub Developer Settings.

  1. Log in to GitHub and open the Developer Settings menu.
  2. Create an OAuth app by clicking on the Register a new application button and set the following values:

    • Application Name: authentik
    • Homepage URL: www.my.company
    • Authorization callback URL: https://authentik.company/source/oauth/callback/github
  3. Click Register Application

  4. Click Generate a new client secret and take note of the Client Secret and Client ID. These values will be required in the next section.

authentik configuration

To support the integration of GitHub with authentik, you need to create a GitHub OAuth source in authentik.

  1. Log in to authentik as an administrator and open the authentik Admin interface.
  2. Navigate to Directory > Federation and Social login, click New Source, and then configure the following settings:
    • Select type: select GitHub OAuth Source as the source type.
    • Create GitHub OAuth Source: provide a name, a slug that must match the slug used in the GitHub Authorization callback URL field (e.g. github), and set the following required configurations:
      • Protocol settings
        • Consumer key: <client_ID>
        • Consumer secret: <client_secret>
        • Scopes (optional): define any further access scopes.
  3. Click Finish to save your settings.

:::info Display new source on login screen For instructions on how to display the new source on the authentik login page, refer to the Add sources to default login page documentation. :::

:::info Embed new source in flow :ak-enterprise For instructions on embedding the new source within a flow, such as an authorization flow, refer to the Source Stage documentation. :::

Optional additional configuration

Check for membership of a GitHub organization

GitHub's profile response does not contain organization membership. A source property mapping can use the OAuth client and token to query the membership API. The mapping below records whether the user is an active member and synchronizes a source-linked authentik group for active members.

  1. Edit the GitHub OAuth source under Directory > Federation and Social login. Add read:org under Protocol settings > Scopes, and then click Update.
  2. Navigate to Customization > Property Mappings. Click Create, select OAuth Source Property Mapping, and then click Next.
  3. Provide a name and enter this expression. Replace your_organization with the GitHub organization login.
organization = "your_organization"
response = client.do_request(
    "GET",
    f"https://api.github.com/user/memberships/orgs/{organization}",
    token=token,
)
if response.status_code == 404:
    active = False
else:
    response.raise_for_status()
    active = response.json().get("state") == "active"

return {
    "attributes": {"github_org_membership": {"organization": organization, "active": active}},
    "groups": [f"github:{organization}"] if active else [],
}
  1. Click Finish. Edit the GitHub OAuth source again and add the mapping under OAuth Attribute mapping > User Property Mappings > Selected User Property Mappings. Click Update.

authentik creates the github:<organization> group using the source's default group matching mode. It reconciles source-linked membership after successful logins. If the GitHub API returns an error other than 404, the mapping stops the login rather than treating an API failure as a membership denial.

To deny login to users outside the organization, create an Expression Policy with this expression and bind it to both the source's enrollment and authentication flows:

from authentik.sources.oauth.models import OAuthSource

source = request.context.get("source")
if not isinstance(source, OAuthSource) or source.provider_type != "github":
    return True

membership = request.context.get("prompt_data", {}).get("attributes", {}).get(
    "github_org_membership", {}
)
if not membership.get("active"):
    ak_message("You are not an active member of the required GitHub organization.")
    return False
return True

The policy reads the property mapping's result from the flow's prompt_data. Binding it to both flows covers new and returning users. For binding steps, see Bind a policy to a flow.

Flows use the ANY policy engine mode by default, so a flow passes when any one of its bound policies passes. The default source flows, default-source-enrollment and default-source-authentication, already bind a policy that passes on every source login, so in ANY mode the organization policy never denies a user. Edit each flow, and under Behavior settings, set Policy engine mode to ALL. See policy bindings and evaluation for details.

If the policy denies a returning user, the group update stage does not run. Any group membership from an earlier successful login remains until that user logs in successfully again or you remove it separately. Use the policy result, not the synchronized group, when you need to enforce current organization membership at login.

Source property mappings

The organization example above uses an OAuth source property mapping to query GitHub. See the source property mappings overview and OAuth expression data for other fields and client methods.

Resources