See PHI912. Broadly, I believe Duo is likely the best technical solution for "better-than-TOTP" MFA available today given that U2F lacks broad support, Yubikey OTP is a weird thing that normal users likely can't hope to figure out (see T8787 for both), and we're missing hardware capabilities on mobile to do this ourselves (push notifications, NFC; see T13230).
But, since Duo is a Cisco "Contact Sales" outfit that unironically has a "Success Planning" graphic, I'm looking at not bringing support upstream into the core. See T13229.
Duo Auth API:
The API generally seems fairly sane except that a couple calls are a little more synchronous than I'd ideally prefer. Support will look something like this:
- MFA providers will become generalized and concrete. TOTP has no configuration today (although stuff like window size could be made configurable). Duo will get a key.
- The "add a factor" flow will /enroll the user. I think we'll use their PHID as their username since we'll run into trouble if we use their actual username and users swap usernames later.
- The "remove a factor" flow will do nothing? There's no way to un-enroll a user? I guess it will just say "delete this thing on your phone". We could ping /enroll_status until their enrollment becomes invalid.
- The "mfa gate" flow will /preauth a user, then let them pick a device? We can also "auto" the device if we don't want to bother with this. We may need a way for a factor implementation to provide a "okay, keep going" response. This may return enroll if they delete Phabricator from their phone but don't delete the factor in Settings.
- Once the user picks a device, we /auth them to push a request with async. The transaction ID becomes the challenge key.
- We can verify with /auth_status plus an explicit timeout. This API is a little weird, and an endpoint which returns immediately would be a better fit on our end (this endpoint does not return until there is a status update). This flow could move to JS to become slightly less weird but we don't really want HTTP processes sitting there indefinitely waiting for users to push buttons on their phones.
At least for now, we will probably only support Duo Push since the other factors are kind of junk and I assume everyone uses Duo Push.