authn-server
authn-server copied to clipboard
Add support for Multifactor Authentication (MFA / TFA)
Is this something you would consider/have considered? It seems to me like it would be an appropriate features to situate in authn-server and It's something I need.
For example, by integrating: https://github.com/pquerna/otp
I would be willing to work on this, if you have some initial guidance then I could give a draft design / implementation proposal.
@silasdavis Yes! I agree that MFA is in scope and TOTP is a good place to start.
Eventually I'd like to also support delivered codes (email or SMS), so it'd be ideal if the implementation considered those to minimize migrations and API changes later.
Recovery codes should be in scope. They should not live in plaintext, though. Might be best to treat them like passwords.
I'm uncertain about an admin API for disabling MFA. On the one hand, it could improve the ability to support account recovery. On the other hand, it could be nice for MFA to offer protection against abuse of the admin API. Let's defer this decision, since that's the more secure position.
What's your recommendation for remembering a secret while waiting for the user to validate it?
AuthN should eventually be able to support both optional and required MFA. I suspect that starting with optional MFA is the best (and most desirable) MVP, since required MFA will add complexity to onboarding new and existing accounts. Thoughts?
When you draft a proposal, please look for opportunities to review and merge the feature in discrete steps. I don't expect this to be a trivial change!
Eventually I'd like to also support delivered codes (email or SMS)
A bit like in #94 this makes me wonder about more general ways for authn to 'push back' on certain hooks.
What's your recommendation for remembering a secret while waiting for the user to validate it?
Encrypt and store in Redis I suppose...
I think admin-disabling MFA should probably be an option, probably also need to facilitate a compulsory MFA login - for which the application would need to be able to distinguish a logged in user without MFA from a logged in user with MFA and require them to enable MFA. We might be able to defer this but probably worth having a vague idea.
It will probably be a few weeks before I am ready to get to this, but should have a better feel for the codebase by then
We might be able to defer [compulsory MFA logins] but probably worth having a vague idea.
Yeah, it's worth peeking ahead. For example, if MFA is implemented as a failure code during login then it'd be easy to reply with failure codes that tell the client what to do next (collect MFA or onboard MFA).
But perhaps the complexity in compulsory MFA really lives in the onboarding process, since the onboarding APIs would need to work with half-authenticated users.
When you say onboarding APIs, to what are you referring, just to be clear?
The APIs necessary to add MFA to an account
I'd like to help with this, TOTP specifically. I've created a simple implementation (#132) with one endpoint /totp that allows an authenticated user to enable TOTP on their own account. A logged in user can call GET /totp to get the QR code, then they POST /totp the generated code to enable it on their account. There's also DELETE /totp to remove TOTP from their account. If TOTP is enabled on their account and they attempt to POST /session (login) then they have to have a valid TOTP code sent with their username/password for the session to be created.
There's a few issues though:
I'm not sure where to mount the api. Password updating for an authenticated user is /password so I just mounted the endpoint at /totp. I'm not sure this is the best place for it, which leads me to my second point:
Eventually I'd like to also support delivered codes (email or SMS), so it'd be ideal if the implementation considered those to minimize migrations and API changes later.
I'm not sure how to structure this to combine the totp api with other 2FA methods/endpoints in the future. Suggestions and pointers would be helpful.
Yeah, it's worth peeking ahead. For example, if MFA is implemented as a failure code during login then it'd be easy to reply with failure codes that tell the client what to do next (collect MFA or onboard MFA).
But perhaps the complexity in compulsory MFA really lives in the onboarding process, since the onboarding APIs would need to work with half-authenticated users.
I really don't know a good solution for having required MFA at the Authn level with onboarding. With the TOTP MFA flow, the user would have to have the totp secret generated and stored with an associated username/password combination before the account is fully created. I think it would have to be in a 'account created but not activated' state or a half-authenticated user like was mentioned. I don't know how that would work in practice. The MFA is optional in the code I have.
@thenhawke thanks for taking the lead on this! i'll respond further in your pull request when i've had a chance to study it.