Contextual Multi-Factor Authentication (MFA)
Overview
This page explains why and how FusionAuth asks for MFA during the login process.
For guidance on implementing MFA using FusionAuth, see the MFA documentation.
When is MFA Required?
FusionAuth displays an MFA challenge to the user when a login attempt meets one of the following criteria:
- Does the tenant or application enable or require MFA?
- Has the user provided an MFA method?
- Did the user log in using an Identity Provider such as Google or OIDC? In this case, MFA is never required.
- Has the device passed appropriate contextual checks, such as using a known device?
The following diagram shows the FusionAuth MFA logic:
High level diagram of MFA logic.
Contextual Checks
Contextual checks are based on attributes of the request evaluated every time a user authenticates. These checks include:
- Has this device been seen before?
- Has this user been seen before on this device?
- Is there a suspicious login detected for this authentication attempt?
The duration of trust of the device can be configured with the tenant.externalIdentifierConfiguration.twoFactorTrustIdTimeToLiveInSeconds configuration value.
The goal of this contextual check is to challenge the user for another factor of authentication whenever FusionAuth determines the risk of invalid access outweighs user friction.
Depending on your license, you can configure MFA policies at both the tenant and application level.
Tenant MFA Configuration
Tenant configuration applies to all applications within a tenant. The MFA policy has three values:
Disabled: no MFA challenge occursEnabled: an MFA challenge occurs only if the user has a valid MFA methodRequired: an MFA challenge always occurs, requires users without MFA to configure an MFA method
Here’s a diagram of the MFA challenge logic when the tenant has a policy for MFA.
Diagram of tenant MFA decision logic.
Application MFA Configuration
Application configuration applies to a single application within a tenant. Application policies always supersede the tenant policy.
With an active application MFA configuration, there is an MFA policy with three possible values:
Disabled: no MFA challenge occursEnabled: an MFA challenge occurs only if the user has a valid MFA methodRequired: an MFA challenge always occurs, requires users without MFA to configure an MFA method
An additional trust policy determines if an application accepts the results of other MFA challenges with the following options:
Any: any application’s challenge results are acceptableThis: only this application’s challenge results are acceptableNone: no application’s challenge results are acceptable, always displays an MFA challenge
Here’s a table outline possible scenarios for different trust policies.
| Trust Policy | Example Application | Notes |
|---|---|---|
Any | Apps in a suite of applications such as Google Drive, Google Calendar and Gmail | Any MFA challenge is good enough since they all have roughly the same risk profile. |
This | A gambling application which uses real money in a suite which has other fantasy gaming apps. | The other fantasy gaming apps might not require MFA at all, but if they do, it’s not a high enough level of security for the “real money” gambling application. |
None | An internal admin dashboard | Access should be strictly controlled and user friction is not an issue. |
Here’s a diagram of MFA challenge logic when the application has a policy for MFA.
Diagram of application MFA decision logic.
License Limitations
Not all plans support all MFA features. The plan you are on affects the MFA options available to you and your users. Learn more about plan features and pricing.
The following contextual MFA features are limited to the specified plan.
Enterprise Only
- Application MFA policies
- Suspicious Login Contextual Check
Any Paid Plan
- Email MFA
- SMS MFA
- User MFA Enrollment Account Management Pages
Any Plan
- TOTP MFA
- Tenant MFA policies
- User MFA Enrollment APIs
- Application MFA policies for the FusionAuth Admin UI only
MFA Challenges After Identity Provider Login
If a user logs in with an Identity Provider such as Google or OIDC, FusionAuth does not challenge for MFA. FusionAuth trusts that the correct MFA challenge process happens at Identity Provider.
There’s an open issue to add a policy to allow for more control in this scenario.
Custom MFA Logic
You may need more granularity on who is challenged for an additional factor during login. For example, you might want everyone who is a member of a certain group or has a certain user.data field to complete an MFA challenge.
To customize MFA to meet your needs, use one of the following methods:
MFA Requirement Lambda
Under Customization -> Lambdas , create a new Lambda of type “MFA requirement lambda”.
The following example forces an MFA check for any user whose email address includes the string ‘gilfoyle’:
function checkRequired(result, user, registration, context) {
if (user.email.includes('gilfoyle')) {
result.required = true;
}
}
For more information, see the MFA requirement lambda documentation.
Use a Webhook
- Set a tenant or application policy to
Enabledand then use the API to ensure that everyone in themfa_requiredgroup has an MFA method. - Use a transactional
user.updatewebhook to ensure that the MFA method can’t be removed while the user is in that group. - Set the trust duration to be the same or less than your session length.
- If you are using the application policy, set the trust policy to
This.
Redirect Users Through a Special Application
The following example guarantees that all users in the mfa_required group are challenged with MFA whenever they log in:
- Create an “MFA check” application with an MFA policy of
Requiredand a trust policy ofNone. - After a user logs in, examine their profile on an interstitial page.
- If they are in the
mfa_requiredgroup, redirect them to this application. They will be prompted for MFA and then redirected to the initial application. - Users that are not in the
mfa_requiredgroup can be sent directly through to the application.
- If they are in the
Make sure the MFA check application uses a lambda to set the aud and applicationId claims to values expected by any access token consumers.
This is similar to doing a conditional step-up authentication on the interstitial page, without using the step-up API.
MFA Challenges Outside Of The Login Process
If you need to prompt for MFA outside of the login process, use step-up authentication. For example, you could display an MFA challenge when a user performs a high-risk action like initiating a money transfer. Use the 2FA API to perform this process.
For more information, see the step-up authentication documentation.
Limitations On MFA Challenges
There’s an open issue about unexpected MFA behavior and workarounds when a user logs in with an identity provider but SSOs to an application with a login policy of Required.
If a user signs up with an MFA method that is allowed for a tenant, such as email, and the tenant configuration changes later to disable that MFA method, the user can still use that MFA method. Users cannot, however, add disabled MFA methods. If you are disabling an MFA method previously in use, it’s recommended you search for users using that method and remove it using a script, updating each user.