Altinity / Altinity/altinity-mcp

Add GitHub as OAuth Identity Provider

Open
#73 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
38
Forks
8
Avg merge
6d 14h
Merged PRs (30d)
8

Description

Problem

GitHub OAuth is not standard OIDC — it lacks .well-known/openid-configuration discovery, issues opaque access tokens (not JWTs), never returns an id_token, and uses non-standard user API claims (id/login instead of sub, no email_verified). The current OAuth implementation nearly supports GitHub via the fetchUserInfo fallback path, but four gaps prevent it from working end-to-end.

Why GitHub?

GitHub is one of the most widely used identity providers for developer tooling. Supporting it broadens the MCP server's audience, especially for teams already using GitHub for authentication across their infrastructure.

What doesn't work today

Gap Detail
Claim mapping GitHub's /user returns id (int) and login instead of OIDC-standard sub. oauthClaimsFromUserInfo produces an empty Subject.
Email verification GitHub's /user endpoint has no email_verified field. require_email_verified: true rejects all GitHub users. Verified email status requires a separate GET /user/emails call.
Private emails GitHub may return email: null when the user's email is private — again requiring /user/emails.
Accept headers Some GitHub API endpoints benefit from explicit Accept: application/json headers.

Proposed approach: generic enhancements (no GitHub-specific code)

All changes are provider-agnostic — no if provider == "github" anywhere. This benefits any future non-OIDC OAuth2 provider (Bitbucket, GitLab self-hosted, custom APIs).

1. New config fields in OAuthConfig (pkg/config/config.go)
Field Type Purpose
userinfo_claims_mapping map[string]string Maps upstream fields to standard OIDC claims (e.g., {"id": "sub", "login": "preferred_username"})
userinfo_email_url string Secondary endpoint for verified email (e.g., https://api.github.com/user/emails)
userinfo_accept_header string Accept header for userinfo requests
token_request_accept_header string Accept header for token exchange requests
2. Claim mapping in oauthClaimsFromUserInfo (cmd/altinity-mcp/oauth_server.go)
  • Add claimsMapping map[string]string parameter
  • Before extracting standard fields, apply mapping: copy raw[srcKey]raw[dstKey] if target not already set
  • Handle numeric id (float64) → string conversion for sub field
3. New helper: fetchVerifiedEmail
  • GET to userinfo_email_url with Authorization: Bearer {token}
  • Parses JSON array of {email, primary, verified} objects (GitHub's /user/emails format)
  • Returns first primary=true && verified=true email
4. Enhance fetchUserInfo
  • Add Accept header when userinfo_accept_header is configured
  • Pass userinfo_claims_mapping to claim extraction
  • After claim extraction, if email missing/unverified and userinfo_email_url configured, call fetchVerifiedEmail
5. Token exchange Accept header (handleOAuthCallback)
  • Replace PostForm with manual http.NewRequest to support configurable Accept header

GitHub config example

server:
  oauth:
    enabled: true
    mode: "gating"
    gating_secret_key: "<RANDOM_SECRET>"
    issuer: "https://github.com"
    client_id: "<GITHUB_CLIENT_ID>"
    client_secret: "<GITHUB_CLIENT_SECRET>"
    auth_url: "https://github.com/login/oauth/authorize"
    token_url: "https://github.com/login/oauth/access_token"
    userinfo_url: "https://api.github.com/user"
    userinfo_email_url: "https://api.github.com/user/emails"
    userinfo_accept_header: "application/json"
    token_request_accept_header: "application/json"
    scopes: ["user:email"]
    userinfo_claims_mapping:
      id: "sub"
      login: "preferred_username"
    require_email_verified: true

Note: Gating mode is required because GitHub issues opaque tokens that ClickHouse cannot validate directly.

Files to modify

  • pkg/config/config.go — Add 4 new OAuthConfig fields
  • cmd/altinity-mcp/oauth_server.go — Core logic (claim mapping, email fetch, Accept headers)
  • cmd/altinity-mcp/oauth_server_test.go — Unit + integration tests
  • docs/oauth_authorization.md — GitHub provider docs + general non-OIDC section
  • helm/altinity-mcp/values_examples/mcp-oauth-github.yaml — New Helm example

Test plan

  • Unit: claim mapping with/without config, numeric ID conversion, mapping doesn't overwrite existing fields, email fetch success/failure
  • Integration: mock GitHub-like upstream (opaque token, /user with id/login, /user/emails with verified array) — full callback flow
  • Regression: all existing OAuth tests pass unchanged (nil mapping = backward compatible)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with OAuthConfig in pkg/config/config.go and the OAuth flow in cmd/altinity-mcp/oauth_server.go, then run the existing oauth_server_test.go tests. Use the GitHub-like mock plan to cover claim mapping, verified-email lookup, configurable Accept headers, and backward compatibility. Done means the GitHub documentation and helm/altinity-mcp/values_examples/mcp-oauth-github.yaml example are included and all existing OAuth tests pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
github, go, helm
Domain
authentication, backend, devops, documentation
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.