goauthentik / authentik

The authentication glue you need.
https://goauthentik.io
Other
13.45k stars 898 forks source link

Email OTP #3291

Open ArsNotFound opened 2 years ago

ArsNotFound commented 2 years ago

Is your feature request related to a problem? Please describe. Authentik does not currently support sending OTP to email.

Describe the solution you'd like The emergence of a new OTP stage, where a temporary password is sent to the user by email.

Describe alternatives you've considered N/A

Additional context N/A

AlvinVrolijk commented 2 years ago

Seems like a 'nice to have' idea to me

Lanhild commented 1 year ago

Not sure about the feasability of this, but having a custom email template with a TOTP code as a variable in it might be doable. (Not sure, I have yet to try this)

so-rose commented 1 year ago

+1 for this, would you be open to a PR?

This is vital to my use case. I've been trying to hack it in with Policies, but built-in support really is by far looking to be the only good solution (email sending in Policies is the only hard "this seems like a pretty bad idea" bottleneck, but even given that, I cannot in good faith call crypto code in Policies a solution).

What would it Fix?

Flows which need to include email verification as part of login (ex. seamless registration as first login for validating an external identity by email, email-code-as-password flows great for time-limited accounts, etc.), are exceedingly more intuitive with OTPs than a new flow-restoring link.

Here are the exact problems that email OTP would solve.

Flow Restoration Problems

On flow restore, it seems that the redirect link and application reference are deleted wholesale. This damages onboarding: The user logging in to 'Service X' will, after verifying their email, be dropped into Authentik's internal application overview instead of where they were going.

Moreover, jf they were referred to a particular URL within Service X, the user will have to find that resource by themselves, try to click the original link again, or give up.

A user checking their email on a different device will need to figure out themselves that they need to re-login on the device they were using; this is less impactful, but still feels brittle enough.

With some Policy hacking to persist redirect URLs in prompt_data across flow restoration, or ex. in the user attributes, maybe this can be solveable (at the cost of complexity). But on the whole it would be little more than a band aid; moreover, there would sometimes be cases that a restoring a flow shouldn't restore the redirect URL...

Non-Browser SSO

Users using Mobile or Desktop apps for SSO with an internal browser must, after the email stage is triggered, figure out themselves to do the following:

  1. Close the SSO login in the app. Click away any 'could not login' messages.
  2. Wait for and open the email link, in your real browser. Close the loaded browser tab (keep in mind, the user is just trying to use Service X, and their browser just showed them some strange "Authentik Application List", which probably don't know what is)
  3. Perform the SSO login again, which now magically works since no email stage is triggered.

If Email Verification does happen to be required to login every time (ex. temporary or rarely-used accounts like for event registration services where onboarding friction is extremely costly), then the flow simply cannot be used in such contexts.

Flow Complexity Problems

Seamless registration can already make for complex flows. Currenrly, in my testing, navigating the above issues may already have tired the user out; if the system immediately wants more information to function (like MFA setup), the user might just close the window instead.

Policies related to continuing the login process after restoring from an email token can be error prone alone. Using persistent state to defer ex. MFA Configuration to subsequent logins now results in, together with the token restoration state, at least 4 possible states to handle, and that's before adding more configuration.

With Email OTP, the Email stage simply passes or fails. All flow restoration checks evaporate, and 'prompt on subsequent login' logic is simplified without token restoration cases.

Implementation Idea

First of all, "OTP" and "Link" could be options in the Email Stage. The Link is still the most appropriate for ex. changing an email, or password resets. Alternatively, a new MFA stage for email OTP, which can likely be almost copied from SMS OTP (which I don't use, so please correct me if I'm wrong!)

When run, it would pick 5 words from a dictionary of ~10,000 short words using secrets.choice, seperated by -. This could go through a salted hash and be stored anywhere (ex. in the flow context), along with a timestamp indicating timeout of ~10min - it's not a secret value, and ~66 bits of entropy makes password hashers too heavy. A new template would be designed for sending this.

To the user, the Stage would present a special code field, which it would validate by running the hash and comparing. A "resend" button would simply replace the hash already stored, thereby invalidating it. The validation message could say "only the latest code is valid" if the user clicked resend and the code is wrong (one boolean of internal state).

In sum, this provides easily (human) transferred codes with ~66 bits of entropy, which are resistant to brute force and lookup table attacks. It would fix a significant number of use cases, and enable a few key ones altogether, while involving a relatively small change to one stage.

Workarounds

If one can send emails in Policies, then one could generate the key, send the email, salted hash and store it (no secret keys in Policies), then go to a Prompt stage.

The Prompt stage would have a field (a not so pretty text field, unfortunately) whose validator checks it against the stored hash.

It's not great; this kind of code feels very iffy to run in Policies. For example, not remembering to use salted hashing significantly weakens the code, and direct comparisons without hashing can directly be cracked with timing attacks. Plus, I'm unsure whether there is any way to send an email (or even a webhook via events) from Policies, such that the SMTP server can validate that Authentik is the sender (or whether there even should be...)

Conclusion

This became a bit long, hope it's okay! Let me know if this seems like reasonable idea. I'd be very interested in implementing it if there's interest.

yoo commented 1 year ago

If I'm correct, this is possible.

Create a new flow magic-link-login with Designation: Authentication and add the following stage bindings:

The magic-link-identification stage is an identification stage with User fields: Username,Email . The magic-link-email stage is an email stage with Activate pending user on success: False and a custom email template. For testing, the Account Confirmation template can be used.

Edit the default-authentication-identification stage, set Flow settings -> Passwordless flow: magic-link-login.

On the login page, you now see Use a security key. Click on the link and enter your username/email. You will be sent an email. Hit the Confirm Account button and proceed to log in like always.

The only thing I didn't figure out is if I can change the Use a security key to Passwordless Login or something else.

The question is how good the UX is with Android / iOS using different browsers/webviews, dose the link always work? Is it always possible to copy and past the link?

motey commented 11 months ago

@yoo

The question is how good the UX is with Android / iOS using different browsers/webviews, dose the link always work? Is it always possible to copy and past the link?

this is the crucial point. A human readable/writable OTP would fix that. Email OTP would enable a much more pleasant onboarding experience for non-techi-users. It would enable 2 factor security as soon as the email address is verified. no further steps that need users to fidget around with phones and install apps. I know its less secure as TOTP, but better as nothing or being forced to play first level support the rest of the day.

marcinwierzbicki commented 10 months ago

I think it would also be a good idea to enable the transfer of an e-mail address from an external system, so that authentik immediately sends or fills in the field with the e-mail address.

authentik drawio

ektorasdj commented 9 months ago

+1 for this

motey commented 9 months ago

I think it would also be a good idea to enable the transfer of an e-mail address from an external system, so that authentik immediately sends or fills in the field with the e-mail address.

[image]

Its a good idea but maybe we should keep the issue clean. imho, "magic links mails" and "OTP mails" are separate features for slightly different needs. this issue is about OTP mails.

CoryHawkless commented 7 months ago

+1 for this. It seems to be the standard UX expectation from 'non technical' users Personally I like webauthn but thats a little harder to explain to an average user.

Possibly a seperate feature,but I should be able to have multiple mfa options. E.g webauthn and email otp enabled and I can select which I'd like to use. Github does this well

chibuzoro commented 5 months ago

this feature seems like a no-brainer and I must say for a product that seems well thought out and given it boldly suggest to replace okta etc. this basic use case seems to make the product appear to fall short. I got a rude awakening on this when I demoed this product potential, only to be asked by a would be user (non techie) that why they cannot just get an email sent with a pin they can login with instead of having to jump around figuring the tech tools they need. Now just like some other issues I have seen on here, this feature has been open for almost 2 years now. is there a roadmap for this one can follow. similar to how the invitation stage doesn't offer a mail forward feature out of the box either through api or otherwise.

maksym-connect commented 2 months ago

@chibuzoro I totally agree with you. It's surprising that such a basic feature is missing, especially for a product aiming to compete with solutions like Okta. Given that this request has been open for almost two years, it does make the product feel a bit less ready for everyday use. This kind of feature is really important in the modern authentication space, and it would be awesome to see it added soon. When choosing between open-source solutions, having these key features right out of the box, along with the flexibility to customize, really makes a big difference.