Altinity / Altinity/altinity-mcp
Add GitHub as OAuth Identity Provider
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]stringparameter - Before extracting standard fields, apply mapping: copy
raw[srcKey]→raw[dstKey]if target not already set - Handle numeric
id(float64) → string conversion forsubfield
3. New helper: fetchVerifiedEmail
GETtouserinfo_email_urlwithAuthorization: Bearer {token}- Parses JSON array of
{email, primary, verified}objects (GitHub's/user/emailsformat) - Returns first
primary=true && verified=trueemail
4. Enhance fetchUserInfo
- Add
Acceptheader whenuserinfo_accept_headeris configured - Pass
userinfo_claims_mappingto claim extraction - After claim extraction, if email missing/unverified and
userinfo_email_urlconfigured, callfetchVerifiedEmail
5. Token exchange Accept header (handleOAuthCallback)
- Replace
PostFormwith manualhttp.NewRequestto support configurableAcceptheader
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 fieldscmd/altinity-mcp/oauth_server.go— Core logic (claim mapping, email fetch, Accept headers)cmd/altinity-mcp/oauth_server_test.go— Unit + integration testsdocs/oauth_authorization.md— GitHub provider docs + general non-OIDC sectionhelm/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,
/userwithid/login,/user/emailswith 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
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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