first commit

This commit is contained in:
2025-11-30 00:07:24 +01:00
commit b5e642aecb
78 changed files with 15162 additions and 0 deletions

105
CLAUDE.md Normal file
View File

@ -0,0 +1,105 @@
# CLAUDE.md
This file provides guidance to AI assistants when working with code in this repository.
## Project Purpose
A production-ready OpenID Connect (OIDC) Identity Provider (IdP) built in Flask. It is designed for self-hosting and homelab environments, uses a PostgreSQL database, and is deployed via Docker. It implements the full Authorization Code Flow with advanced user management.
## How to Run the Server
The primary way to run the server is with Docker Compose.
```bash
# 1. Copy the production environment template
cp .env.production .env
# 2. (Optional) Edit the .env file, especially OIDC_ISSUER
nano .env
# 3. Build and start the services (in detached mode)
./deploy.sh
```
The server will be available on port 5000, with a PostgreSQL database running in a separate container. For local development outside of Docker, see the `README.md`.
## Architecture Overview
### Configuration (`config.py`, `.env`)
- **Environment-based**: The application loads its configuration based on the `FLASK_ENV` environment variable (`development` or `production`).
- **`config.py`**: Contains three classes: `DevelopmentConfig`, `ProductionConfig`, and `TestingConfig`. The `get_config()` function returns the appropriate class.
- **`.env` file**: All secrets (like `SECRET_KEY`, `DATABASE_URL`) and environment-specific settings are loaded from this file using `python-dotenv`.
- **Validation**: `ProductionConfig` validates that all required environment variables are set, preventing startup with an incomplete configuration.
### Main Application (`oidc_server.py`)
- **Flask App**: The core of the application. It initializes the database, rate limiter, and loads the configuration. It also initializes `Flask-Migrate` for database schema migrations.
- **Blueprints**: The application is structured with Flask Blueprints for modularity:
- **OIDC Endpoints**: `/authorize`, `/token`, `/userinfo`, `/.well-known/openid-configuration`.
- **User-facing pages**: `/login`, `/register`, `/change-password`, `/dashboard`.
- **Admin Panel**: A complete admin section under `/admin/...` protected by an `@admin_required` decorator.
- **Templates**: All HTML templates are stored as strings in `templates.py` and `admin_templates.py` and rendered with `render_template_string` for simplicity.
### Database Layer (`models.py`)
SQLAlchemy ORM models define the database schema.
1. **`User` Model**:
- Stores user credentials with **bcrypt-hashed** passwords.
- Implements roles (`role` field) and a flexible, JSON-based `permissions` system.
- Helper methods like `set_password()`, `check_password()`, `get_permissions()`, `has_permission()`.
- `is_admin` and `is_active` flags for access control.
2. **`Client` Model**:
- Stores OIDC client applications.
- `client_id` is the public identifier.
- `client_secret_hash` stores the hashed client secret using bcrypt.
- `redirect_uris` and `allowed_scopes` are stored as JSON strings.
3. **`AuthorizationCode` Model**:
- Stores temporary authorization codes with a configurable TTL (Time To Live).
- `is_valid()` method checks if the code is expired or has already been used.
- One-time use is enforced by the `used` flag.
3. **`AccessToken` Model**:
- Stores issued access tokens with a configurable TTL.
- Can be invalidated using the `revoked` flag.
4. **`AuditLog` Model**:
- **New**: Logs critical security events.
- A class method `AuditLog.log()` is used to easily create new log entries.
- Tracks actions like `login_success`, `login_failed`, `user_created`, `user_deleted`, etc.
- Stores IP address, User-Agent, and other relevant details.
### Security Features
- **Rate Limiting**: `Flask-Limiter` is used to protect sensitive endpoints like `/login`, `/admin/login`, and `/token` from brute-force attacks.
- **Audit Logging**: All important user and admin actions are logged to the `audit_logs` table for security analysis.
- **Password Security**: Passwords are never stored in plaintext. `bcrypt` is used for hashing.
- **Admin Protection**: The admin area is protected by a decorator (`@admin_required`) that checks for a valid admin session and ensures the user has admin privileges.
## Key Implementation Details
- **OIDC Flow**: The standard flow is implemented across `/authorize` and `/token`. The ID token is signed using **RS256** with a private key. The corresponding public key is exposed via the `/jwks` endpoint.
- **Database Migrations**: The database schema is managed by `Flask-Migrate` (Alembic). The `flask db upgrade` command applies migrations, and the `flask seed` command populates the database with initial users.
- **Token Cleanup**: `cleanup_expired_tokens()` provides a way to periodically remove expired tokens from the database.
## Security Status
This is an overview of security features from the `TODO.md` file.
- ✅ **bcrypt password hashing**
- ✅ **Persistent database storage**
- ✅ **User self-service registration & password change**
- ✅ **Rate Limiting** on critical endpoints
- ✅ **Audit Logging** for security-relevant events
- ✅ **Environment-based config** (no secrets in code)
- ✅ **Asymmetric JWT signing (RS256)**
- ✅ **Database migrations (Alembic)**
- ✅ **Multi-client support** (managed in the database)
- ✅ **Docker support** with a non-root user
- ⚠️ **Still needs for full OIDC compliance and higher security**:
- Refresh Tokens.
- PKCE support for public clients (SPAs, mobile apps).