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:

No
Yes
Yes
No
No
Yes
Yes
No
No
Yes
Is MFA Turned On For This Tenant?
Do Not Challenge User
User Logged In Using an Identity Provider?
Do Not Challenge User
Has the User Set Up MFA?
Is MFA Required By Tenant Or Application?
Does the Device Pass Contextual Check?
Do Not Challenge User
Challenge User
Do Not Challenge User
Prompt MFA Setup

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 occurs
  • Enabled: an MFA challenge occurs only if the user has a valid MFA method
  • Required: 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.

True
False
Disabled
Enabled
Required
MFA Configured
No MFA Configured
MFA Configured
No MFA Configured
Context Check Fails
Context Check Succeeds
Context Check Fails
Context Check Succeeds
MFA Policy At Application Level Configured?
Application MFA Policy Controls
What is MFA Policy At Tenant Level?
Do Not Challenge User
Check User Has MFA Method
Check User Has MFA Method
Check Request Context
Do Not Challenge User
Check Request Context
Prompt User To Set Up MFA
Challenge User
Do Not Challenge User
Challenge User
Do Not Challenge User

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 occurs
  • Enabled: an MFA challenge occurs only if the user has a valid MFA method
  • Required: 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 acceptable
  • This: only this application’s challenge results are acceptable
  • None: no application’s challenge results are acceptable, always displays an MFA challenge

Here’s a table outline possible scenarios for different trust policies.

Trust PolicyExample ApplicationNotes
AnyApps in a suite of applications such as Google Drive, Google Calendar and GmailAny MFA challenge is good enough since they all have roughly the same risk profile.
ThisA 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.
NoneAn internal admin dashboardAccess 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.

No Application Policy Present
Disabled
Enabled
MFA Configured
No MFA Configured
Required
MFA Configured
No MFA Configured
Context Check Fails
Context Check Succeeds
Context Check Fails
Context Check Succeeds
Any
This Application
This Application
Any Other Application
None
What is MFA Policy At Application Level?
Defer To The Tenant Policy
Do Not Challenge User
Check User Has MFA Method
Check Request Context
Do Not Challenge User
Check User Has MFA Method
Check Request Context
Prompt User To Set Up MFA
Challenge User
What is the Application MFA Trust Policy?
Challenge User
Do Not Challenge User
Is MFA Trust From This Application?
Do Not Challenge User
Challenge User
Challenge User

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

  1. Set a tenant or application policy to Enabled and then use the API to ensure that everyone in the mfa_required group has an MFA method.
  2. Use a transactional user.update webhook to ensure that the MFA method can’t be removed while the user is in that group.
  3. Set the trust duration to be the same or less than your session length.
  4. 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:

  1. Create an “MFA check” application with an MFA policy of Required and a trust policy of None.
  2. After a user logs in, examine their profile on an interstitial page.
    1. If they are in the mfa_required group, redirect them to this application. They will be prompted for MFA and then redirected to the initial application.
    2. Users that are not in the mfa_required group can be sent directly through to the application.

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.