Features Apograph CMS on GitHub

GitHub sign-in

Identity plugin @apograph/identity-server@apograph/identity-admin

Its own package because GitHub is not OpenID Connect — and that changes three things.

Documents 0.5.2 Updated Edit this page Report a problem

On this page

GitHub sign-in, for github.com and GitHub Enterprise Server.

Its own package because GitHub is not OpenID Connect

There is no identity token, so “verify” cannot mean “check a signature”. It means spending the authorization code for an access token over TLS, then reading the profile back from GitHub with it.

The port allows this — complete returns a profile and never promises how it was obtained — which is exactly the flexibility a second protocol needed, and the reason this exists rather than as a preset inside the OIDC adapter.

It depends only on the identity domain package. No SDK: two endpoints and two reads are plain fetch, and there is no cryptography here to get wrong.

Install

npm install @apograph/identity-provider-github
import { createGithubProvider } from '@apograph/identity-provider-github';

IdentityPlugin(config.plugins.identity, {
    sso: {
        providers: [{ name: 'github', provider: createGithubProvider(settings) }]
    }
});

Configuration

VariableWhat it does
SSO_GITHUB_CLIENT_IDThe OAuth app’s client id
SSO_GITHUB_CLIENT_SECRETRequired — see below
SSO_GITHUB_NAMERegistration name
SSO_GITHUB_LABELThe sign-in button’s text
SSO_GITHUB_ENTERPRISE_URLA GitHub Enterprise Server root. Empty for github.com
SSO_GITHUB_ORGShapes GitHub’s account chooser. Cosmetic

Three consequences of not being OIDC

The client secret is required. There is no PKCE in this flow, so the secret is the only thing proving the code is being redeemed by the application it was issued to. A configuration without one is refused.

state is the whole replay defence. There is no nonce to bind into a token, so the adapter checks the echoed state itself rather than assuming the caller did — and sends neither a nonce nor a PKCE challenge, because sending values a provider ignores is noise that reads as protection.

The address comes from the verified-emails endpoint, never the profile. A profile address is something a person can set to anything, and it is frequently empty. Trusting it would break the port’s third clause in its most literal form: an unverified string used as if the provider had vouched for it.

No verified address is a refusal, not an unverified profile

An account with no verified address is refused outright rather than reported as emailVerified: false.

The distinction matters. A false would still let a deployment link the account if it ever relaxed that rule — and there is no address here worth linking, because GitHub has told us it does not know whether anyone can be reached at it.

Other things worth knowing

The subject is the numeric id, as a string, never the login. A login can be changed, and a released login can be claimed by somebody else — the same failure mode that keeps an email out of that field.

accept: application/json on the token exchange. Without it GitHub answers form-encoded, which parses as an empty object and reads as “no access token” three lines later.

A 200 with an error field is a failure. GitHub reports a bad code that way, so the status alone is not the check.

Enterprise Server serves its API under /api/v3, while github.com uses a separate host. Getting that wrong is a 404 on the profile read, one step after a token exchange that appeared to work.

SSO_GITHUB_ORG is cosmetic, like Google’s hd. It shapes the account chooser; Apograph’s own rules decide who gets in.