# Open WebUI Open WebUI is an extensible, self-hosted AI interface that provides a web-based chat experience for interacting with LLMs. This document covers deployment, Casdoor SSO integration, and configuration. ## Architecture ### Components | Component | Location | Purpose | |-----------|----------|---------| | Open WebUI | Native on Oberon | AI chat interface | | PostgreSQL | Portia | Database with pgvector extension | | Casdoor | Titania | SSO identity provider | | HAProxy | Ariel | TLS termination, routing | ### Network Diagram ``` ┌────────────────────────────────────────────────────────────────────┐ │ External Access │ │ https://openwebui.ouranos.helu.ca │ └───────────────────────────────┬────────────────────────────────────┘ │ ▼ ┌────────────────────────────────────────────────────────────────────┐ │ ariel.incus (HAProxy) │ │ TLS termination → proxy to oberon.incus:25588 │ └───────────────────────────────┬────────────────────────────────────┘ │ ▼ ┌────────────────────────────────────────────────────────────────────┐ │ oberon.incus │ │ │ │ ┌────────────────────────────────────────────────────────────────┐ │ │ │ Open WebUI (systemd) │ │ │ │ - Python 3.12 virtual environment │ │ │ │ - Port 25588 │ │ │ │ - OAuth/OIDC via Casdoor │ │ │ └────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ PostgreSQL │ OIDC │ │ ▼ ▼ │ │ portia.incus:5432 titania.incus:22081 │ │ (openwebui database) (Casdoor SSO) │ └────────────────────────────────────────────────────────────────────┘ ``` ### Network Ports | Port | Service | Access | |------|---------|--------| | 25588 | Open WebUI HTTP | Via HAProxy | | 5432 | PostgreSQL | Internal (Portia) | | 22081 | Casdoor | Internal (Titania) | ## Casdoor SSO Integration Open WebUI uses native OAuth/OIDC to authenticate against Casdoor. Local signup is disabled—all users must authenticate through Casdoor. ### How It Works 1. User visits `https://openwebui.ouranos.helu.ca` 2. Open WebUI redirects to Casdoor login page 3. User authenticates with Casdoor credentials 4. Casdoor redirects back with authorization code 5. Open WebUI exchanges code for tokens and creates/updates user session 6. User email from Casdoor becomes their Open WebUI identity ### Configuration OAuth settings are defined in host variables and rendered into the environment file: **Host Variables** (`inventory/host_vars/oberon.incus.yml`): ```yaml # OAuth/OIDC Configuration (Casdoor SSO) openwebui_oauth_client_id: "{{ vault_openwebui_oauth_client_id }}" openwebui_oauth_client_secret: "{{ vault_openwebui_oauth_client_secret }}" openwebui_oauth_provider_name: "Casdoor" openwebui_oauth_provider_url: "https://id.ouranos.helu.ca/.well-known/openid-configuration" # Disable local authentication openwebui_enable_signup: false openwebui_enable_email_login: false ``` **Environment Variables** (rendered from `openwebui.env.j2`): ```bash ENABLE_SIGNUP=false ENABLE_EMAIL_LOGIN=false ENABLE_OAUTH_SIGNUP=true OAUTH_CLIENT_ID= OAUTH_CLIENT_SECRET= OAUTH_PROVIDER_NAME=Casdoor OPENID_PROVIDER_URL=https://id.ouranos.helu.ca/.well-known/openid-configuration ``` ### Casdoor Application The `app-openwebui` application is defined in `ansible/casdoor/init_data.json.j2`: | Setting | Value | |---------|-------| | Name | `app-openwebui` | | Display Name | Open WebUI | | Redirect URI | `https://openwebui.ouranos.helu.ca/oauth/oidc/callback` | | Grant Types | `authorization_code`, `refresh_token` | | Token Format | JWT | | Token Expiry | 168 hours (7 days) | ## Prerequisites ### 1. PostgreSQL Database The `openwebui` database must exist on Portia with the `pgvector` extension: ```bash ansible-playbook postgresql/deploy.yml ``` ### 2. Casdoor SSO Casdoor must be deployed and the `app-openwebui` application configured: ```bash ansible-playbook casdoor/deploy.yml ``` ### 3. Vault Secrets Add to `ansible/inventory/group_vars/all/vault.yml`: ```yaml # OpenWebUI vault_openwebui_secret_key: "" vault_openwebui_db_password: "" vault_openwebui_oauth_client_id: "" vault_openwebui_oauth_client_secret: "" # API Keys (optional) vault_openwebui_openai_api_key: "" vault_openwebui_anthropic_api_key: "" vault_openwebui_groq_api_key: "" vault_openwebui_mistral_api_key: "" ``` Generate secrets: ```bash # Secret key openssl rand -hex 32 # Database password openssl rand -base64 24 ``` ## Deployment ### Fresh Installation ```bash cd ansible # 1. Ensure PostgreSQL is deployed ansible-playbook postgresql/deploy.yml # 2. Deploy Casdoor (if not already deployed) ansible-playbook casdoor/deploy.yml # 3. Get OAuth credentials from Casdoor admin UI # - Navigate to https://id.ouranos.helu.ca # - Go to Applications → app-openwebui # - Copy Client ID and Client Secret # - Update vault.yml with these values # 4. Deploy Open WebUI ansible-playbook openwebui/deploy.yml ``` ### Verify Deployment ```bash # Check service status ssh oberon.incus "sudo systemctl status openwebui" # View logs ssh oberon.incus "sudo journalctl -u openwebui -f" # Test health endpoint curl -s http://oberon.incus:25588/health # Test via HAProxy curl -s https://openwebui.ouranos.helu.ca/health ``` ### Redeployment To redeploy Open WebUI (preserves database): ```bash ansible-playbook openwebui/deploy.yml ``` ## Configuration Reference ### Host Variables Located in `ansible/inventory/host_vars/oberon.incus.yml`: ```yaml # Service account openwebui_user: openwebui openwebui_group: openwebui openwebui_directory: /srv/openwebui openwebui_port: 25588 openwebui_host: puck.incus # Database openwebui_db_host: portia.incus openwebui_db_port: 5432 openwebui_db_name: openwebui openwebui_db_user: openwebui openwebui_db_password: "{{ vault_openwebui_db_password }}" # Authentication (SSO only) openwebui_enable_signup: false openwebui_enable_email_login: false # OAuth/OIDC (Casdoor) openwebui_oauth_client_id: "{{ vault_openwebui_oauth_client_id }}" openwebui_oauth_client_secret: "{{ vault_openwebui_oauth_client_secret }}" openwebui_oauth_provider_name: "Casdoor" openwebui_oauth_provider_url: "https://id.ouranos.helu.ca/.well-known/openid-configuration" # API Keys openwebui_openai_api_key: "{{ vault_openwebui_openai_api_key }}" openwebui_anthropic_api_key: "{{ vault_openwebui_anthropic_api_key }}" openwebui_groq_api_key: "{{ vault_openwebui_groq_api_key }}" openwebui_mistral_api_key: "{{ vault_openwebui_mistral_api_key }}" ``` ### Data Persistence Open WebUI data locations: ``` /srv/openwebui/ ├── .venv/ # Python virtual environment ├── .env # Environment configuration └── data/ # User uploads, cache ``` Database (on Portia): ``` PostgreSQL: openwebui database with pgvector extension ``` ## User Management ### First-Time Setup After deployment, the first user to authenticate via Casdoor becomes an admin. Subsequent users get standard user roles. ### Promoting Users to Admin 1. Log in as an existing admin 2. Navigate to Admin Panel → Users 3. Select the user and change their role to Admin ### Existing Users Migration If users were created before SSO was enabled: - Users with matching email addresses will be linked automatically - Users without matching emails must be recreated through Casdoor ## Troubleshooting ### Service Issues ```bash # Check service status ssh oberon.incus "sudo systemctl status openwebui" # View logs ssh oberon.incus "sudo journalctl -u openwebui -n 100" # Restart service ssh oberon.incus "sudo systemctl restart openwebui" ``` ### OAuth/OIDC Issues ```bash # Verify Casdoor is accessible curl -s https://id.ouranos.helu.ca/.well-known/openid-configuration | jq # Check redirect URI matches # Must be: https://openwebui.ouranos.helu.ca/oauth/oidc/callback # Verify client credentials in environment ssh oberon.incus "sudo grep OAUTH /srv/openwebui/.env" ``` ### Database Issues ```bash # Test database connection ssh oberon.incus "PGPASSWORD= psql -h portia.incus -U openwebui -d openwebui -c '\dt'" # Check pgvector extension ssh portia.incus "sudo -u postgres psql -d openwebui -c '\dx'" ``` ### Common Errors | Error | Cause | Solution | |-------|-------|----------| | "Invalid redirect_uri" | Mismatch between Casdoor config and Open WebUI | Verify redirect URI in Casdoor matches exactly | | "Invalid client credentials" | Wrong client ID/secret | Update vault with correct values from Casdoor | | "OIDC discovery failed" | Casdoor unreachable | Check Casdoor is running on Titania | | "Database connection failed" | PostgreSQL unreachable | Verify PostgreSQL on Portia, check network | ## Security Considerations 1. **SSO-only authentication** - Local signup disabled, all users authenticate through Casdoor 2. **API keys in vault** - All API keys stored encrypted in Ansible vault 3. **Database credentials** - Stored in vault, rendered to environment file with restrictive permissions (0600) 4. **Session security** - JWT tokens with 7-day expiry, managed by Casdoor ## Related Documentation - [Casdoor SSO](services/casdoor.md) - Identity provider configuration - [PostgreSQL](../ansible.md) - Database deployment - [HAProxy](../terraform.md) - TLS termination and routing