5.4 KiB
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.
# 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_ENVenvironment variable (developmentorproduction). config.py: Contains three classes:DevelopmentConfig,ProductionConfig, andTestingConfig. Theget_config()function returns the appropriate class..envfile: All secrets (likeSECRET_KEY,DATABASE_URL) and environment-specific settings are loaded from this file usingpython-dotenv.- Validation:
ProductionConfigvalidates 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-Migratefor 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_requireddecorator.
- OIDC Endpoints:
- Templates: All HTML templates are stored as strings in
templates.pyandadmin_templates.pyand rendered withrender_template_stringfor simplicity.
Database Layer (models.py)
SQLAlchemy ORM models define the database schema.
-
UserModel:- Stores user credentials with bcrypt-hashed passwords.
- Implements roles (
rolefield) and a flexible, JSON-basedpermissionssystem. - Helper methods like
set_password(),check_password(),get_permissions(),has_permission(). is_adminandis_activeflags for access control.
-
ClientModel:- Stores OIDC client applications.
client_idis the public identifier.client_secret_hashstores the hashed client secret using bcrypt.redirect_urisandallowed_scopesare stored as JSON strings.
-
AuthorizationCodeModel:- 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
usedflag.
-
AccessTokenModel:- Stores issued access tokens with a configurable TTL.
- Can be invalidated using the
revokedflag.
-
AuditLogModel:- 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-Limiteris used to protect sensitive endpoints like/login,/admin/login, and/tokenfrom brute-force attacks. - Audit Logging: All important user and admin actions are logged to the
audit_logstable for security analysis. - Password Security: Passwords are never stored in plaintext.
bcryptis 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
/authorizeand/token. The ID token is signed using RS256 with a private key. The corresponding public key is exposed via the/jwksendpoint. - Database Migrations: The database schema is managed by
Flask-Migrate(Alembic). Theflask db upgradecommand applies migrations, and theflask seedcommand 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).