[email protected]

How-to · Local AI for Business

Set up Open WebUI SSO: OIDC with Entra ID, Keycloak and Authentik

Editorial note: Versions, commands and prices may change. Please verify critical steps independently before production use. This guide does not replace individual professional, legal or tax advice.

Rather not set up SSO for Open WebUI yourself? The WZ-IT AI platform is Open WebUI as a managed service: your own instance, models operated in Germany by German providers and SSO are included in the monthly price from €149.90 net. View the AI platform · Clarify the integration together

Open WebUI signs users in through OpenID Connect (OIDC) at an identity provider. The configuration consists of a few environment variables and fails in practice on details: a redirect URI that is off by one character, a claim that is not in the token, or a first login that turns the wrong account into the administrator. This guide walks through the setup with Microsoft Entra ID and Keycloak, places Authentik and ZITADEL and ends with a checklist. It is based on the Open WebUI documentation, the source code of Open WebUI v0.12.4 and the documentation of the identity providers. As of 28 October 2026.

Table of contents

Which sign-in path fits

Path Suited for Redirect URI Core variables
Generic OIDC Keycloak, Authentik, ZITADEL, Okta and any OIDC provider /oauth/oidc/callback OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OPENID_PROVIDER_URL
Microsoft provider Entra ID, one tenant /oauth/microsoft/callback MICROSOFT_CLIENT_ID, MICROSOFT_CLIENT_SECRET, MICROSOFT_CLIENT_TENANT_ID
Trusted header Authenticating reverse proxy (oauth2-proxy, Cloudflare Access, Tailscale Serve) none WEBUI_AUTH_TRUSTED_EMAIL_HEADER

Only one OIDC provider can be configured at a time, and the Microsoft provider supports a single tenant (SSO documentation). With a trusted header, Open WebUI must only be reachable by the proxy: anyone who can set the header themselves signs in as any user. The rest of this guide covers OIDC.

Settle before the first login

  1. Create the local administrator first. The first account on a fresh instance becomes administrator, even if it is created through SSO: the code assigns the role admin as soon as exactly one user exists after the insert. WEBUI_ADMIN_EMAIL and WEBUI_ADMIN_PASSWORD create the account on first start and switch off self-registration (environment variables).
  2. Set WEBUI_URL before the first SSO login. The variable is a persistent setting: later changes to the environment variable no longer apply, only the admin area or ENABLE_PERSISTENT_CONFIG=false do.
  3. Assign a fixed WEBUI_SECRET_KEY. It signs session tokens and encrypts OAuth tokens. An automatically generated key lives inside the container; if the container is recreated, all sessions become invalid.
  4. Set the redirect URI explicitly. Without OPENID_REDIRECT_URI, Open WebUI derives it from the request; behind a proxy that changes the URL it then differs from the entry at the identity provider.

Base configuration

services:
  open-webui:
    image: ghcr.io/open-webui/open-webui:v0.12.4   # pin the version
    environment:
      WEBUI_URL: "https://chat.example.com"
      WEBUI_SECRET_KEY: "${WEBUI_SECRET_KEY}"
      ENABLE_OAUTH_SIGNUP: "true"
      OAUTH_PROVIDER_NAME: "Keycloak"
      OAUTH_CLIENT_ID: "open-webui"
      OAUTH_CLIENT_SECRET: "${OAUTH_CLIENT_SECRET}"
      OPENID_PROVIDER_URL: "https://id.example.com/realms/company/.well-known/openid-configuration"
      OPENID_REDIRECT_URI: "https://chat.example.com/oauth/oidc/callback"
      OAUTH_SCOPES: "openid email profile"
Variable Default Effect
ENABLE_OAUTH_SIGNUP false Without true, SSO creates no new accounts and the first login is rejected with 403
DEFAULT_USER_ROLE pending New accounts wait for approval as long as no roles come from the token
OAUTH_MERGE_ACCOUNTS_BY_EMAIL false Links SSO accounts to local accounts with the same address; unsafe if the provider does not verify addresses
ENABLE_OAUTH_PERSISTENT_CONFIG false Environment variables stay authoritative, the OAuth section in the admin panel is read-only
OAUTH_TOKEN_ENDPOINT_AUTH_METHOD not set client_secret_basic or client_secret_post if the provider accepts only one method

Microsoft Entra ID

  1. Register the app. Platform "Web", redirect URI https://chat.example.com/oauth/microsoft/callback. Microsoft requires https (exception: localhost) and treats the URL path as case-sensitive (redirect URI rules).
  2. Create a client secret. Its lifetime is at most 24 months, and Microsoft recommends less than 12 (credentials). When the secret expires, nobody can sign in; the expiry date and renewal belong in the operations calendar.
  3. Permissions: delegated openid, email and profile with administrator consent. The scope offline_access is added in MICROSOFT_OAUTH_SCOPE; it needs no further configuration in Entra. Without it, token renewal fails after about an hour; model connections using OAuth and SharePoint access are affected, the chat itself is not (SSO documentation).
MICROSOFT_CLIENT_ID=<application ID>
MICROSOFT_CLIENT_SECRET=<client secret>
MICROSOFT_CLIENT_TENANT_ID=<directory ID>
MICROSOFT_REDIRECT_URI=https://chat.example.com/oauth/microsoft/callback
MICROSOFT_OAUTH_SCOPE=openid email profile offline_access
ENABLE_OAUTH_SIGNUP=true

OPENID_PROVIDER_URL is not required for Microsoft: sign-in and sign-out use the tenant's own discovery URL (SSO documentation, troubleshooting). The community group name sync tutorial still sets it as "Required for logout to work properly" (https://login.microsoftonline.com/<directory ID>/v2.0/.well-known/openid-configuration).

Restrict access. A registered app is open to all users of the tenant by default. With "Assignment required", only assigned users and groups get through, Global Administrators excepted (Microsoft). Combined with ENABLE_OAUTH_SIGNUP=true, every person in the tenant would otherwise get an account. Assigning groups (instead of individual users) requires Entra ID P1 or P2, and nested groups are not taken into account (Microsoft).

Roles through app roles. Create the app roles admin and user and assign groups; Entra writes them into the claim roles (Microsoft). In Open WebUI, ENABLE_OAUTH_ROLE_MANAGEMENT=true is enough; the defaults OAUTH_ROLES_CLAIM=roles, OAUTH_ALLOWED_ROLES=user,admin and OAUTH_ADMIN_ROLES=admin match.

Groups, with pitfalls. The groups claim contains object IDs by default, and a JWT carries at most 200 groups; for large organisations Microsoft recommends "Groups assigned to the application" (optional claims). Open WebUI contains no Graph lookup for the overflow case (checked in utils/oauth.py). Plain-text names come from groupMembershipClaims: ApplicationGroup and the property cloud_displayname, which only works in that combination.

Email claim. Open WebUI needs email. Microsoft calls the value not guaranteed to be correct and mutable, and advises never to use it for authorisation (claims reference). OAUTH_MERGE_ACCOUNTS_BY_EMAIL should therefore only be active for a limited time, for example to take over local accounts.

Keycloak

  1. Create the client in its own realm (not in master): type OpenID Connect, client authentication on (confidential client), standard flow on. The redirect URI https://chat.example.com/oauth/oidc/callback is compared exactly and case-sensitively; wildcards are only possible at the end of the pattern, and the full wildcard * does not belong in production (Keycloak). The secret is on the "Credentials" tab.
  2. Discovery URL: https://id.example.com/realms/<realm>/.well-known/openid-configuration (Keycloak, endpoints). The variables match the base configuration.

Roles: realm roles are in the claim realm_access.roles by default, but only in the access token and the introspection endpoint (Keycloak, token roles). Open WebUI reads claims from the ID token and userinfo. In the "realm roles" mapper, "Add to ID token" therefore has to be on; then OAUTH_ROLES_CLAIM=realm_access.roles applies (nested paths are allowed) together with OAUTH_ADMIN_ROLES=admin.

Groups: the "Group Membership" mapper with the claim name groups and "Add to ID token" on. "Full group path" is on by default and produces values such as /engineering; switch it off for names without the slash (mapper source code). Then set ENABLE_OAUTH_GROUP_MANAGEMENT=true.

Authentik and ZITADEL

Authentik: an application with an OAuth2/OpenID provider, redirect URI of type "Strict" on /oauth/oidc/callback, discovery at https://<authentik>/application/o/<slug>/.well-known/openid-configuration. Roles come from application entitlements and a scope mapping roles; add OAUTH_SCOPES="openid email profile roles" (Authentik, support level: community). The example there switches off the login form and password login, which removes local emergency access.

ZITADEL: application type Web; ZITADEL recommends PKCE (ZITADEL), in Open WebUI with OAUTH_CODE_CHALLENGE_METHOD=S256. Discovery: <instance>/.well-known/openid-configuration. The role claim urn:zitadel:iam:org:project:roles is an object (role to organisation) (ZITADEL, claims); Open WebUI reads lists or strings. The ZITADEL documentation shows an action (Actions V1) that writes roles as a flat list with values of the form project ID:role into a claim of its own; Actions V1 are planned to be sunset in ZITADEL V5, and new implementations belong on Actions V2 (ZITADEL, migration).

Roles and groups

Roles Groups
Purpose System role user or admin, access at all Rights to models, knowledge bases, tools
Switch ENABLE_OAUTH_ROLE_MANAGEMENT ENABLE_OAUTH_GROUP_MANAGEMENT
Claim OAUTH_ROLES_CLAIM (default roles) OAUTH_GROUP_CLAIM (default groups)
Further variables OAUTH_ALLOWED_ROLES (user,admin), OAUTH_ADMIN_ROLES (admin) ENABLE_OAUTH_GROUP_CREATION, OAUTH_BLOCKED_GROUPS
Claim present, value does not match login rejected with 403 memberships are removed
Claim missing or empty role stays, new users get DEFAULT_USER_ROLE memberships stay unchanged

Group synchronisation is strict: anyone manually added in Open WebUI to a group that is not in the claim loses the membership at the next login, administrators included. Local groups can be excluded with OAUTH_BLOCKED_GROUPS. Role and group changes only apply after a new sign-in (documentation). How groups carry rights is described on the page about groups.

SCIM and offboarding

Open WebUI documents SCIM 2.0 for provisioning users and groups (SCIM documentation). It is enabled with SCIM_ENABLED=true, a random SCIM_TOKEN and SCIM_AUTH_PROVIDER (microsoft or oidc); the base URL is https://chat.example.com/api/v1/scim/v2/. According to the documentation, active: false sets the role to pending and ends the running WebSocket connections, and a pending account is turned away by the API and the WebSocket; administrators can be neither deleted nor demoted through SCIM, and locally created accounts are invisible to SCIM. On v0.12.0, the SSO sign-in of SCIM users failed with 401; since v0.12.1 this is fixed. Neither the SCIM page nor the licence page names a licence restriction for SCIM, and routers/scim.py contains no licence check; the licence text remains authoritative. Entra syncs applications outside the gallery roughly every 40 minutes (Microsoft).

Without SCIM, a blocked account stays usable in Open WebUI until the session token expires. JWT_EXPIRES_IN defaults to four weeks. Without Redis, signing out does not revoke individual tokens, and back-channel logout (ENABLE_OAUTH_BACKCHANNEL_LOGOUT) also needs Redis (SSO troubleshooting). Three routes remain for offboarding: SCIM, Redis with back-channel logout, or a short lifetime of hours to a few days. Administrators end all sessions of an account with "Sign out all devices".

Emergency access and password login

Setting Effect Consequence
ENABLE_SIGNUP=false no local self-registration (default: true) always set
ENABLE_LOGIN_FORM=false form hidden, local registration via API rejected password sign-in via API and at /auth?form=true remains possible
ENABLE_PASSWORD_AUTH=false blocks every password sign-in, API and LDAP included no local emergency access any more
OAUTH_AUTO_REDIRECT=true straight to the provider, only with one provider and ENABLE_LOGIN_FORM=false /auth?form=true shows the local form

The documentation ties ENABLE_PASSWORD_AUTH=false to ENABLE_OAUTH_SIGNUP being on and SSO working, and recommends it for SSO-only instances that are publicly reachable (environment variables). A robust interim state: self-registration off, form hidden, one local administrator with a long password in a vault. Open WebUI offers two-factor sign-in with an authenticator app; SSO logins can be exempted if the identity provider already enforces a second factor. /auth?form=true and /api/v1/auths/signin should only be reachable from the admin network, for example through VPN or NetBird. The full block ENABLE_PASSWORD_AUTH=false is a second step, secured by a test with the identity provider switched off.

Multiple replicas and reverse proxy

  • WEBUI_SECRET_KEY identical on all replicas, otherwise login loops, 401 errors and "Error decrypting tokens". OAUTH_SESSION_TOKEN_ENCRYPTION_KEY takes the same value by default.
  • External PostgreSQL instead of SQLite, Redis (REDIS_URL, WEBSOCKET_MANAGER=redis) and an external vector database (scaling).
  • The proxy does not cache /api, /oauth and /ws and passes WebSocket headers through. Cookies with SameSite=lax; for slow providers OAUTH_TIMEOUT helps.

Typical failure patterns

Symptom Cause Fix
Error at the provider, with Entra AADSTS50011 redirect URI differs: path, case, http instead of https, oidc instead of microsoft register the URI exactly as https://<domain>/oauth/<provider>/callback (Microsoft)
Back at the sign-in page with "Sign-in with your identity provider failed" catch-all message, among others for a failed token exchange, missing email, missing sub claim, domain not allowed; roles that are not allowed or ENABLE_OAUTH_SIGNUP=false report "You do not have permission to access this resource" instead read the backend log
New user waits for approval DEFAULT_USER_ROLE=pending and no role claim set up role mapping or deliberately set user
"Email already registered" local account with the same address merge accounts, for a limited time with OAUTH_MERGE_ACCOUNTS_BY_EMAIL
Loop after login, mismatching_state inconsistent key, cookie settings, proxy cache, deviating WEBUI_URL section on replicas and proxy

Checklist after setup

  • Login with a standard user, an administrator and an unauthorised person; the last one is turned away.
  • New users get the expected role, not an unintended pending.
  • Groups are correct after signing in again; removal at the identity provider takes effect at the next login.
  • Local emergency administrator: password in a vault, two-factor active, access path tested and limited to the admin network.
  • ENABLE_SIGNUP=false; decision on the login form and ENABLE_PASSWORD_AUTH documented.
  • WEBUI_SECRET_KEY persistent and backed up, identical across replicas; image version pinned.
  • Client secret expiry date in the calendar, renewal rehearsed.
  • Offboarding test: block an account at the identity provider and measure when access ends.
  • MFA enforced at the identity provider (Conditional Access or the Keycloak authentication flow).

SSO and licence at WZ-IT

On the AI platform, SSO is included in every package in the monthly price (sign-in with Microsoft Entra ID, Google or Keycloak; packages from €149.90 net per month, depending on the number of users). For an Open WebUI instance in another environment, WZ-IT connects Keycloak or Authentik depending on the environment and plans SSO, groups and roles together with the customer; existing identity providers can be taken over after an interface check. According to the manufacturer's licence page, connecting SSO and LDAP is allowed without an enterprise licence as long as the Open WebUI branding stays visible and unchanged (licence page). The assessment is in the article Open WebUI License 2026 and is not legal advice. WZ-IT runs Open WebUI with the original branding.

As of and methodology

Checked on 28 October 2026 against the Open WebUI documentation, the source code of open-webui/open-webui v0.12.4 (25 October 2026; utils/oauth.py, routers/auths.py, routers/scim.py), the Microsoft Learn pages, the Keycloak documentation including the mapper source code, and the Authentik and ZITADEL pages. The LICENSE file last changed on 14 April 2026. The configurations are derived from documentation and code, not a record of a test run. Not covered: Okta, Google, GitHub, LDAP.

Our approach at WZ-IT

The order of an integration: define roles and groups at the identity provider before the first sign-in runs, set up the local administrator with two-factor sign-in and check the offboarding path, that is the moment access ends after an account is blocked. This includes a fixed WEBUI_SECRET_KEY, a pinned version and a test of emergency access.

Further guides

Run Open WebUI with SSO in production? The AI platform includes SSO in the monthly price from €149.90 net. Book a call

Rather have it operated?

You'd rather not run Local AI for Business yourself? WZ-IT handles setup, operations and maintenance - privacy-focused from Germany.

Enquiry

Assess local AI for your use case

Start with the AI Cube or have us assess a custom AI platform, knowledge connection, or integration.

  • Straight with Timo and Robin - no sales team, no pitch
  • A professional assessment of your situation
  • Concrete next steps for infrastructure, software or AI

The conversation is free and non-binding.

I got to know Timo and Robin as dedicated and professional partners who make a lot of things possible for their clients that initially seem impossible. I felt very well advised. The services offered have thoroughly convinced me. (translated)
Andrea PawlowskiCommunications Manager, Golem.de, Germany
Timo and Robin, founders of WZ-IT

Assess local AI for your use case

I got to know Timo and Robin as dedicated and professional partners who make a lot of things possible for their clients that initially seem impossible. I felt very well advised. The services offered have thoroughly convinced me. (translated)
Andrea PawlowskiCommunications Manager, Golem.de, Germany

Frequently Asked Questions

Answers to the most important questions

Knowledge

More on Local AI for Business

All Local AI for Business articles

Companies worldwide trust WZ-IT

  • Stadtwerke Brühl
  • DGHO e.V.
  • solarwerkstatt berlin
  • Krüger Dirndl
  • ABCO Water Systems
  • Golem.de
  • EVADXB
  • nextGYM
  • AInergy
  • ml&s
  • Odiseo Solutions
  • Annota
  • ARGE
  • SweetConnect GmbH
  • Aphy AG
  • CORGOS
  • Rekorder
  • SolidProof
  • Yonju
  • Keymate
  • Paritel
  • Mr. Clipart
  • Millenium
  • Negosh
  • Führerscheinmacher
  • BTI
  • Deutsche Gesellschaft für Datenschutz
Read client reviews