From 40b0cd5e8abff9d1249321f6351f98cf51205c6d Mon Sep 17 00:00:00 2001 From: Christoph Wurst <1374172+ChristophWurst@users.noreply.github.com> Date: Thu, 5 Nov 2026 16:01:55 +0100 Subject: [PATCH] docs(oidc): move admin/user docs to the official documentation Admin- and user-facing docs belong in nextcloud/documentation (nextcloud/documentation#16017), not in this repo's doc/, the same reason doc/admin.md and doc/user.md were removed in 491f4888. doc/oidc-xoauth2.md now covers only the local test environment, same scope as doc/developer.md. Assisted-by: ClaudeCode:claude-sonnet-5 Signed-off-by: Christoph Wurst <1374172+ChristophWurst@users.noreply.github.com> --- doc/oidc-xoauth2.md | 133 ++------------------------------------------ 1 file changed, 6 insertions(+), 127 deletions(-) diff --git a/doc/oidc-xoauth2.md b/doc/oidc-xoauth2.md index 723c361040..7bbc4cdd40 100644 --- a/doc/oidc-xoauth2.md +++ b/doc/oidc-xoauth2.md @@ -3,134 +3,13 @@ - SPDX-License-Identifier: AGPL-3.0-or-later --> -# OpenID Connect (XOAUTH2) for individual mail accounts +# OpenID Connect (XOAUTH2) local test environment -Mail can authenticate a user's IMAP/SMTP connection with an OpenID Connect (OIDC) -access token over the `XOAUTH2` SASL mechanism, instead of storing a password. This -generalises the built-in Google and Microsoft integrations to any OIDC provider -(Keycloak, Authentik, Stalwart, …). - -An administrator registers one or more **OIDC providers**, each matched to accounts by -the user's **email domain**. When a user adds a mail account whose address is in a -configured domain, Mail pre-fills the mail servers and starts an interactive -authorization-code flow: the user consents at the identity provider, and Mail stores -the resulting access and refresh tokens on the account. - -> This is the *individual account* flow (the user runs the consent popup themselves). -> Automatic provisioning of accounts without user interaction is a separate feature. - -## How it works - -``` -Admin registers provider ─► email_domain + IMAP/SMTP host/port/ssl - + client_id/secret + discovery URL + scopes - │ -User adds account (alice@example.com) ─► domain matches provider → hosts pre-filled - │ -Popup → provider authorization endpoint → consent → redirect back with code - │ -Server exchanges code for tokens (confidential client, secret stays server-side) - │ -IMAP/SMTP over XOAUTH2; the access token is refreshed automatically before it expires -``` - -- **Matching key: email domain.** One provider per domain. The provider is a full - connection template for that domain (separate IMAP and SMTP host/port/SSL). -- **Confidential client.** The code→token exchange runs on the server, so the client - secret is never exposed to the browser. PKCE is not required (but the flow tolerates - providers that mandate it). -- **Endpoints come from discovery.** By default only the discovery URL - (`…/.well-known/openid-configuration`) is stored; the authorization and token - endpoints are fetched from it and cached. Providers without a discovery document - can instead define these endpoints manually (see below). -- **Refresh tokens** are used to keep the connection alive for background sync, so the - default scopes include `offline_access`. - -## Admin configuration - -1. Open **Administration settings → Groupware → Mail** and find the - **OpenID Connect integration** section. -2. Click **Add OIDC provider** and fill in: - - **Display name** – free-text label. - - **Email domain** – e.g. `example.com`. Accounts with an address in this domain use - this provider. - - **IMAP** and **SMTP** – host, port and encryption (SSL/TLS, STARTTLS or none). - Defaults are `993`/SSL and `587`/STARTTLS. The two hosts may differ. - - **Discovery endpoint** – the provider's `.well-known/openid-configuration` URL. - Alternatively, tick **Manually define endpoints** and enter the **Authorization - endpoint** and **Token endpoint** directly — useful for identity providers that - don't publish a discovery document, or to override it. An **Introspection - endpoint** is optional (see [below](#when-the-grant-can-no-longer-be-renewed)). - When manual endpoints are used the discovery URL is ignored. - - **Client ID** / **Client secret** – credentials of the OAuth client you register - with your identity provider (see below). The secret is stored encrypted and shown - back only as a placeholder. - - **Scopes** – defaults to `openid email offline_access`. -3. **Save.** - -### Registering the OAuth client with your provider - -Create a confidential (web) OAuth client in your identity provider and authorize this -**redirect URL** (shown in the provider form): - -``` -https:///index.php/apps/mail/integration/oidc-auth -``` - -Grant the client the scopes it needs to issue mail tokens and refresh tokens, and make -sure the access token it issues is accepted by your IMAP/SMTP server for `XOAUTH2`. - -## User setup - -1. In Mail, choose **Add mail account** and enter the email address (e.g. - `alice@example.com`). -2. If the domain matches a configured provider, the server fields are filled in and a - single sign-on notice appears. Continue. -3. A popup opens at your identity provider. Sign in and grant access. -4. The account is created and syncs over XOAUTH2 — no password is stored. - -## Token refresh - -Before each IMAP connection Mail checks whether the access token is about to expire and, -if so, refreshes it with the stored refresh token. This runs during background sync as -well, so accounts keep working without user interaction as long as the refresh token is -valid. If the provider rotates refresh tokens, the new one is stored on every refresh, so -a regularly syncing account keeps rolling its grant forward. - -## When the grant can no longer be renewed - -The refresh token itself eventually expires or is revoked — for example after an extended -outage where nothing synced, or if the provider never issued one (no `offline_access`). -OAuth defines no way to know that lifetime up front, so Mail reacts to it instead: - -1. A refresh that fails is not trusted on its own — the provider may simply have been - unreachable. Mail asks the provider's **introspection endpoint** (RFC 7662) whether the - refresh token is still active. -2. Only a definitive `active: false` (or having no refresh token at all while the access - token has expired) marks the account as needing re-authentication. A network error or - an unavailable introspection endpoint is treated as transient and changes nothing. -3. The next time the user opens Mail, a dialog offers to **Reconnect**, which runs the - same consent popup as the initial setup and restores the account. The flag is cleared - automatically as soon as any refresh or reconnect succeeds. - -> With a discovery URL, the introspection endpoint is taken from the discovery document's -> `introspection_endpoint`. With manually defined endpoints, it is used only when the -> optional **Introspection endpoint** is filled in. Without an introspection endpoint a -> failed refresh is always treated as transient and the account is never flagged -> automatically. - -## Troubleshooting - -- **No SSO notice when adding the account** – the email domain does not exactly match a - configured provider's *Email domain*. Matching is case-insensitive but otherwise exact. -- **Popup returns but the account is not authorized** – check the Nextcloud log - (`mail` app). Common causes: the redirect URL is not authorized at the provider, the - discovery URL is unreachable, or the client secret is wrong. -- **Authentication fails at IMAP/SMTP** – the mail server must accept the provider's - access token for `XOAUTH2`. Verify the token audience/scope expected by your mail - server. -- **Discovery changes are not picked up** – the discovery document is cached for a short - time; wait for the cache to expire or restart PHP workers. +Admin and user documentation for the generic OIDC/XOAUTH2 integration (registering a +provider, how accounts connect, troubleshooting) lives in the +[official documentation](https://docs.nextcloud.com/server/latest/admin_manual/groupware/mail.html), +not here. This file covers only how to stand up a local identity provider and mail +server pair for development, since that setup doesn't belong in the admin manual. ## Setting up a local test environment