Skip to content

Commit 5a0df98

Browse files
committed
Add support for GitHub OAuth
1 parent b72c20c commit 5a0df98

10 files changed

Lines changed: 764 additions & 18 deletions

File tree

GITHUB_OAUTH_SETUP.md

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
# GitHub OAuth Setup Guide
2+
3+
This guide explains how to configure and use GitHub OAuth authentication in llms.py.
4+
5+
## Overview
6+
7+
The llms.py application now supports:
8+
1. **OAuth Authentication** (default) - Sign in with GitHub
9+
10+
## Features
11+
12+
- ✅ GitHub OAuth 2.0 integration
13+
- ✅ Secure session management
14+
- ✅ CSRF protection with state tokens
15+
- ✅ User profile display with avatar
16+
- ✅ Logout functionality
17+
- ✅ Configurable authentication type
18+
- ✅ Environment variable support for credentials
19+
20+
## Setup Instructions
21+
22+
### 1. Create a GitHub OAuth App
23+
24+
1. Go to GitHub Settings → Developer settings → OAuth Apps
25+
2. Click "New OAuth App"
26+
3. Fill in the application details:
27+
- **Application name**: `llms.py` (or your preferred name)
28+
- **Homepage URL**: `http://localhost:8080`
29+
- **Authorization callback URL**: `http://localhost:8080/auth/github/callback`
30+
4. Click "Register application"
31+
5. Note down your **Client ID**
32+
6. Click "Generate a new client secret" and note down the **Client Secret**
33+
34+
### 2. Configure Environment Variables
35+
36+
Set the following environment variables with your GitHub OAuth credentials:
37+
38+
```bash
39+
export GITHUB_CLIENT_ID="your_github_client_id_here"
40+
export GITHUB_CLIENT_SECRET="your_github_client_secret_here"
41+
```
42+
43+
For permanent configuration, add these to your shell profile (`~/.bashrc`, `~/.zshrc`, etc.).
44+
45+
### 3. Configuration in llms.json
46+
47+
Enable the OAuth configuration that's included in `llms/llms.json`:
48+
49+
```json
50+
{
51+
"auth": {
52+
"enabled": true,
53+
"github": {
54+
"client_id": "$GITHUB_CLIENT_ID",
55+
"client_secret": "$GITHUB_CLIENT_SECRET",
56+
"redirect_uri": "http://localhost:8080/auth/github/callback"
57+
}
58+
},
59+
...
60+
}
61+
```
62+
63+
**Note**: The `$` prefix indicates environment variables. The values will be automatically expanded at runtime.
64+
65+
## Usage
66+
67+
### Starting the Server
68+
69+
```bash
70+
llms --serve 8000
71+
```
72+
73+
Or if running from the repository:
74+
75+
```bash
76+
./llms.sh --serve 8000
77+
```
78+
79+
### Signing In
80+
81+
1. Navigate to `http://localhost:8080`
82+
2. Click "Sign in with GitHub"
83+
3. Authorize the application on GitHub
84+
4. You'll be redirected back to the application, now authenticated
85+
86+
### Signing Out
87+
88+
1. Click on your avatar in the top-right corner
89+
2. A dropdown menu will appear showing your profile info
90+
3. Click "Sign Out"
91+
92+
### To disable authentication:
93+
94+
Disable authentication in `llms.json`:
95+
96+
```json
97+
"auth": {
98+
"enabled": false,
99+
"github": {
100+
"client_id": "$GITHUB_CLIENT_ID",
101+
"client_secret": "$GITHUB_CLIENT_SECRET",
102+
"redirect_uri": "http://localhost:8080/auth/github/callback"
103+
}
104+
}
105+
```
106+
107+
## Architecture
108+
109+
### Server-Side (Python)
110+
111+
**New Endpoints:**
112+
- `GET /auth/github` - Initiates GitHub OAuth flow
113+
- `GET /auth/github/callback` - Handles OAuth callback
114+
- `GET /auth/session` - Validates session token
115+
- `POST /auth/logout` - Ends user session
116+
117+
**Session Management:**
118+
- Sessions stored in-memory (`g_sessions` dictionary)
119+
- Session tokens are 32-byte URL-safe random strings
120+
- Sessions expire after 24 hours
121+
- CSRF protection using state tokens (expire after 10 minutes)
122+
123+
### Client-Side (JavaScript)
124+
125+
**New Components:**
126+
- `OAuthSignIn.mjs` - OAuth sign-in UI component
127+
- Updated `Avatar.mjs` - Profile display with logout dropdown
128+
- Updated `ai.mjs` - OAuth methods and session handling
129+
- Updated `Main.mjs` - Conditional sign-in component rendering
130+
131+
**Authentication Flow:**
132+
1. User clicks "Sign in with GitHub"
133+
2. Redirected to `/auth/github`
134+
3. Server redirects to GitHub OAuth authorization
135+
4. User authorizes on GitHub
136+
5. GitHub redirects to `/auth/github/callback` with code
137+
6. Server exchanges code for access token
138+
7. Server fetches user info from GitHub API
139+
8. Server creates session and redirects to `/?session=TOKEN`
140+
9. Client validates session and stores user info
141+
10. User is authenticated
142+
143+
## Security Considerations
144+
145+
### CSRF Protection
146+
- State tokens are generated for each OAuth flow
147+
- State tokens are validated on callback
148+
- Expired state tokens (>10 minutes) are automatically cleaned up
149+
150+
### Session Security
151+
- Session tokens are cryptographically random (32 bytes)
152+
- Sessions expire after 24 hours
153+
- Expired sessions are automatically cleaned up
154+
- Session tokens are transmitted via URL parameter (initial) and HTTP header (subsequent requests)
155+
156+
### Environment Variables
157+
- OAuth credentials are stored in environment variables
158+
- Never commit credentials to version control
159+
- Use `$VAR_NAME` syntax in config files for automatic expansion
160+
161+
## Troubleshooting
162+
163+
### "GitHub OAuth not configured" error
164+
- Ensure `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET` environment variables are set
165+
- Restart the server after setting environment variables
166+
167+
### "Invalid state parameter" error
168+
- This can happen if the OAuth flow takes longer than 10 minutes
169+
- Try the sign-in process again
170+
171+
### "Invalid or expired session" error
172+
- Your session may have expired (24-hour limit)
173+
- Sign in again to create a new session
174+
175+
### Callback URL mismatch
176+
- Ensure the redirect_uri in `llms.json` matches exactly what you configured in GitHub OAuth App settings
177+
- Default is `http://localhost:8080/auth/github/callback`
178+
179+
## Production Deployment
180+
181+
For production deployment, update the following:
182+
183+
1. **Change redirect_uri** in `llms.json`:
184+
```json
185+
"redirect_uri": "https://yourdomain.com/auth/github/callback"
186+
```
187+
188+
2. **Update GitHub OAuth App** callback URL to match
189+
190+
3. **Use HTTPS** for secure token transmission
191+
192+
4. **Consider persistent session storage** (Redis, database) instead of in-memory storage
193+
194+
5. **Set appropriate session expiration** based on your security requirements
195+
196+
## Files Modified
197+
198+
- `llms/llms.json` - Added auth configuration
199+
- `llms/main.py` - Added OAuth endpoints and session management
200+
- `llms/ui/ai.mjs` - Added OAuth methods and authType config
201+
- `llms/ui/OAuthSignIn.mjs` - New OAuth sign-in component
202+
- `llms/ui/Main.mjs` - Conditional sign-in component rendering
203+
- `llms/ui/Avatar.mjs` - Added logout functionality
204+
205+
## API Reference
206+
207+
### Session Data Structure
208+
209+
```javascript
210+
{
211+
"userId": "12345678",
212+
"userName": "octocat",
213+
"displayName": "The Octocat",
214+
"profileUrl": "https://avatars.githubusercontent.com/u/583231",
215+
"email": "octocat@github.com",
216+
"sessionToken": "abc123...",
217+
"created": 1234567890.123
218+
}
219+
```
220+
221+
### HTTP Headers
222+
223+
**For authenticated requests:**
224+
```
225+
X-Session-Token: <session_token>
226+
```

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ After the container starts, you can access the UI and API at `http://localhost:8
186186

187187
See [DOCKER.md](DOCKER.md) for detailed instructions on customizing configuration files.
188188

189+
## GitHub OAuth Authentication
190+
191+
llms.py supports optional GitHub OAuth authentication to secure your web UI and API endpoints. When enabled, users must sign in with their GitHub account before accessing the application.
192+
193+
See [GITHUB_OAUTH_SETUP.md](GITHUB_OAUTH_SETUP.md) for detailed setup instructions.
194+
189195
## Configuration
190196

191197
The configuration file [llms.json](llms/llms.json) is saved to `~/.llms/llms.json` and defines available providers, models, and default settings. Key sections:

llms/llms.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
{
2+
"auth": {
3+
"enabled": true,
4+
"github": {
5+
"client_id": "$GITHUB_CLIENT_ID",
6+
"client_secret": "$GITHUB_CLIENT_SECRET",
7+
"redirect_uri": "http://localhost:8000/auth/github/callback"
8+
}
9+
},
210
"defaults": {
311
"headers": {
412
"Content-Type": "application/json",

0 commit comments

Comments
 (0)