Feature-rich webmail client for Nextcloud 33 and 34 with native Single Sign-On via OAuth2
SASL (OAUTHBEARER / XOAUTH2). Users log into Nextcloud via your OIDC provider and open
webmail without a second login or stored mail password.
X2Mail reuses the OIDC access token from the Nextcloud SSO session and uses it for mail protocol authentication.
User -> OIDC provider (Keycloak, Authentik, ...)
-> Nextcloud (user_oidc)
-> X2Mail reads access token from session
-> IMAP/SMTP/Sieve: AUTHENTICATE OAUTHBEARER <token>
-> Mail server validates token (introspection/JWKS)
-> Mailbox opens
The same token is used for IMAP, SMTP submission, and optional ManageSieve. X2Mail refreshes
it through user_oidc before expiry.
After Nextcloud SSO login, users should access mail with the same OIDC access token — no separate webmail password flow.
X2Mail is a webmail client. It does not replace your MTA, gateway, or spam stack.
- IMAP OAuth SASL — server advertises
AUTH=OAUTHBEARERand/orAUTH=XOAUTH2 - SMTP submission OAuth SASL — authenticated sending with the same token model
- OIDC token validation — mail server validates access tokens against your IdP
- Stable mail identity — token claim maps to mailbox address (typically
email) - Optional ManageSieve — if enabled in X2Mail, Sieve endpoint must match host/port/TLS mode
These stacks are tested end-to-end with X2Mail (IMAP + SMTP submission + optional
ManageSieve via OAUTHBEARER / XOAUTH2, Keycloak audience mapping, wizard Test Login):
| Stack | Role | Setup guide |
|---|---|---|
| Dovecot 2.4+ + Postfix | IMAP on Dovecot; SMTP submission auth via Dovecot SASL (oauth2 passdb + OIDC introspection/JWKS) |
dovecot-postfix-oauthbearer.md |
| Stalwart 0.16+ | Integrated IMAP, SMTP submission, and ManageSieve; OIDC validation + optional LDAP directory | stalwart-oauthbearer.md |
IdP configuration (Keycloak example, audience mapper, email claim): keycloak.md.
Any other product is not listed here unless it exposes the same client-facing OAuth SASL on IMAP and submission and you validate it yourself (preflight + wizard Test Login).
Not verified in this project: integrated stacks such as mailcow do not ship a supported, persistent OAuth2 SASL path for external IdPs out of the box (community overrides only; not equivalent to the Dovecot or Stalwart flows above).
Same requirements whether services run on one host or many:
- Split hosts — Nextcloud, mail server, and IdP on different machines/VLANs/sites
- Gateway in transport path — PMG, Rspamd, or another MTA/filter in front of delivery; X2Mail still connects only to the IMAP, SMTP submission, and ManageSieve endpoints of the mail server that performs OAuth SASL
Install and configure the OIDC app:
user_oidc
occ app:install user_oidc
occ user_oidc:provider YourProvider \
-c YOUR_CLIENT_ID \
-s YOUR_CLIENT_SECRET \
-d https://idp.example.com/realms/example/.well-known/openid-configurationocc x2mail:setup sets store_login_token=1 for user_oidc when needed.
Your mail stack must validate OIDC tokens and accept OAuth SASL on client protocols.
Stack-specific setup guides (masked examples, in repository docs/configs/):
These guides are published to the GitHub mirror on release (not shipped inside the Nextcloud app package from the App Store).
The mail server accepts tokens only when:
audincludes the mail-server OIDC client (recommended via audience mapper), or- X2Mail token exchange is configured (
--oidc-audience, optionally--oidc-scopes)
Required claims:
- user identity for mailbox mapping (typically
email)
Details: docs/configs/keycloak.md
Install and enable X2Mail from the official app catalog:
In the Nextcloud web UI: Apps → search X2Mail → Download and enable.
Nextcloud applies updates automatically when a new signed release is published to the App Store.
After installation, configure mail connectivity in Settings → X2Mail or with occ x2mail:setup.
For manual deployment, download a release tarball from GitHub Releases:
cd /path/to/nextcloud/custom_apps
tar xzf x2mail-*.tar.gz
chown -R www-data:www-data x2mail
occ app:enable x2mail
occ x2mail:setup ...The App Store and manual tarball install the same app package; only the delivery path differs.
All X2Mail administration lives in Nextcloud Settings → X2Mail. The settings page exposes:
- Setup wizard — IMAP/SMTP/Sieve hosts + ports + TLS modes, OIDC provider, optional token-exchange audience. Built-in connectivity preflight and a Test Login button that performs a real OAUTHBEARER login against IMAP, SMTP, and ManageSieve using the admin's current SSO token.
- General — app menu title (default X2Mail, native NC menu only), attachment size limit, attachment thumbnails, OpenPGP/GnuPG toggles.
- Advanced — Nextcloud language enforcement, engine
app_path, engine + X2Mail debug logging. - Info — installed X2Mail version + project link.
The legacy SnappyMail-style engine admin panel was removed in 0.7.0.
Dovecot + Postfix (typical STARTTLS listeners):
occ x2mail:setup \
--imap-host mail.example.com \
--imap-port 143 --imap-ssl starttls \
--smtp-host mail.example.com \
--smtp-port 587 --smtp-ssl starttls \
--domain example.com \
--sieve \
--sieve-host mail.example.com \
--sieve-port 4190 --sieve-ssl starttlsStalwart (typical implicit-TLS listeners — verified with X2Mail):
occ x2mail:setup \
--imap-host mail.example.com \
--imap-port 993 --imap-ssl ssl \
--smtp-host mail.example.com \
--smtp-port 465 --smtp-ssl ssl \
--domain example.com \
--sieve \
--sieve-host mail.example.com \
--sieve-port 4190 --sieve-ssl sslPreflight example (the Sieve line appears only when --sieve is enabled):
✓ IMAP mail.example.com:143 (XOAUTH2, OAUTHBEARER)
✓ SMTP mail.example.com:587 (XOAUTH2, OAUTHBEARER)
✓ Sieve mail.example.com:4190 (OAUTHBEARER)
✓ OIDC user_oidc, token_store=ok
Open Settings -> X2Mail:
- Configure IMAP, SMTP, and Sieve in separate sections
- Check connectivity — reachability + advertised OAuth SASL on IMAP/SMTP/Sieve, plus OIDC apps and your SSO session (no mail login)
- Test Login — a real OAUTHBEARER login to IMAP/SMTP/Sieve with your current SSO token
Test Login authenticates as your own admin account — it fails if you have no
mailbox, even when the configuration is correct for other users. The real
token-based login test is only available in the wizard, not via occ (the CLI
has no SSO session).
Example wizard output (connectivity check followed by Test Login):
✓ IMAP mail.example.com:143 (XOAUTH2, OAUTHBEARER)
✓ SMTP mail.example.com:587 (XOAUTH2, OAUTHBEARER)
✓ Sieve mail.example.com:4190 (OAUTHBEARER)
✓ OIDC user_oidc, token_store=ok
✓ SSO Active session with valid token
✓ TOKEN email=user@example.com, aud=nextcloud,mail-service, expires=11min
✓ IMAP login OK
✓ SMTP login OK
✓ Sieve login OK
When a token-exchange audience is configured, the TOKEN line warns if that
audience is missing from the token's aud claim.
The release setup keeps one active domain profile. Saving replaces older stored profiles.
| Option | Default | Description |
|---|---|---|
--imap-host |
(required) | IMAP hostname |
--imap-port |
143 |
IMAP port |
--imap-ssl |
none |
none, ssl, tls/starttls |
--smtp-host |
same as IMAP | SMTP hostname |
--smtp-port |
587 |
SMTP port |
--smtp-ssl |
none |
none, ssl, tls/starttls |
--domain |
(required) | Mail domain (user@domain) |
--oidc-provider |
user_oidc |
user_oidc |
--oidc-audience |
(empty) | Token exchange audience/client (optional) |
--oidc-scopes |
(empty) | Extra scopes requested during token exchange (optional) |
--sieve |
off | Enable ManageSieve |
--sieve-host |
same as IMAP | ManageSieve hostname |
--sieve-port |
4190 |
ManageSieve port |
--sieve-ssl |
none |
none, ssl, tls/starttls |
--skip-checks |
off | Skip connectivity preflight |
Generated domain config uses OAuth SASL only (OAUTHBEARER, XOAUTH2) and enables SMTP auth automatically.
occ x2mail:statusShows domain profile, protocol security modes, OIDC provider, and token-store status.
1. User logs into Nextcloud via OIDC
2. user_oidc stores access token (+ refresh token)
3. User opens X2Mail
4. X2Mail performs IMAP AUTHENTICATE OAUTHBEARER <token>
5. Mail server validates token with IdP and opens mailbox
6. Outbound mail uses SMTP AUTH with the same token
7. Optional Sieve uses the same token model
8. TokenRefreshMiddleware refreshes token via user_oidc
- SSO webmail with OAuth SASL (
OAUTHBEARER/XOAUTH2) - Single active domain profile for SSO users
- Setup wizard with preflight + live token diagnostics
- Real OAuth login test for IMAP/SMTP/Sieve
- Automatic token refresh
- ManageSieve filtering support
- Nextcloud Contacts / Files / Calendar integration
- Multiple identities, OpenPGP / S-MIME
occ x2mail:setup,occ x2mail:status
- Run
occ x2mail:status(autologin/OIDC/domain) - Verify
occ config:app:get user_oidc store_login_tokenis1 - Ensure login happened via SSO, not local Nextcloud password
- Domain in config must match mailbox domain (
user@example.com->example.com)
- Check wizard TOKEN line:
emailpresent? - Check
audincludes your mail-server OIDC client - Verify mail server can reach IdP introspection/JWKS endpoint
- Re-run setup with correct host/port/TLS mode
- Confirm submission endpoint advertises
OAUTHBEARER/XOAUTH2 - Verify generated config has
SMTP.useAuth=true(default in SSO setup) - Check audience and token validation path (same as IMAP)
- Align
--sieve-portand--sieve-sslwith server listener mode - STARTTLS on
4190vs implicit TLS on4190must match exactly - Re-save wizard or re-run
occ x2mail:setupwith corrected sieve options
- Install issuing CA in Nextcloud trust store, or use publicly trusted cert
- Ensure hostname in cert matches configured IMAP/SMTP/Sieve host
openssl s_client -connect mail.example.com:143 -starttls imap -quiet
# CAPABILITY should include AUTH=OAUTHBEARER and/or AUTH=XOAUTH2
openssl s_client -connect mail.example.com:587 -starttls smtp -quiet
# EHLO should include AUTH ... OAUTHBEARER ... XOAUTH2For stack-specific failures, see:
- docs/configs/dovecot-postfix-oauthbearer.md
- docs/configs/stalwart-oauthbearer.md
- docs/configs/keycloak.md
git clone https://github.com/NK-IT-CLOUD/x2mail.git
cd x2mail
make buildSee CHANGELOG.md, RELEASE.md, and SECURITY.md.
Report vulnerabilities privately as described in SECURITY.md.
Permanent fork of SnappyMail v2.38.2, rebuilt for Nextcloud 33+ with native OIDC/SSO.
AGPL-3.0 — see LICENSE.