12 KiB
Deployment Guide
Complete guide for deploying the OIDC Identity Provider in both development and production environments.
Table of Contents
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:
- 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:
curl http://localhost:5000/.well-known/openid-configuration
2. Test Admin Login:
- Open http://localhost:5000/admin/login in browser
- Login with
admin/admin123 - You should see the admin dashboard
3. Test User Registration:
- Open http://localhost:5000/register
- Create a new user account
- 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_ISSUERwith your domain - ✅ Review token lifetimes (
ACCESS_TOKEN_LIFETIME, etc.)
Step 3: Deploy the Application
Run the deployment script:
./deploy.sh
This will:
- Build Docker images
- Start OIDC server and PostgreSQL
- Apply database migrations
- Seed initial data
Step 4: Secure the Admin Account
CRITICAL: Change the default admin password immediately!
- Navigate to
https://<your-domain>/admin/login - Log in with default credentials:
- Username:
admin - Password:
admin123
- Username:
- 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:
-
Deploy the OIDC Server following Steps 1-3 above
-
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;
}
}
- 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 identifierredirect_uri: Callback URLresponse_type:codescope:openid profile emailstate: CSRF protection token
Token Endpoint
POST http://localhost:5000/token
Parameters:
grant_type:authorization_codecode: Authorization coderedirect_uri: Same as authorizationclient_id: Client identifierclient_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
- Change default admin password
- Set up HTTPS with reverse proxy
- Configure automated database backups
- Set up monitoring and log aggregation
Optional Improvements
- Fix JWKS endpoint (known issue with public key format)
- Implement refresh tokens
- Add PKCE support for public clients
- Add email verification
- Implement 2FA/MFA
- Set up automated testing
For more information, see: