GitHub Auth + Org Membership
Overview
xbrain supports two authentication methods: Google OAuth (default) and GitHub OAuth. GitHub auth adds team membership verification via GitHub Organization membership — only members of your configured GitHub Org can access xbrain.
Both methods produce JWT sessions in LibreChat. The auth method is transparent to the memory-api interface — the same API endpoints work regardless of how the user authenticated.
Authentication Methods
| Method | Provider | User ID format | Org restriction |
|---|---|---|---|
| Google OAuth | Google SSO | google:{sub} |
No |
| GitHub OAuth | GitHub | github:{login} |
Yes (optional, via GITHUB_ORG) |
Both methods use the same session mechanism. A user authenticated with Google and the same person authenticated with GitHub are treated as separate user records in xbrain unless account linking is configured (see below).
GitHub OAuth Setup
Step 1 — Create GitHub OAuth App
In your GitHub organization settings: Settings → Developer settings → OAuth Apps → New OAuth App
- Application name: xbrain
- Homepage URL:
https://your-domain - Authorization callback URL:
https://your-domain/oauth/github/callback
Step 2 — Configure LibreChat
Add the GitHub OAuth credentials to LibreChat's environment:
infrastructure/.envGITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
LibreChat will display a "Sign in with GitHub" button on the login page alongside the existing "Sign in with Google" button.
Step 3 — Configure Org verification in memory-api
infrastructure/.envGITHUB_ORG=your-github-org-name # e.g. "excalibur-game"
GITHUB_API_PAT=ghp_... # Personal Access Token with read:org scope
Org restriction
Set GITHUB_ORG to restrict access to org members only. If left empty,
any GitHub user can authenticate successfully. The GITHUB_API_PAT must
have read:org permission to check organization membership via the GitHub API.
How Org Membership Verification Works
When a user authenticates with GitHub, memory-api detects the token type by its prefix and verifies org membership before granting access:
User clicks "Sign in with GitHub" in LibreChat
│
▼
GitHub OAuth → returns gho_ prefixed access token
│
▼
memory-api detects token prefix (gho_) → GitHub auth path
│
▼
GET https://api.github.com/orgs/{GITHUB_ORG}/members/{login}
using GITHUB_API_PAT
│
┌───┴───┐
│ 204 │ 404
▼ ▼
Allow Return 403
(github_is_org_member=True) (not an org member)
The gho_ prefix is the standard prefix for GitHub OAuth user access tokens.
Detecting it requires no additional API call — memory-api routes the token to the GitHub
verification path immediately upon seeing the prefix.
Database Schema
GitHub user data is stored in the users table. Migration 0007 (Alembic) adds
the GitHub-specific columns:
sql — migration 0007-- Migration 0007 adds GitHub identity columns:
ALTER TABLE users ADD COLUMN github_username VARCHAR(255);
ALTER TABLE users ADD COLUMN github_id BIGINT;
-- github_is_org_member uses three-state logic:
-- True → verified org member (GitHub user, check passed)
-- False → not an org member (GitHub user, check failed)
-- None → not applicable (Google user — NOT False)
--
-- This allows: if user.github_is_org_member is False: reject
-- Without accidentally blocking Google users (who have NULL)
Three-state logic
github_is_org_member=None (NULL) is the correct value for Google-authenticated
users — not False. This distinction prevents a naive if not github_is_org_member
check from blocking all Google users. Always use explicit is False comparison
when checking org membership.
User Identity
GitHub users are identified by their login handle. The source_user_id format
is github:{login}:
python# Example GitHub user identity
source_user_id = "github:mrboups"
github_username = "mrboups"
github_id = 12345678 # GitHub numeric user ID
# Note: GitHub email can be null if the user has hidden their email
# xbrain uses github:{login} as the stable identifier, not email.
# Email is stored only when GitHub returns it in the OAuth response.
Account Linking
A user can sign in with both Google AND GitHub. Each creates a separate user record in xbrain's database. The two identities are not automatically merged.
bash# Check the identity of a GitHub-authenticated user
curl "https://api.grooveos.app/v1/me" \
-H "Authorization: Bearer $GITHUB_JWT"
# Returns: {"source_user_id": "github:mrboups", "github_username": "mrboups", ...}
# The same physical person with Google auth would return:
# {"source_user_id": "google:115...", "github_username": null, ...}
Future enhancement
Automatic account linking — merging Google and GitHub identities into a single user record — is a planned future enhancement. For now, each auth method creates a separate record and the user's memory entries are scoped to that identity. Manual linking can be done via direct database update by an admin.
Security Notes
-
Token detection: GitHub tokens are detected by the
gho_prefix — no additional API call is required to determine the token type. -
PAT storage:
GITHUB_API_PATis stored as an environment variable on the VM. It is never written to the database or returned in API responses. -
Membership caching: Org membership is verified at login time only.
The result is stored in
github_is_org_memberand cached for the session duration. No per-request GitHub API call is made. -
Null safety:
github_is_org_member=Nonefor Google users prevents accidental access restriction on non-GitHub auth paths. -
GITHUB_ORG env var: Set to your org slug (e.g.
excalibur-game). If unset, GitHub OAuth works but without org restriction.