authentik
authentik copied to clipboard
Email OTP
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
Seems like a 'nice to have' idea to me
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)
+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:
- Close the SSO login in the app. Click away any 'could not login' messages.
- 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)
- 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.
If I'm correct, this is possible.
Create a new flow magic-link-login
with Designation: Authentication
and add the following stage bindings:
- magic-link-identification
- magic-link-email
- default-authentication-mfa-validation
- default-authentication-login
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?
@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.
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.
+1 for this
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.
+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