Files
GearBox/docs/authentication.md
Jean-Luc Makiola 3906273a10
Some checks failed
CI / ci (push) Failing after 18s
CI / e2e (push) Has been skipped
CI / deploy (push) Has been skipped
docs: update authentication.md with Logto setup checklist
2026-04-12 20:31:45 +02:00

184 lines
6.6 KiB
Markdown

# Authentication
GearBox uses a public-read, authenticated-write model. All GET endpoints are publicly accessible. Any request that modifies data (POST, PUT, PATCH, DELETE) requires authentication.
## Table of Contents
- [Overview](#overview)
- [OIDC Authentication (Logto)](#oidc-authentication-logto)
- [Logto Setup Checklist](#logto-setup-checklist)
- [API Keys](#api-keys)
- [Account Management](#account-management)
- [Auth Middleware Behavior](#auth-middleware-behavior)
- [Frontend Behavior](#frontend-behavior)
---
## Overview
Authentication is handled by [Logto](https://logto.io/), a self-hosted open-source OIDC provider. Users register and log in through Logto's sign-in experience. GearBox validates OIDC sessions and provides in-app account management via the Logto Management API.
**Auth methods:**
- **Browser sessions** — OIDC via Logto (redirect flow)
- **API keys** — `X-API-Key` header for programmatic access (MCP, scripts)
- **OAuth 2.1 + PKCE** — for Claude mobile/web MCP connections
---
## OIDC Authentication (Logto)
### Required Environment Variables
```bash
OIDC_ISSUER=https://your-logto-domain/oidc # Logto OIDC issuer URL
OIDC_CLIENT_ID=<client-id> # From Logto app settings
OIDC_CLIENT_SECRET=<client-secret> # From Logto app settings
OIDC_AUTH_SECRET=<random-32-char-hex> # Session encryption key
OIDC_SCOPES="openid profile email" # Must match Logto app scopes
OIDC_REDIRECT_URI=https://your-app/callback # Must match Logto redirect URI
```
### Management API (M2M)
GearBox uses the Logto Management API for in-app account management (password change, email change, account deletion). This requires a Machine-to-Machine (M2M) application in Logto.
```bash
LOGTO_MANAGEMENT_API_ENDPOINT=https://your-logto-domain # Logto base URL
LOGTO_M2M_APP_ID=<m2m-app-id> # From Logto M2M app
LOGTO_M2M_APP_SECRET=<m2m-app-secret> # From Logto M2M app
```
---
## Logto Setup Checklist
Complete these steps in the Logto admin console after deployment.
### Application Setup
- [ ] Create a **Traditional Web** application in Logto Console
- [ ] Set redirect URI to `https://your-app/callback`
- [ ] Note the Client ID and Client Secret for env vars
- [ ] Grant user scopes: `openid`, `profile`, `email`
### Machine-to-Machine (M2M) Application
- [ ] Create an **M2M** application in Logto Console
- [ ] Grant access to the **Logto Management API** resource
- [ ] Note the M2M App ID and Secret for env vars
### Branding & Sign-in Experience
- [ ] Upload GearBox logo in Logto Console > Sign-in Experience > Branding
- [ ] Set primary brand color to match GearBox (`gray-700` / `#374151`)
- [ ] Set background color to white
- [ ] Customize sign-in page text if desired
- [ ] (Optional) Configure custom domain `auth.gearbox.de` in Logto Console > Settings
### Social Connectors
- [ ] Add **Google** connector in Logto Console > Connectors > Social
- Create OAuth 2.0 credentials in Google Cloud Console
- Set authorized redirect URI to Logto's callback URL
- [ ] Add **GitHub** connector in Logto Console > Connectors > Social
- Create OAuth App in GitHub Developer Settings
- Set authorization callback URL to Logto's callback URL
- [ ] Enable both connectors in the Sign-in Experience
### Email Verification & Password Policy
- [ ] Enable **mandatory email verification** at signup in Logto Console > Sign-up settings
- [ ] Set password policy: minimum 8 characters, require mixed case, require at least one number
- Logto Console > Sign-in Experience > Password policy
### Verification
After completing the checklist:
- [ ] Visit `/login` — GearBox logo and colors appear on Logto sign-in page
- [ ] Google and GitHub sign-in buttons are visible
- [ ] Create a new account — email verification is required before access
- [ ] Try a weak password (e.g., "abc") — rejected by policy
- [ ] Log in — redirected back to GearBox with session active
---
## API Keys
API keys provide programmatic access for scripts, MCP clients, and integrations. Managed in **Settings > API Keys**.
### Key behavior
- Keys are shown **once** at creation time. Store them securely.
- Keys are stored as a hash. Only the 8-character prefix is kept for display.
- Pass the key via the `X-API-Key` header.
```http
POST /api/items
X-API-Key: gbk_a1b2c3d4...
Content-Type: application/json
{ "name": "Revelate Tangle", "categoryId": 2 }
```
### API Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/auth/keys` | List all API keys (name, prefix, date) |
| `POST` | `/api/auth/keys` | Create a new key (returns full key once) |
| `DELETE` | `/api/auth/keys/:id` | Revoke a key |
---
## Account Management
All account management happens within GearBox — users never interact with Logto directly.
### Profile (`/profile`)
The profile page has four sections:
1. **Profile Info** — display name, bio, avatar (editable)
2. **Account Info** — email (editable via Logto Management API), member-since date
3. **Security** — change password
4. **Danger Zone** — delete account
### API Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/auth/me` | Current session state (user, email, createdAt) |
| `PUT` | `/api/auth/profile` | Update display name, bio, avatar |
| `POST` | `/api/account/password` | Change password (requires current password) |
| `POST` | `/api/account/email` | Change email (updates Logto) |
| `DELETE` | `/api/account` | Delete account (anonymizes public content) |
### Account Deletion
When a user deletes their account:
- Personal items, threads, and private data are deleted
- Public setups and catalog contributions are preserved, attributed to "Deleted User"
- User is removed from Logto
---
## Auth Middleware Behavior
The middleware on `/api/*` (excluding `/api/auth/*` and `/api/account/*`) follows:
1. `GET` requests — always allowed, no auth check
2. `X-API-Key` header present — verified against stored hashes
3. `Authorization: Bearer` header present — verified as OAuth token
4. OIDC session cookie present — validated via `@hono/oidc-auth`
5. No credentials — returns `401 { "error": "Authentication required" }`
---
## Frontend Behavior
- Anonymous visitors see all public content (catalog, public setups, profiles, discovery feed)
- A "Sign in" button appears in the top nav for anonymous users
- Write actions (add to collection, create thread, etc.) show an auth prompt modal
- The floating action button (FAB) is hidden when not authenticated
- Authenticated users see their avatar in the top nav with a dropdown menu linking to Profile and Settings