# Deployment Guide Complete guide for deploying the OIDC Identity Provider in both development and production environments. --- ## Table of Contents 1. [Development Deployment](#development-deployment) 2. [Production Deployment](#production-deployment) 3. [Management Commands](#management-commands) 4. [Troubleshooting](#troubleshooting) --- ## Development Deployment ### Quick Start The fastest way to get the OIDC server running for development and testing. #### Step 1: Get the Code ```bash git clone wlkns_auth cd wlkns_auth ``` #### Step 2: Configure Environment ```bash # Copy the production environment template cp .env.production .env # Edit if needed (default works for local development) nano .env ``` For local development, the default `OIDC_ISSUER=http://localhost:5000` works fine. #### Step 3: Deploy with Docker ```bash # Build and start services docker-compose -f docker-compose.prod.yml up -d # Or use the deployment script ./deploy.sh ``` #### Step 4: Verify Deployment **Check service status:** ```bash docker-compose -f docker-compose.prod.yml ps ``` **Test health endpoint:** ```bash curl http://localhost:5000/health ``` Expected response: ```json { "status": "healthy", "database": "healthy", "timestamp": "2025-11-27T09:19:54.558214", "version": "1.0.0" } ``` ### Access Information **OIDC Server:** - Base URL: http://localhost:5000 - Discovery: http://localhost:5000/.well-known/openid-configuration - Admin Panel: http://localhost:5000/admin/login **Default Credentials:** *Admin User:* - Username: `admin` - Password: `admin123` - Role: admin - Permissions: read:data, write:data, manage:users, manage:settings *Test User:* - Username: `test` - Password: `test123` - Role: user - Permissions: read:data **⚠️ IMPORTANT:** Change the admin password immediately after first login! **Default OIDC Client:** - Client ID: `test-client` - Client Secret: (generated in `.env`) - Redirect URIs: `http://localhost:8080/callback` - Allowed Scopes: openid, profile, email ### Development Testing **1. Test OIDC Discovery:** ```bash curl http://localhost:5000/.well-known/openid-configuration ``` **2. Test Admin Login:** 1. Open http://localhost:5000/admin/login in browser 2. Login with `admin` / `admin123` 3. You should see the admin dashboard **3. Test User Registration:** 1. Open http://localhost:5000/register 2. Create a new user account 3. Login at http://localhost:5000/login **4. Test OIDC Flow (Optional):** ```bash # In a separate terminal python3 test_client.py ``` Then open http://localhost:8080 and click "Mit OIDC einloggen" --- ## Production Deployment ### Prerequisites - A server with Docker and Docker Compose installed - A domain name pointing to your server's IP address - Basic familiarity with the command line - Ports 80 and 443 open if exposing to the internet ### Step 1: Get the Code ```bash git clone wlkns_auth cd wlkns_auth ``` ### Step 2: Configure the Environment Copy the production environment template: ```bash cp .env.production .env ``` **Required: Set your public domain:** ```bash nano .env ``` Change the `OIDC_ISSUER` to your server's public URL: ```bash # Example: OIDC_ISSUER=https://auth.yourdomain.com OIDC_ISSUER=https://auth.example.com ``` **Security Checklist:** - ✅ Generate new `SECRET_KEY` (done automatically in `.env.production`) - ✅ Use strong `POSTGRES_PASSWORD` (done automatically) - ✅ Set proper `OIDC_ISSUER` with your domain - ✅ Review token lifetimes (`ACCESS_TOKEN_LIFETIME`, etc.) ### Step 3: Deploy the Application Run the deployment script: ```bash ./deploy.sh ``` This will: 1. Build Docker images 2. Start OIDC server and PostgreSQL 3. Apply database migrations 4. Seed initial data ### Step 4: Secure the Admin Account **CRITICAL:** Change the default admin password immediately! 1. Navigate to `https:///admin/login` 2. Log in with default credentials: - Username: `admin` - Password: `admin123` 3. Go to user list → Edit admin user → Set a strong password ### Advanced Production Scenarios #### Scenario A: Using an Existing Nginx Reverse Proxy If you already have Nginx running and want it to manage SSL: 1. **Deploy the OIDC Server** following Steps 1-3 above 2. **Configure Nginx** with this server block: ```nginx server { listen 443 ssl http2; server_name auth.yourdomain.com; # Your SSL certificate configuration ssl_certificate /path/to/your/fullchain.pem; ssl_certificate_key /path/to/your/privkey.pem; # SSL hardening (recommended) ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` 3. **Test and Reload Nginx:** ```bash sudo nginx -t sudo systemctl reload nginx ``` #### Scenario B: Manual Deployment (Without Docker) While Docker is recommended, you can run the application manually: **1. Install Dependencies:** ```bash # Create virtual environment python3 -m venv venv source venv/bin/activate # Install dependencies pip install -r requirements.txt ``` **2. Configure Environment:** Create a `.env` file with these required variables: ```bash FLASK_APP=oidc_server.py FLASK_ENV=production DATABASE_URL=postgresql://user:password@localhost:5432/oidc_db OIDC_ISSUER=https://auth.yourdomain.com SECRET_KEY= ``` **3. Run Database Migrations:** ```bash flask db upgrade flask seed ``` **4. Start the Server:** ```bash # For production, use Gunicorn gunicorn --bind 0.0.0.0:5000 "oidc_server:app" # Or with workers gunicorn --workers 4 --bind 0.0.0.0:5000 "oidc_server:app" ``` --- ## Management Commands ### Service Control ```bash # View logs (all services) docker-compose -f docker-compose.prod.yml logs -f # View logs (specific service) docker-compose -f docker-compose.prod.yml logs -f oidc_server docker-compose -f docker-compose.prod.yml logs -f postgres # Stop services docker-compose -f docker-compose.prod.yml down # Start services docker-compose -f docker-compose.prod.yml up -d # Restart services docker-compose -f docker-compose.prod.yml restart # Rebuild and restart docker-compose -f docker-compose.prod.yml up -d --build ``` ### Database Operations **Run Migrations:** ```bash docker exec -e FLASK_APP=oidc_server.py oidc_server flask db upgrade ``` **Seed Database:** ```bash docker exec -e FLASK_APP=oidc_server.py oidc_server flask seed ``` **Access PostgreSQL:** ```bash docker exec -it oidc_postgres psql -U oidc_user -d oidc_db ``` **Query Users:** ```bash docker exec oidc_postgres psql -U oidc_user -d oidc_db -c "SELECT username, email, is_admin, role FROM users;" ``` **Create Database Backup:** ```bash # Create backup directory mkdir -p backups # Create compressed backup docker exec oidc_postgres pg_dump -U oidc_user -d oidc_db | gzip > backups/oidc_backup_$(date +%Y%m%d_%H%M%S).sql.gz ``` **Restore from Backup:** ```bash # Stop the application docker-compose -f docker-compose.prod.yml down # Start only PostgreSQL docker-compose -f docker-compose.prod.yml up -d postgres # Restore backup gunzip -c backups/oidc_backup_20251127_120000.sql.gz | docker exec -i oidc_postgres psql -U oidc_user -d oidc_db # Start all services docker-compose -f docker-compose.prod.yml up -d ``` ### Updating the Application To update to the latest version: ```bash # Pull latest code git pull # Rebuild and restart docker-compose -f docker-compose.prod.yml up -d --build # Apply any new migrations docker exec -e FLASK_APP=oidc_server.py oidc_server flask db upgrade ``` --- ## Troubleshooting ### Services Won't Start ```bash # Check logs for errors docker-compose -f docker-compose.prod.yml logs # Check if ports are already in use sudo netstat -tlnp | grep 5000 sudo netstat -tlnp | grep 5432 # Check Docker service status sudo systemctl status docker ``` ### Database Connection Issues ```bash # Verify PostgreSQL is healthy docker-compose -f docker-compose.prod.yml ps postgres # Test database connection docker exec oidc_postgres pg_isready -U oidc_user -d oidc_db # Check database logs docker-compose -f docker-compose.prod.yml logs postgres ``` ### "Bad Gateway" from Nginx This usually means the OIDC server container is not running: ```bash # Check container status docker-compose -f docker-compose.prod.yml ps # View OIDC server logs docker-compose -f docker-compose.prod.yml logs oidc_server # Restart the service docker-compose -f docker-compose.prod.yml restart oidc_server ``` ### "Invalid Credentials" on Login ```bash # Ensure database was seeded docker exec -e FLASK_APP=oidc_server.py oidc_server flask seed # Check if users exist docker exec oidc_postgres psql -U oidc_user -d oidc_db -c "SELECT * FROM users;" # Verify default password hasn't been changed ``` ### Container Keeps Restarting ```bash # Check container logs for errors docker logs oidc_server --tail=100 # Common issues: # - Missing environment variables # - Database connection failure # - Syntax errors in Python files # - Missing JWT keys # Check environment variables docker exec oidc_server env | grep FLASK ``` ### "Invalid Redirect URI" Error Make sure the `redirect_uri` your client application is using is listed in that client's configuration in the admin dashboard. ```bash # Check client configuration docker exec oidc_postgres psql -U oidc_user -d oidc_db -c "SELECT client_id, redirect_uris FROM clients;" ``` ### "Invalid Client ID" Error Ensure the `client_id` is correct and the client exists: ```bash # List all clients docker exec oidc_postgres psql -U oidc_user -d oidc_db -c "SELECT * FROM clients;" ``` --- ## OIDC Endpoints Reference ### Discovery Document ``` GET http://localhost:5000/.well-known/openid-configuration ``` ### Authorization Endpoint ``` GET http://localhost:5000/authorize ``` Parameters: - `client_id`: Client identifier - `redirect_uri`: Callback URL - `response_type`: `code` - `scope`: `openid profile email` - `state`: CSRF protection token ### Token Endpoint ``` POST http://localhost:5000/token ``` Parameters: - `grant_type`: `authorization_code` - `code`: Authorization code - `redirect_uri`: Same as authorization - `client_id`: Client identifier - `client_secret`: Client secret ### UserInfo Endpoint ``` GET http://localhost:5000/userinfo Authorization: Bearer ``` ### Health Check ``` GET http://localhost:5000/health ``` --- ## Security Checklist ### Production Security - ✅ Change default admin password - ✅ Use HTTPS (via Nginx reverse proxy) - ✅ Set strong `SECRET_KEY` - ✅ Use strong database passwords - ✅ Enable firewall (only expose 80/443) - ✅ Regular database backups - ✅ Keep Docker images updated - ✅ Review audit logs regularly - ✅ Configure rate limiting appropriately - ✅ Use environment variables for secrets ### Active Security Features - bcrypt password hashing - RS256 JWT signing - Session security (HttpOnly, SameSite) - Rate limiting on login endpoints - Audit logging - Non-root Docker user - Strong generated secrets --- ## What's Working ✅ Docker Compose deployment ✅ PostgreSQL database with persistence ✅ User authentication (bcrypt hashing) ✅ Admin panel with CRUD operations ✅ OIDC discovery endpoint ✅ Authorization endpoint ✅ Token endpoint ✅ UserInfo endpoint ✅ Health check endpoint ✅ Rate limiting ✅ Audit logging ✅ Database migrations ✅ Multi-client support --- ## Next Steps ### Immediate Actions 1. Change default admin password 2. Set up HTTPS with reverse proxy 3. Configure automated database backups 4. Set up monitoring and log aggregation ### Optional Improvements 1. Fix JWKS endpoint (known issue with public key format) 2. Implement refresh tokens 3. Add PKCE support for public clients 4. Add email verification 5. Implement 2FA/MFA 6. Set up automated testing --- For more information, see: - [Architecture Documentation](architecture.md) - [Testing Guide](testing.md) - [Project Roadmap](todo.md)