**Summary:** MFA enforcement (`verify_mfa_secret_hash`) appears to be wired only for **internal-directory** accounts. In `crates/common/src/auth/authentication.rs` (v0.16.12) the external-directory auth branch calls `directory.authenticate(credentials)`, which verifies the password but never checks `otp_auth` / calls `verify_mfa_secret_hash` — so accounts backed by an external SQL or LDAP directory cannot have TOTP enforced.
**Use case / who benefits:** deployments that use an external directory as the source of truth — e.g. a hosting control panel that stores mail accounts in its own database and exposes them to Stalwart via the SQL directory. These setups can’t offer working 2FA on mailboxes today.
**What I observed** (v0.16.12, latest; external MySQL directory, `columnSecret` = one hash column):
- Provisioning an `otpauth://…` value as an additional account secret (returned via `columnSecret`) does **not** enforce TOTP — IMAP **and** JMAP still authenticate with the password alone.
- External-directory accounts have no settable `x:Account` object, so the OTP Auth URL can’t be attached via the management API either.
- The Account Manager docs say *“for external directories, administrators provision the OTP Auth URL as an account secret,”* but there doesn’t appear to be a code path that consumes it for the SQL/LDAP auth flow.
**Requested behavior:** enforce TOTP for external-directory accounts — e.g. recognize an `otpauth://`-prefixed value returned by the directory (SQL `columnSecret` row / LDAP attribute) as an MFA requirement in the external-auth path, mirroring the internal `credential.otp_auth` flow. App-password support for these accounts would help too, since mail clients can’t do interactive TOTP.
**Environment:** Stalwart v0.16.12, external MySQL SQL directory.
Thanks!