Files
TimeTracker/docs/admin/configuration/OIDC_SETUP.md
T
Dries Peeters 29f7186ee8 docs: Reorganize documentation structure for better navigation
Complete reorganization of project documentation to improve discoverability,
navigation, and maintainability. All documentation has been restructured into
a clear, role-based hierarchy.

## Major Changes

### New Directory Structure
- Created `docs/api/` for API documentation
- Created `docs/admin/` with subdirectories:
  - `admin/configuration/` - Configuration guides
  - `admin/deployment/` - Deployment guides
  - `admin/security/` - Security documentation
  - `admin/monitoring/` - Monitoring and analytics
- Created `docs/development/` for developer documentation
- Created `docs/guides/` for user-facing guides
- Created `docs/reports/` for analysis reports and summaries
- Created `docs/changelog/` for detailed changelog entries (ready for future use)

### File Organization

#### Moved from Root Directory (40+ files)
- Implementation notes → `docs/implementation-notes/`
- Test reports → `docs/testing/`
- Analysis reports → `docs/reports/`
- User guides → `docs/guides/`

#### Reorganized within docs/
- API documentation → `docs/api/`
- Administrator documentation → `docs/admin/` (with subdirectories)
- Developer documentation → `docs/development/`
- Security documentation → `docs/admin/security/`
- Telemetry documentation → `docs/admin/monitoring/`

### Documentation Updates

#### docs/README.md
- Complete rewrite with improved navigation
- Added visual documentation map
- Organized by role (Users, Administrators, Developers)
- Better categorization and quick links
- Updated all internal links to new structure

#### README.md (root)
- Updated all documentation links to reflect new structure
- Fixed 8 broken links

#### app/templates/main/help.html
- Enhanced "Where can I get additional help?" section
- Added links to new documentation structure
- Added documentation index link
- Added admin documentation link for administrators
- Improved footer with organized documentation links
- Added "Complete Documentation" section with role-based links

### New Index Files
- Created README.md files for all new directories:
  - `docs/api/README.md`
  - `docs/guides/README.md`
  - `docs/reports/README.md`
  - `docs/development/README.md`
  - `docs/admin/README.md`

### Cleanup
- Removed empty `docs/security/` directory (moved to `admin/security/`)
- Removed empty `docs/telemetry/` directory (moved to `admin/monitoring/`)
- Root directory now only contains: README.md, CHANGELOG.md, LICENSE

## Results

**Before:**
- 45+ markdown files cluttering root directory
- Documentation scattered across root and docs/
- Difficult to find relevant documentation
- No clear organization structure

**After:**
- 3 files in root directory (README, CHANGELOG, LICENSE)
- Clear directory structure organized by purpose and audience
- Easy navigation with role-based organization
- All documentation properly categorized
- Improved discoverability

## Benefits

1. Better Organization - Documentation grouped by purpose and audience
2. Easier Navigation - Role-based sections (Users, Admins, Developers)
3. Improved Discoverability - Clear structure with README files in each directory
4. Cleaner Root - Only essential files at project root
5. Maintainability - Easier to add and organize new documentation

## Files Changed

- 40+ files moved from root to appropriate docs/ subdirectories
- 15+ files reorganized within docs/
- 3 major documentation files updated (docs/README.md, README.md, help.html)
- 5 new README index files created
- 2 empty directories removed

All internal links have been updated to reflect the new structure.
2025-12-14 07:56:07 +01:00

203 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## OpenID Connect (OIDC) Setup Guide
This guide explains how to enable Single Sign-On (SSO) with OpenID Connect for TimeTracker. OIDC is optional; you can run with local login only, OIDC only, or both.
### Quick Summary
- Set `AUTH_METHOD=oidc` (SSO only) or `AUTH_METHOD=both` (SSO + local password authentication).
- Configure `OIDC_ISSUER`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, and `OIDC_REDIRECT_URI`.
- Optional: Configure admin mapping via `OIDC_ADMIN_GROUP` or `OIDC_ADMIN_EMAILS`.
- Restart the app. The login page will show an “Sign in with SSO” button when enabled.
### Prerequisites
- A running TimeTracker instance (Docker or local).
- An OIDC provider (e.g., Azure AD, Okta, Keycloak, Auth0, Google Workspace).
- A client application registered at your IdP with Authorization Code flow enabled.
### 1) Application URLs
You will need these URLs when creating the OIDC client at your Identity Provider:
- Authorization callback (Redirect URI):
- `https://<your-app-host>/auth/oidc/callback`
- Post-logout redirect (optional):
- `https://<your-app-host>/`
Make sure your external URL and protocol (HTTP/HTTPS) match how users access the app. Behind a reverse proxy, ensure the proxy sets `X-Forwarded-Proto` so redirects/cookies work correctly.
### 2) Required Environment Variables
Add these to your environment (e.g., `.env`, Docker Compose, or Kubernetes Secrets):
```
AUTH_METHOD=oidc # Options: none | local | oidc | both (see section 5 for details)
# Core OIDC settings
OIDC_ISSUER=https://idp.example.com/realms/your-realm
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret
OIDC_REDIRECT_URI=https://your-app.example.com/auth/oidc/callback
# Scopes and claims (defaults are usually fine)
OIDC_SCOPES=openid profile email
OIDC_USERNAME_CLAIM=preferred_username
OIDC_FULL_NAME_CLAIM=name
OIDC_EMAIL_CLAIM=email
OIDC_GROUPS_CLAIM=groups
# Optional admin mapping
OIDC_ADMIN_GROUP=timetracker-admins # If your IdP issues a groups claim
OIDC_ADMIN_EMAILS=alice@company.com,bob@company.com
# Optional: RP-Initiated Logout (set only if your provider supports end_session_endpoint)
# If unset, users will be logged out locally and redirected to TimeTracker's login page.
# If set, TimeTracker will redirect to the provider's logout endpoint after local logout.
OIDC_POST_LOGOUT_REDIRECT_URI=https://your-app.example.com/
```
Also ensure the standard app settings are configured (database, secret key, etc.). See `env.example` for a complete template.
### 3) Provider-Specific Notes
- Azure AD (Entra ID)
- Issuer: `https://login.microsoftonline.com/<tenant-id>/v2.0`
- Use `openid profile email` scopes.
- Preferred username commonly available via `preferred_username` or `upn`.
- Group claims may need to be enabled in App Registration → Token configuration.
- Okta
- Issuer: `https://<yourOktaDomain>/oauth2/default`
- Add claims for `groups` if you want role mapping by group.
- Keycloak
- Issuer: `https://<keycloak>/realms/<realm>`
- You can map custom claims and groups in the realm client.
- Google Workspace
- Issuer: `https://accounts.google.com`
- Groups generally not available by default; prefer admin mapping via emails.
### 4) Behavior and Mapping
- When a user completes SSO:
- We parse ID token and/or fetch userinfo to get `preferred_username`, `name`, `email` and optional `groups`.
- We upsert a local user record with `username`, `full_name`, `email`, and store OIDC linkage in `oidc_issuer` + `oidc_sub`.
- If `ALLOW_SELF_REGISTER=true` (default), unknown users are created on first login; otherwise theyre blocked.
- Admin role can be granted if users groups contains `OIDC_ADMIN_GROUP` or if users email is in `OIDC_ADMIN_EMAILS`.
### 5) Authentication Methods
The `AUTH_METHOD` environment variable controls how users authenticate with TimeTracker. It supports four options:
#### Available Options
1. **`none`** - No password authentication (username only)
- Users log in with just their username, no password required
- No password field shown on login page
- Useful for trusted internal networks or development environments
- Self-registration works (users can create accounts by entering any username)
- **Note:** This is the least secure option and should only be used in trusted environments
2. **`local`** - Password authentication required (default)
- Users must set and use a password to log in
- Password field is shown on login page
- Users without passwords are prompted to set one in their profile
- Passwords can be changed in user profile settings
- Self-registration works (new users must provide a password during registration)
- Works for both regular login and kiosk mode
- **Note:** This is the recommended option for most installations
3. **`oidc`** - OIDC/Single Sign-On only
- Users authenticate via your OIDC provider (e.g., Azure AD, Okta, Keycloak)
- Local login form is hidden
- `/login` redirects directly to OIDC login
- Requires OIDC configuration (see Required Environment Variables above)
- Self-registration still works if `ALLOW_SELF_REGISTER=true` (users created on first OIDC login)
4. **`both`** - OIDC + Local password authentication
- Shows both SSO button and local login form
- Users can choose to log in with OIDC or use username/password
- Local authentication requires passwords (same as `local` mode)
- Best for organizations transitioning to SSO or supporting mixed authentication
- Requires OIDC configuration to be set up
#### Summary Table
| Mode | Password Field | Password Required | OIDC Available | Self-Register | Use Case |
|------|---------------|-------------------|----------------|---------------|----------|
| `none` | ❌ No | ❌ No | ❌ No | ✅ Yes | Trusted internal networks, development |
| `local` | ✅ Yes | ✅ Yes | ❌ No | ✅ Yes | Standard password authentication |
| `oidc` | ❌ No | ❌ No | ✅ Yes | ✅ Yes | Enterprise SSO only |
| `both` | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | Mixed authentication (SSO + local) |
### 6) Docker Compose Example
```yaml
services:
app:
image: ghcr.io/your-org/timetracker:latest
environment:
- AUTH_METHOD=oidc
- OIDC_ISSUER=https://idp.example.com/realms/your-realm
- OIDC_CLIENT_ID=${OIDC_CLIENT_ID}
- OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}
- OIDC_REDIRECT_URI=https://your-app.example.com/auth/oidc/callback
- OIDC_SCOPES=openid profile email
- OIDC_ADMIN_GROUP=timetracker-admins
- OIDC_POST_LOGOUT_REDIRECT_URI=https://your-app.example.com/
- SECRET_KEY=${SECRET_KEY}
- DATABASE_URL=${DATABASE_URL}
# ... other settings like ports/volumes
```
### 7) Security Recommendations
- Always use HTTPS in production.
- Set secure cookies: `SESSION_COOKIE_SECURE=true` in production.
- Keep the client secret in a secret store (not committed to git).
- Restrict `ADMIN_*` variables to trusted values only.
- Ensure your reverse proxy forwards `X-Forwarded-Proto` so redirects use HTTPS URLs.
### 8) Troubleshooting
- “SSO button doesnt appear”
- Check `AUTH_METHOD`. Must be `oidc` or `both`.
- “Redirect URI mismatch”
- The `OIDC_REDIRECT_URI` must exactly match the value registered at your IdP.
- “Invalid token / missing claims”
- Confirm scopes and claim names. Override with `OIDC_*_CLAIM` envs if your IdP uses different names.
- “User is not admin”
- Verify `OIDC_ADMIN_GROUP` matches the group claim value, or add the users email to `OIDC_ADMIN_EMAILS`.
- "Logout keeps me signed in" or "Logout redirects to provider error page"
- Not all IdPs support RP-Initiated Logout (end-session). If your provider doesn't support it (e.g., Authelia), **do not set** `OIDC_POST_LOGOUT_REDIRECT_URI`. TimeTracker will then perform local logout only and redirect to the login page.
- If your provider supports end-session and you want to log out from the IdP too, set `OIDC_POST_LOGOUT_REDIRECT_URI` to your desired post-logout landing page.
### 9) Routes Reference
- Local login page: `GET /login` (POST for username form when enabled)
- Start OIDC login: `GET /login/oidc`
- OIDC callback: `GET /auth/oidc/callback`
- Logout: `GET /logout` (tries provider end-session if available)
### 10) Database Changes
The app includes a migration that adds the following to `users`:
- `email` (nullable)
- `oidc_issuer` (nullable)
- `oidc_sub` (nullable)
- Unique constraint on `(oidc_issuer, oidc_sub)`
If your DB wasnt migrated automatically, run your usual migration flow.
### 11) Support
If you run into issues, capture the application logs (including the IdP error page if any) and verify your env vars. Most problems are due to a mismatch in redirect URI, missing scopes/claims, or proxy/HTTPS configuration.