GitHub Auth + Org Membership

Phase 5 GitHub OAuth + Org verification Migration 0007

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

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