Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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/user with the GitHub access token and extracts the id field (a numeric integer) as the upstream_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_accounts row automatically so the second visit succeeds.
  • Default group and ACR/AMR injection — the upstream stanza sets default_groups, default_acr, and default_amr so 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.

  • ahdapa binary — the script looks in $PATH first (resolved to its full path), then target/release/ahdapa, then target/debug/ahdapa, and falls back to cargo build if 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

  1. Reads GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET from the environment or prompts for them.
  2. Substitutes the values into github.toml (__GITHUB_CLIENT_ID__ and __GITHUB_CLIENT_SECRET__ placeholders) and writes contrib/demo/github/github-runtime.toml.
  3. Starts ahdapa on port 8080 and waits for it to be ready.
  4. Logs in as alice via the admin API to obtain a session cookie.
  5. Checks GET /api/admin/federated-accounts — if the GitHub account is already linked, prints the URL and waits for Ctrl-C.
  6. 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.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  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...
  1. Visit http://127.0.0.1:8080/auth/external/github in a browser.
  2. GitHub prompts for permission to share your profile. Authorize it.
  3. GitHub redirects back to ahdapa. Because no federated_accounts row exists yet, ahdapa returns HTTP 403. This is expected.
  4. The script detects your numeric GitHub user ID (e.g. 12345678) from the server log and calls POST /api/admin/federated-accounts to create the link between your GitHub account and abbra@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.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  1. 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.

FileDescription
github.tomlServer config with GitHub upstream IdP stanza and __GITHUB_CLIENT_ID__ placeholders
users.tomlLocal 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