GitHub OAuth Setup
This guide explains how to configure and use GitHub OAuth authentication in llms.py to secure your web UI and API endpoints.
Overview
Section titled “Overview”The llms.py application supports GitHub OAuth 2.0 authentication, allowing users to sign in with their GitHub account before accessing the application.
Features
Section titled “Features”- ✅ GitHub OAuth 2.0 integration
- ✅ Secure session management
- ✅ CSRF protection with state tokens
- ✅ User profile display with avatar
- ✅ Logout functionality
- ✅ Configurable authentication type
- ✅ Environment variable support for credentials
- ✅ Optional user access restrictions
Setup Instructions
Section titled “Setup Instructions”1. Create a GitHub OAuth App
Section titled “1. Create a GitHub OAuth App”- Go to GitHub Settings → Developer settings → OAuth Apps
- Click “New OAuth App”
- Fill in the application details:
- Application name:
llms.py(or your preferred name) - Homepage URL:
http://localhost:8080 - Authorization callback URL:
http://localhost:8080/auth/github/callback
- Application name:
- Click “Register application”
- Note down your Client ID
- Click “Generate a new client secret” and note down the Client Secret
2. Configure Environment Variables
Section titled “2. Configure Environment Variables”Set the following environment variables with your GitHub OAuth credentials:
export GITHUB_CLIENT_ID="your_github_client_id_here"export GITHUB_CLIENT_SECRET="your_github_client_secret_here"Optional: Restrict Access to Specific Users
Section titled “Optional: Restrict Access to Specific Users”To restrict access to specific GitHub users, set a comma or space-separated list:
export GITHUB_USERS="octocat mythz"If this variable is set, only the listed users will be able to access llms.py after authentication.
Make Permanent
Section titled “Make Permanent”For permanent configuration, add these to your shell profile (~/.bashrc, ~/.zshrc, etc.):
# GitHub OAuth Configurationexport GITHUB_CLIENT_ID="your_github_client_id_here"export GITHUB_CLIENT_SECRET="your_github_client_secret_here"export GITHUB_USERS="octocat mythz"Then reload your shell:
source ~/.bashrc # or ~/.zshrc3. Configuration in llms.json
Section titled “3. Configuration in llms.json”Enable the OAuth configuration in ~/.llms/llms.json:
{ "auth": { "enabled": true, "github": { "client_id": "$GITHUB_CLIENT_ID", "client_secret": "$GITHUB_CLIENT_SECRET", "redirect_uri": "http://localhost:8080/auth/github/callback" } }}Note: The $ prefix indicates environment variables. The values will be automatically expanded at runtime.
Starting the Server
Section titled “Starting the Server”llms --serve 8000Or if running from the repository:
./llms.sh --serve 8000Signing In
Section titled “Signing In”- Navigate to
http://localhost:8080 - Click “Sign in with GitHub”
- Authorize the application on GitHub
- You’ll be redirected back to the application, now authenticated
Signing Out
Section titled “Signing Out”- Click on your avatar in the top-right corner
- A dropdown menu will appear showing your profile info
- Click “Sign Out”
Disabling Authentication
Section titled “Disabling Authentication”To disable authentication, update llms.json:
{ "auth": { "enabled": false, "github": { "client_id": "$GITHUB_CLIENT_ID", "client_secret": "$GITHUB_CLIENT_SECRET", "redirect_uri": "http://localhost:8080/auth/github/callback" } }}Architecture
Section titled “Architecture”Server-Side (Python)
Section titled “Server-Side (Python)”New Endpoints:
GET /auth/github- Initiates GitHub OAuth flowGET /auth/github/callback- Handles OAuth callbackGET /auth/session- Validates session tokenPOST /auth/logout- Ends user session
Session Management:
- Sessions stored in-memory (
g_sessionsdictionary) - Session tokens are 32-byte URL-safe random strings
- Sessions expire after 24 hours
- CSRF protection using state tokens (expire after 10 minutes)
Client-Side (JavaScript)
Section titled “Client-Side (JavaScript)”New Components:
OAuthSignIn.mjs- OAuth sign-in UI component- Updated
Avatar.mjs- Profile display with logout dropdown - Updated
ai.mjs- OAuth methods and session handling - Updated
Main.mjs- Conditional sign-in component rendering
Authentication Flow:
- User clicks “Sign in with GitHub”
- Redirected to
/auth/github - Server redirects to GitHub OAuth authorization
- User authorizes on GitHub
- GitHub redirects to
/auth/github/callbackwith code - Server exchanges code for access token
- Server fetches user info from GitHub API
- Server creates session and redirects to
/?session=TOKEN - Client validates session and stores user info
- User is authenticated
Security Considerations
Section titled “Security Considerations”CSRF Protection
Section titled “CSRF Protection”- State tokens are generated for each OAuth flow
- State tokens are validated on callback
- Expired state tokens (>10 minutes) are automatically cleaned up
Session Security
Section titled “Session Security”- Session tokens are cryptographically random (32 bytes)
- Sessions expire after 24 hours
- Expired sessions are automatically cleaned up
- Session tokens are transmitted via URL parameter (initial) and HTTP header (subsequent requests)
Environment Variables
Section titled “Environment Variables”- OAuth credentials are stored in environment variables
- Never commit credentials to version control
- Use
$VAR_NAMEsyntax in config files for automatic expansion
Production Deployment
Section titled “Production Deployment”For production deployment, update the following:
-
Change redirect_uri in
llms.json:{"auth": {"github": {"redirect_uri": "https://yourdomain.com/auth/github/callback"}}} -
Update GitHub OAuth App callback URL to match your production domain
-
Use HTTPS for secure token transmission
-
Consider persistent session storage (Redis, database) instead of in-memory storage
-
Set appropriate session expiration based on your security requirements
Using Docker
Section titled “Using Docker”Pass environment variables to Docker:
docker run -p 8000:8000 \ -e GITHUB_CLIENT_ID="your_client_id" \ -e GITHUB_CLIENT_SECRET="your_client_secret" \ -e GITHUB_USERS="username1,username2" \ -e GROQ_API_KEY="your_groq_key" \ ghcr.io/servicestack/llms:latestUsing Docker Compose
Section titled “Using Docker Compose”Create .env file:
GITHUB_CLIENT_ID=your_client_idGITHUB_CLIENT_SECRET=your_client_secretGITHUB_USERS=username1,username2GROQ_API_KEY=your_groq_keyUpdate docker-compose.yml:
version: '3.8'
services: llms: image: ghcr.io/servicestack/llms:latest ports: - "8000:8000" environment: - GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID} - GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET} - GITHUB_USERS=${GITHUB_USERS} - GROQ_API_KEY=${GROQ_API_KEY} volumes: - llms-data:/home/llms/.llms restart: unless-stopped
volumes: llms-data:Start:
docker-compose up -dTroubleshooting
Section titled “Troubleshooting””GitHub OAuth not configured” error
Section titled “”GitHub OAuth not configured” error”- Ensure
GITHUB_CLIENT_IDandGITHUB_CLIENT_SECRETenvironment variables are set - Restart the server after setting environment variables
”Invalid state parameter” error
Section titled “”Invalid state parameter” error”- This can happen if the OAuth flow takes longer than 10 minutes
- Try the sign-in process again
”Invalid or expired session” error
Section titled “”Invalid or expired session” error”- Your session may have expired (24-hour limit)
- Sign in again to create a new session
Callback URL mismatch
Section titled “Callback URL mismatch”- Ensure the
redirect_uriinllms.jsonmatches exactly what you configured in GitHub OAuth App settings - Default is
http://localhost:8080/auth/github/callback - For production:
https://yourdomain.com/auth/github/callback
Access Denied
Section titled “Access Denied”Error: User authenticated but can’t access
Solution: Check GITHUB_USERS includes the username:
echo $GITHUB_USERSEnvironment Variables Not Loaded
Section titled “Environment Variables Not Loaded”Solution: Verify variables are set:
echo $GITHUB_CLIENT_IDecho $GITHUB_CLIENT_SECRETRestart llms.py after setting variables.
API Reference
Section titled “API Reference”Session Data Structure
Section titled “Session Data Structure”{ "userId": "12345678", "userName": "octocat", "displayName": "The Octocat", "profileUrl": "https://avatars.githubusercontent.com/u/583231", "sessionToken": "abc123...", "created": 1234567890.123}HTTP Headers
Section titled “HTTP Headers”For authenticated requests:
X-Session-Token: <session_token>Files Modified
Section titled “Files Modified”The following files were modified to implement GitHub OAuth:
llms/llms.json- Added auth configurationllms/main.py- Added OAuth endpoints and session managementllms/ui/ai.mjs- Added OAuth methods and authType configllms/ui/OAuthSignIn.mjs- New OAuth sign-in componentllms/ui/Main.mjs- Conditional sign-in component renderingllms/ui/Avatar.mjs- Added logout functionality
Security Best Practices
Section titled “Security Best Practices”-
Use HTTPS in Production: Always use HTTPS for production deployments
-
Keep Secrets Secret: Never commit client secrets to version control
-
Rotate Secrets: Periodically regenerate client secrets
-
Restrict Access: Use
GITHUB_USERSto limit access to trusted users -
Monitor Access: Check logs for unauthorized access attempts
-
Session Expiration: Consider adjusting session timeout based on your security requirements
Next Steps
Section titled “Next Steps”- Docker Deployment - Deploy with Docker
- Configuration - Advanced configuration
- Web UI - Explore UI features
- Troubleshooting - Common issues and solutions