Files
oicd/docs/deployment.md
2025-11-30 00:07:24 +01:00

12 KiB

Deployment Guide

Complete guide for deploying the OIDC Identity Provider in both development and production environments.


Table of Contents

  1. Development Deployment
  2. Production Deployment
  3. Management Commands
  4. Troubleshooting

Development Deployment

Quick Start

The fastest way to get the OIDC server running for development and testing.

Step 1: Get the Code

git clone <your-repo-url> wlkns_auth
cd wlkns_auth

Step 2: Configure Environment

# 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

# 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:

docker-compose -f docker-compose.prod.yml ps

Test health endpoint:

curl http://localhost:5000/health

Expected response:

{
    "status": "healthy",
    "database": "healthy",
    "timestamp": "2025-11-27T09:19:54.558214",
    "version": "1.0.0"
}

Access Information

OIDC Server:

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:

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):

# 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

git clone <your-repo-url> wlkns_auth
cd wlkns_auth

Step 2: Configure the Environment

Copy the production environment template:

cp .env.production .env

Required: Set your public domain:

nano .env

Change the OIDC_ISSUER to your server's public URL:

# 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:

./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://<your-domain>/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:

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;
    }
}
  1. Test and Reload Nginx:
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:

# 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:

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=<generate-random-secret>

3. Run Database Migrations:

flask db upgrade
flask seed

4. Start the Server:

# 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

# 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:

docker exec -e FLASK_APP=oidc_server.py oidc_server flask db upgrade

Seed Database:

docker exec -e FLASK_APP=oidc_server.py oidc_server flask seed

Access PostgreSQL:

docker exec -it oidc_postgres psql -U oidc_user -d oidc_db

Query Users:

docker exec oidc_postgres psql -U oidc_user -d oidc_db -c "SELECT username, email, is_admin, role FROM users;"

Create Database Backup:

# 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:

# 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:

# 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

# 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

# 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:

# 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

# 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

# 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.

# 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:

# 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 <access_token>

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: