Skip to content

Open WebUI - AI Chat Interface

This cluster runs Open WebUI, providing a modern chat interface for the self-hosted Gemma LLM with enterprise-grade authentication via OCI Identity Domain.

https://chat.k8s.sudhanva.me

Open WebUI connects to Gemma via the OpenAI-compatible API, with authentication handled by OCI Identity Domain:

flowchart TB
    subgraph Internet
        User((User))
    end

    subgraph OCI["Oracle Cloud Infrastructure"]
        subgraph Identity["OCI Identity Domain"]
            OIDC[OIDC Provider<br/>OAuth 2.0 + OpenID Connect]
            JWK[JWK Signing Keys]
        end

        LB[Network Load Balancer]

        subgraph OKE["OKE Cluster"]
            subgraph Gateway["Envoy Gateway"]
                EG[HTTPS Listeners<br/>TLS Termination]
            end

            subgraph OpenWebUI["Open WebUI Pod"]
                UI[Web Interface<br/>:8080]
                OAuth[authlib<br/>OIDC Client]
            end

            subgraph GemmaPod["Gemma Pod"]
                LLM[llama-server<br/>Gemma 3 1B]
            end

            ESO[External Secrets<br/>Operator]
            Secret[K8s Secret<br/>oidc-credentials]
        end

        Vault[(OCI Vault<br/>Client ID/Secret)]
    end

    User -->|1. Access| LB
    LB --> EG
    EG --> UI
    UI -->|2. Redirect| OIDC
    User -->|3. Login| OIDC
    OIDC -->|4. Auth Code| UI
    OAuth -->|5. Token Exchange| OIDC
    OAuth -->|6. Fetch JWK| JWK
    UI -->|7. Chat| LLM
    Vault -->|Sync| ESO
    ESO --> Secret
    Secret --> UI

The complete OpenID Connect authentication flow:

sequenceDiagram
    participant U as User Browser
    participant OW as Open WebUI
    participant OIDC as OCI Identity Domain
    participant JWK as JWK Endpoint

    U->>OW: 1. Visit chat.k8s.sudhanva.me
    OW->>U: 2. Show login page

    U->>OW: 3. Click "Continue with Oracle"
    OW->>U: 4. Redirect to OCI Identity

    U->>OIDC: 5. Enter credentials
    OIDC->>OIDC: 6. Validate user
    OIDC->>U: 7. Redirect with auth code

    U->>OW: 8. Callback with code
    OW->>OIDC: 9. Exchange code for tokens

    Note over OW,JWK: Token Validation
    OW->>JWK: 10. Fetch public keys
    JWK-->>OW: 11. Return JWK set
    OW->>OW: 12. Validate ID token

    OW->>U: 13. Session created
    U->>OW: 14. Start chatting!
FeatureDescription
Chat InterfaceModern, responsive ChatGPT-like UI
OCI OIDC AuthenticationSecure SSO via OCI Identity Domain
Gemma IntegrationPre-configured to use Gemma 3 1B
Conversation HistoryPersistent chat storage (2GB PVC)
Model SelectionSwitch between available models
OAuth User SignupAuto-create users on first OIDC login

Open WebUI is configured with generous resources within free tier limits:

ResourceRequestLimitNotes
Memory1 GB4 GBAmple headroom for UI operations
CPU0.5 core2 coresBurst capacity for responsiveness
Storage2 GB PVC-Persistent user data and chats

The OIDC application is created via Terraform in tf-oke/identity.tf:

flowchart LR
    subgraph Terraform
        TF[identity.tf]
        Vars[terraform.tfvars]
    end

    subgraph OCI["OCI Identity Domain"]
        App[OIDC Application<br/>open-webui]
        Scopes[Allowed Scopes<br/>openid, profile, email]
        Grants[Grant Types<br/>Authorization Code<br/>Refresh Token]
        Redirect[Redirect URI<br/>chat.k8s.sudhanva.me<br/>/oauth/oidc/callback]
    end

    subgraph Vault["OCI Vault"]
        ClientID[client-id]
        ClientSecret[client-secret]
        ProviderURL[provider-url]
    end

    TF -->|Creates| App
    Vars -->|Provides| TF
    App --> Scopes
    App --> Grants
    App --> Redirect
    TF -->|Stores| Vault

Navigate to OCI Console → Identity & Security → Domains → Default → Applications → open-webui:

SettingRequired ValueLocation
Authorization Code✅ EnabledOAuth configuration
Refresh Token✅ EnabledOAuth configuration
Redirect URLhttps://chat.k8s.sudhanva.me/oauth/oidc/callbackOAuth configuration

Under Resources → Token Issuance Policy, add these scopes:

ScopePurpose
openidRequired for OIDC (ID token)
profileAccess user’s name
emailAccess user’s email

Navigate to Settings → Domain settings → Edit domain settings:

SettingRequired ValuePurpose
Configure client access✅ EnabledAllows public access to JWK endpoint
flowchart TB
    subgraph Problem["Without Public JWK Access"]
        App1[Open WebUI] -->|GET /admin/v1/SigningCert/jwk| JWK1[JWK Endpoint]
        JWK1 -->|401 Unauthorized| App1
        App1 -->|Cannot validate ID token| Fail[Login Failed]
    end

    subgraph Solution["With Public JWK Access Enabled"]
        App2[Open WebUI] -->|GET /admin/v1/SigningCert/jwk| JWK2[JWK Endpoint]
        JWK2 -->|200 OK + Keys| App2
        App2 -->|Validate ID token| Success[Login Success]
    end

OIDC credentials flow from OCI Vault to the cluster:

flowchart LR
    subgraph Terraform
        TF[identity.tf<br/>vault.tf]
        TFVARS[terraform.tfvars]
    end

    subgraph OCI["OCI Vault"]
        CID[Secret: client-id]
        SEC[Secret: client-secret]
        URL[Secret: provider-url]
    end

    subgraph Kubernetes
        ESO[External Secrets<br/>Operator]
        ExtSec[ExternalSecret<br/>oidc-credentials-sync]
        K8sSec[Secret<br/>oidc-credentials]
        Pod[Open WebUI Pod]
    end

    TFVARS -->|Variables| TF
    TF -->|Creates| CID
    TF -->|Creates| SEC
    TF -->|Creates| URL
    CID --> ESO
    SEC --> ESO
    URL --> ESO
    ESO -->|Watches| ExtSec
    ExtSec -->|Creates| K8sSec
    K8sSec -->|Env Vars| Pod

Set in tf-oke/terraform.tfvars:

# OIDC Configuration for Open WebUI
oidc_client_id = "your-client-id-from-oci"
oidc_client_secret = "your-client-secret-from-oci"
oidc_provider_url = "https://idcs-xxxxx.identity.oraclecloud.com/.well-known/openid-configuration"

Open WebUI receives these environment variables from the oidc-credentials secret:

VariableSourceDescription
OAUTH_CLIENT_IDVault secretApplication client ID
OAUTH_CLIENT_SECRETVault secretApplication client secret
OPENID_PROVIDER_URLVault secretOIDC discovery endpoint
ENABLE_OAUTH_SIGNUPDeploymenttrue - Create users on first login
ENABLE_LOGIN_FORMDeploymentfalse - OIDC only, no password login
OAUTH_PROVIDER_NAMEDeploymentOracle - Button text
OAUTH_SCOPESDeploymentopenid profile email

Only users assigned to the Open WebUI application in OCI Identity can login:

  1. Go to OCI Console → Identity & Security → Domains → Default
  2. Click Applications → open-webui
  3. Under Users, click Assign
  4. Select users to grant access
  1. Same path as above
  2. Under Users, find the user
  3. Click Revoke

When a user logs in for the first time:

  1. They are redirected to OCI Identity Domain
  2. After authentication, redirected back to Open WebUI
  3. Open WebUI creates a local user account (ENABLE_OAUTH_SIGNUP=true)
  4. User can start chatting immediately
httpx.HTTPStatusError: Client error '401 Unauthorized' for url
'https://idcs-xxx.identity.oraclecloud.com/admin/v1/SigningCert/jwk'

Cause: The “Access signing certificate” setting is disabled in OCI Identity Domain.

Fix:

  1. Navigate to OCI Console → Identity & Security → Domains → Default
  2. Go to Settings → Domain settings
  3. Click Edit domain settings
  4. Enable Configure client access under “Access signing certificate”
  5. Save changes
  6. Restart Open WebUI: kubectl rollout restart deploy/open-webui
httpx.HTTPStatusError: Client error '401 Unauthorized' for url
'https://idcs-xxx.identity.oraclecloud.com/.well-known/openid-configuration'

Cause: The OPENID_PROVIDER_URL is incorrectly formatted (e.g., includes :443 port or missing discovery path).

Fix: Ensure the provider URL in terraform.tfvars follows this format:

oidc_provider_url = "https://idcs-xxxxx.identity.oraclecloud.com/.well-known/openid-configuration"

Then run terraform apply and restart Open WebUI.

Error: invalid_scope - Scope 'openid' is not configured for the application

Cause: Required OIDC scopes not enabled in OCI Identity Domain.

Fix:

  1. Navigate to Applications → open-webui → Resources → Token Issuance Policy
  2. Add scopes: openid, profile, email
  3. Save changes

Cause: Redirect URI mismatch between OCI application config and actual callback URL.

Fix: Verify the redirect URI matches exactly:

https://chat.k8s.sudhanva.me/oauth/oidc/callback

Cause: User not assigned to the Open WebUI application in OCI Identity Domain.

Fix: Assign the user (see User Management section above).

POST /oauth/oidc/callback HTTP/1.1" 405

Cause: OCI Identity Domain uses response_mode=form_post which sends the callback via POST. Older versions of Open WebUI only accepted GET requests.

Fix: Ensure you’re running Open WebUI version with form_post support (added September 2025):

Terminal window
# Restart to pull latest image
kubectl rollout restart deploy/open-webui
# Wait for pod to be ready
kubectl get pods -l app=open-webui -w

The :main tag includes this fix. If using a pinned version, ensure it’s from after September 2025.

Verify the secret is synced correctly:

Terminal window
# Check ExternalSecret status
kubectl get externalsecret oidc-credentials-sync
# View secret contents (base64 decoded)
kubectl get secret oidc-credentials -o jsonpath='{.data.client-id}' | base64 -d
kubectl get secret oidc-credentials -o jsonpath='{.data.provider-url}' | base64 -d
Terminal window
# Follow logs
kubectl logs -f deploy/open-webui
# Check for OIDC errors
kubectl logs deploy/open-webui | grep -i "oauth\|oidc\|401\|error"

Check Gemma pod is healthy:

Terminal window
kubectl get pods -l app=gemma
kubectl logs -f deploy/gemma -c llama-server
FilePurpose
argocd/apps/open-webui/deployment.yamlPod specification with OIDC env vars
argocd/apps/open-webui/service.yamlClusterIP service on port 8080
argocd/apps/open-webui/httproute.yamlGateway routing for chat.k8s.sudhanva.me
argocd/infrastructure/managed-secrets/secrets.yamlExternalSecret for oidc-credentials
argocd/infrastructure/envoy-gateway/config.yamlHTTPS listener for chat subdomain
argocd/infrastructure/envoy-gateway/dnsendpoint.yamlDNS record for chat.k8s.sudhanva.me

Use this checklist when setting up Open WebUI with OIDC:

  • Terraform creates OCI Identity Domain application
  • Terraform stores credentials in OCI Vault
  • Enable Authorization Code grant type in OCI Console
  • Enable Refresh Token grant type in OCI Console
  • Add openid, profile, email scopes
  • Enable Configure client access for signing certificate
  • Assign users to the application
  • ExternalSecret syncs to oidc-credentials secret
  • Open WebUI pod starts without errors
  • OIDC login works end-to-end