Discourse ID and 2FA

@JammyDodger, I’ve recently registered an account at for a free instance:

There, I appear to experience what t/227972 describes, too:

Most documentation appears to indicate that this should be enabled by default:

However, I’ve no option to even enable it, and it’s not enabled by default:

Moved your post here, because this is a different issue than the Contribute > Bug you posted in originally.

Discourse ID is not using OAuth2. It’s functioning, in effect, as an SSO provider, which is different.

To configure 2FA, you’d need to do so at the SSO provider, ID. Specifically https://id.discourse.com/my/preferences/security.

@jomaxro, thanks. Perhaps, what confused me was that I attempted to set enforce_second_factor to “all”, yet wasn’t able to, because I was informed that “You cannot enforce 2FA if local logins are disabled.” If this isn’t too off-topic, what’s the solution to that?

That’s a good question … and one I don’t have the answer too. I’ve looped in the team to find someone who does!

So I’ve been corrected by the team. Discourse ID does use OAuth2 under the hood - my apologies. I thought it was using a different protocol.


To your question, we do not support 2FA with external logins. As the message you saw stated, 2FA cannot be enforced without local logins being enabled. We rely on the external login provider (Discourse ID in this case, but this applies to all external providers) to manage 2FA, including enforcement.

@jomaxro, does that mean that, with the free trial plan, I cannot modify that preference? Alternatively, can I somehow disconnect Discourse ID?

Want to confirm, are you referring to a free trial, or the free plan?

@jomaxro, apologies. Free plan, I believe:

Question for us: Does the IdP pass along the information of whether or not the user performed MFA to the SP?

I’m thinking of the analogous mechanism to U2F / FIDO - the program can ask for an attestation from the device as to the level of user interaction expected/required for the credential.

If Discourse ID… or similarly any other IdP (SAML? oAuth2? OIDC?) passes this information along to the SP it would be a piece of information we could potentially use.

If not we’re kind of stuck needing to implement MFA post-federated login to get this guarantee.

The standards way to do this is via OIDC. Discourse ID is currently built using OAuth2 only. To support an MFA flag, we’d need to implement OIDC on the provider layer and pass the MFA values back and forth for clients that require it.

There are several complications:

  • in Discourse core, we have the option to require 2FA for certain user types only (staff or all), we likely need something similar to be supported via ID
  • ID allows logins via Google/Apple/Facebook/Github – but they don’t reliably say if the user did complete 2FA when logging in… we may need to implement 2FA on the ID layer and also likely double-2FA some users, not ideal
  • is 2FA on the identity provider layer (that is, not on the local instance) sufficient for all consumers? Generally speaking, I think yes, but we’d need to do a bit more research before committing to it