Demo: GitHub OAuth2 social login
Location: contrib/demo/github/
Starts one ahdapa instance configured to use GitHub as an upstream OAuth2 provider. Users authenticate at GitHub and are mapped to a local ahdapa account. This demo shows how to integrate a plain OAuth2 provider that does not support OIDC Discovery or ID tokens.
What it shows
- Non-OIDC upstream provider — GitHub does not expose an OIDC Discovery
document or issue ID tokens. All three endpoints
(
authorization_endpoint,token_endpoint,userinfo_endpoint) are configured explicitly in the[[federation.upstream_idps]]stanza. - Numeric subject claim — after the code exchange, ahdapa calls
GET https://api.github.com/userwith the GitHub access token and extracts theidfield (a numeric integer) as theupstream_sub. - Auto-link flow — the script detects the numeric GitHub user ID from
the server log after the first (rejected) login attempt, then creates the
federated_accountsrow automatically so the second visit succeeds. - Default group and ACR/AMR injection — the upstream stanza sets
default_groups,default_acr, anddefault_amrso that downstream applications receive meaningful authentication context even though GitHub does not return these fields.
Prerequisites
-
A GitHub OAuth App with:
- Homepage URL:
http://127.0.0.1:8080 - Authorization callback URL:
http://127.0.0.1:8080/internal/callback/github
Register one at: GitHub → Settings → Developer settings → OAuth Apps → New OAuth App. Copy the Client ID and generate a Client Secret.
- Homepage URL:
-
ahdapabinary — the script looks in$PATHfirst (resolved to its full path), thentarget/release/ahdapa, thentarget/debug/ahdapa, and falls back tocargo buildif none is found. -
Port 8080 free.
-
A browser to complete the GitHub OAuth2 flow.
Running
contrib/demo/github/run.sh
The script prompts for the GitHub OAuth App credentials if they are not already set in the environment:
GitHub OAuth App Client ID: <paste here>
GitHub OAuth App Client Secret: <paste here>
Alternatively, export them before running:
export GITHUB_CLIENT_ID=Ov23liABCDEF123456
export GITHUB_CLIENT_SECRET=abcdef1234567890abcdef1234567890abcdef12
contrib/demo/github/run.sh
What the script does
- Reads
GITHUB_CLIENT_IDandGITHUB_CLIENT_SECRETfrom the environment or prompts for them. - Substitutes the values into
github.toml(__GITHUB_CLIENT_ID__and__GITHUB_CLIENT_SECRET__placeholders) and writescontrib/demo/github/github-runtime.toml. - Starts ahdapa on port 8080 and waits for it to be ready.
- Logs in as
alicevia the admin API to obtain a session cookie. - Checks
GET /api/admin/federated-accounts— if the GitHub account is already linked, prints the URL and waits for Ctrl-C. - If not yet linked, prints the URL and watches the server log for a
"no local account linked"line that contains the GitHub numeric user ID.
First-time link flow
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Step 1 — visit this URL to start the GitHub login:
http://127.0.0.1:8080/auth/external/github
GitHub will ask for permission and redirect back here.
Because your account is not linked yet you will see a
403 page — that is expected. This script detects your
GitHub user ID from the server log and links the account
automatically.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Watching for your GitHub user ID...
- Visit
http://127.0.0.1:8080/auth/external/githubin a browser. - GitHub prompts for permission to share your profile. Authorize it.
- GitHub redirects back to ahdapa. Because no
federated_accountsrow exists yet, ahdapa returns HTTP 403. This is expected. - The script detects your numeric GitHub user ID (e.g.
12345678) from the server log and callsPOST /api/admin/federated-accountsto create the link between your GitHub account andabbra@CORP.LOCAL.
Detected GitHub user ID: 12345678
Linking to abbra@CORP.LOCAL...
Account linked.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Step 2 — visit the URL again to complete the login:
http://127.0.0.1:8080/auth/external/github
You will be redirected to GitHub and back, then land in the
admin panel logged in as abbra@CORP.LOCAL.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Visit the URL again. GitHub recognizes the already-authorized app and
redirects immediately. ahdapa finds the link and issues a local session
for
abbra@CORP.LOCAL. The admin panel opens.
On subsequent runs the account is already linked and the login works on the first visit.
Configuration notes
The relevant upstream IdP stanza in github.toml:
[[federation.upstream_idps]]
id = "github"
issuer = "https://github.com"
client_id = "__GITHUB_CLIENT_ID__"
client_secret = "__GITHUB_CLIENT_SECRET__"
token_endpoint_auth_method = "client_secret_post"
authorization_endpoint = "https://github.com/login/oauth/authorize"
token_endpoint = "https://github.com/login/oauth/access_token"
userinfo_endpoint = "https://api.github.com/user"
subject_claim = "id"
scopes = ["read:user", "user:email"]
callback_path = "/internal/callback/github"
default_groups = ["corp-staff"]
default_acr = "urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocolPassword"
default_amr = ["pwd", "fed"]
Key points:
subject_claim = "id"— uses the numeric integer field from the GitHub userinfo response as the external subject identifier rather than a username string.default_groups,default_acr,default_amr— injected into every token issued after a successful GitHub login because GitHub’s userinfo does not include these fields.- No
discovery_url— OIDC Discovery is not used; all three endpoints are provided explicitly.
The demo maps GitHub users to abbra@CORP.LOCAL. To map to a different local
account, change the LOCAL_SUB variable in run.sh.
| File | Description |
|---|---|
github.toml | Server config with GitHub upstream IdP stanza and __GITHUB_CLIENT_ID__ placeholders |
users.toml | Local users: alice (admin) used for the setup API |
Security notes
github-runtime.toml is git-ignored because it contains the real client
secret. Do not commit it. The secret is held only in the script’s environment
and the runtime config file, which is deleted on Ctrl-C.
See also
- Federation — full federation configuration reference.
- Two-IdP federation demo — OIDC federation between two ahdapa instances.