Combine LDAP (IMAP/SMTP) with external OIDC (Authentik) for JMAP/webmail only?

Your question

Hi, I’m running Stalwart with an LDAP directory (Authentication.directoryId → LDAP, bind auth against OpenLDAP/lldap) for IMAP/SMTP password login across several mail clients (Outlook, iOS Mail, Android). I’d like to add native OIDC login for Bulwark webmail (which supports OAUTH_ENABLED/OAUTH_ISSUER_URL against an external provider, in my case Authentik) — but without breaking existing password-based IMAP/SMTP login for my other devices/family members.

From reading the docs and schema (stalwart-cli describe), it looks like Authentication.directoryId is a single global slot for the whole server, and while Domain.directoryId allows a per-domain override, that still applies to all protocols for that domain, not per-protocol. An OIDC-type Directory object can’t validate passwords, so switching the active directory to OIDC would break IMAP/SMTP login entirely.

Questions:

  1. Is there any supported way to keep LDAP as the directory for IMAP/SMTP/JMAP account lookups, while additionally accepting OIDC bearer tokens (via OAUTHBEARER) from an external provider like Authentik, specifically for JMAP/webmail sessions?
  2. I noticed the LDAP directory’s attrSecretChanged field is described as being used “to determine when to invalidate OAuth tokens” — does this imply LDAP + OIDC/OAuth can coexist in some configuration? If so, is that Stalwart’s own built-in OIDC provider (token issuance) rather than delegating to an external IdP like Authentik?
  3. I found discussion #1398 (LDAP + OAuth2 via pwdChangeTime) and discussion #3095 (Authentik + Bulwark, InvalidIssuer JWT error, unresolved) — is there a current, correct guide for wiring Authentik as an external OIDC directory for Bulwark specifically, without touching the LDAP-based IMAP/SMTP auth?

Happy to share my exact config (redacted) if useful. Thanks!

I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.

on

Based on current docs, the directory is a single, server-wide setting, and there is no per-protocol split.

  1. No, there isn’t a supported way to run LDAP for IMAP/SMTP and simultaneously OIDC-against-Authentik for JMAP/webmail on the same server. The directoryId field on the Authentication singleton selects one Directory object as the authentication backend, and that Directory backs all protocols (IMAP, POP3, SMTP, JMAP) — there’s no protocol-scoped override. The only override is Domain.directoryId, which lets a specific domain use a different Directory, but again that applies to every protocol for that domain, not to JMAP alone. An OIDC-type Directory can’t validate a plaintext password, so pointing directoryId at it would indeed break IMAP/SMTP for anyone without an OAUTHBEARER-capable client.

  2. attrSecretChanged is not about delegating to Authentik. It’s specific to the LDAP directory in bind-authentication mode. Because bind auth never reads a password hash, Stalwart uses that attribute (default pwdChangeTime) purely to detect when an LDAP user’s password changed, so it can invalidate cached tokens issued by Stalwart’s own built-in OAuth/OIDC provider (used for browser/WebUI/JMAP sign-in flows) — not tokens from an external IdP. So this field doesn’t imply LDAP+Authentik coexistence; it’s about Stalwart-as-provider working alongside LDAP-as-directory.

  3. There’s a current OIDC-as-external-provider guide, but it describes the single-directory model above rather than a way to run it side-by-side with LDAP per protocol: OpenID Connect | Stalwart

If Bulwark just needs a way to log webmail users into their Stalwart accounts via Authentik while everyone else keeps LDAP passwords for IMAP/SMTP, the practical options today are: (a) use Stalwart’s own built-in OIDC/OAuth provider for the webmail login (LDAP still backs password verification for all protocols, and Stalwart issues its own tokens after that), or (b) keep the OAUTHBEARER limitation in mind — most non-webmail clients don’t support it anyway, so switching the primary directory to OIDC and issuing app passwords for IMAP/SMTP clients is the documented workaround pattern, though that reverses your priority (LDAP becomes secondary rather than primary). There’s no built-in mechanism to have two independent directories active for different protocols concurrently.

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.

That is correct. One directory is resolved per domain and it serves every protocol and both credential types; there is no per-protocol or per-listener directory field. Only an OIDC-type directory can validate bearer tokens, and only LDAP or SQL can validate passwords, so those two cannot sit on the same domain.

What gets you the outcome you are after is to leave LDAP as the directory and point Bulwark at Stalwart’s own OIDC provider. Users log in with their LDAP password through our authorization endpoint, the token that comes back is one we issued and validate internally, and IMAP and SMTP password auth are untouched. Authentik stays out of the mail path entirely, or sits behind our login if you want it there. Check one thing from the Bulwark side: whether its issuer URL can be pointed at us. I have not verified that myself.

On attrSecretChanged: that is about invalidating tokens Stalwart issued, when the LDAP password changes. Default is pwdChangeTime. It is not a mechanism for an external IdP to signal anything.

If you do insist on Authentik tokens reaching Stalwart directly, your InvalidIssuer is because Authentik mints per-application issuers, so issuerUrl has to be the exact one in the token’s iss claim, not the Authentik base URL. The other trap right behind it is requireAudience, which defaults to “stalwart” and will reject tokens whose aud is your client id. Going that route replaces LDAP for the domain, so IMAP and SMTP would then need app passwords.