# Contextual Multi-Factor Authentication (MFA) Learn about how FusionAuth decides to trigger multi-factor authentication (MFA) in the login flow. > For the index of this section of the site, see [llms.txt](https://4002.18-224-161-104.sslip.io/docs/llms.txt) 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](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/multi-factor-authentication.md). ## 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: ```mermaid graph TD isPolicyEnabled[Is MFA Turned On For This Tenant?] --> |No| noChallengePolicy[Do Not Challenge User] isPolicyEnabled --> |Yes| identityProviderLogin[User Logged In Using an Identity Provider?] identityProviderLogin --> |Yes| noChallengeIdentityProvider[Do Not Challenge User] identityProviderLogin --> |No| isUserMFAEnabled[Has the User Set Up MFA?] isUserMFAEnabled --> |No| isUserMFARequired[Is MFA Required By Tenant Or Application?] isUserMFAEnabled --> |Yes| devicePassesContextualCheck[Does the Device Pass Contextual Check?] devicePassesContextualCheck--> |Yes| noChallengeContextualCheck[Do Not Challenge User] devicePassesContextualCheck--> |No| challengeContextualCheck[Challenge User] isUserMFARequired --> |No| noChallengeMFARequired[Do Not Challenge User] isUserMFARequired --> |Yes| promptMFASetupRequired[Prompt MFA Setup] style noChallengePolicy stroke:#00FF00,stroke-width:4px style noChallengeIdentityProvider stroke:#00FF00,stroke-width:4px style noChallengeMFARequired stroke:#00FF00,stroke-width:4px style noChallengeContextualCheck stroke:#00FF00,stroke-width:4px style promptMFASetupRequired stroke:#FF0000,stroke-width:4px style challengeContextualCheck stroke:#FF0000,stroke-width:4px ``` 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](#license-limitations), 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 the following 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 * `ChallengeOnHighRisk`: see [Intelligent MFA](#intelligent-mfa) for more * `ChallengeOnMediumRisk`: see [Intelligent MFA](#intelligent-mfa) for more Here's a diagram of the MFA challenge logic when the tenant has a policy for MFA that is not an Intelligent MFA policy. ```mermaid graph TD applicationMfaPolicy[MFA Policy At Application Level Configured?] --> |True| applicationMfaPolicyControls[Application MFA Policy Controls] applicationMfaPolicy --> |False| tenantMfaPolicy tenantMfaPolicy[What is MFA Policy At Tenant Level?] --> |Disabled| noChallenge[Do Not Challenge User] tenantMfaPolicy --> |Enabled| checkUserConfigEnabled[Check User Has MFA Method] tenantMfaPolicy --> |Required| checkUserConfigRequired[Check User Has MFA Method] checkUserConfigEnabled --> |MFA Configured| contextualMFACheck[Check Request Context] checkUserConfigEnabled --> |No MFA Configured| noChallengeUserConfig[Do Not Challenge User] checkUserConfigRequired --> |MFA Configured| contextualMFACheckRequired[Check Request Context] checkUserConfigRequired --> |No MFA Configured| forceUserToSetupMFA[Prompt User To Set Up MFA] contextualMFACheck --> |Context Check Fails| challenge[Challenge User] contextualMFACheck --> |Context Check Succeeds| noChallengeContextual[Do Not Challenge User] contextualMFACheckRequired --> |Context Check Fails| challengeRequired[Challenge User] contextualMFACheckRequired --> |Context Check Succeeds| noChallengeContextualRequired[Do Not Challenge User] style noChallengeContextualRequired stroke:#00FF00,stroke-width:4px style noChallenge stroke:#00FF00,stroke-width:4px style noChallengeContextual stroke:#00FF00,stroke-width:4px style noChallengeUserConfig stroke:#00FF00,stroke-width:4px style challengeRequired stroke:#FF0000,stroke-width:4px style challenge stroke:#FF0000,stroke-width:4px style forceUserToSetupMFA stroke:#FF0000,stroke-width:4px ``` 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 the following 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 * `ChallengeOnHighRisk`: see [Intelligent MFA](#intelligent-mfa) for more * `ChallengeOnMediumRisk`: see [Intelligent MFA](#intelligent-mfa) for more 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 Policy | Example Application | Notes | | --- | --- | --- | | `Any` | Apps in a [suite of applications](https://4002.18-224-161-104.sslip.io/docs/get-started/use-cases/app-suite.md) 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 the MFA challenge logic when the application has a policy for MFA that is not an Intelligent MFA policy. ```mermaid graph TD applicationMfaPolicy[What is MFA Policy At Application Level?] --> |No Application Policy Present| deferToTenant[Defer To The Tenant Policy] applicationMfaPolicy --> |Disabled| noChallenge[Do Not Challenge User] applicationMfaPolicy --> |Enabled| checkUserConfigEnabled[Check User Has MFA Method] checkUserConfigEnabled --> |MFA Configured| contextualMFACheck[Check Request Context] checkUserConfigEnabled --> |No MFA Configured| noChallengeNoMFAConfigured[Do Not Challenge User] applicationMfaPolicy --> |Required| checkUserConfigRequired[Check User Has MFA Method] checkUserConfigRequired --> |MFA Configured| contextualMFACheckRequired[Check Request Context] checkUserConfigRequired --> |No MFA Configured| forceUserToSetupMFA[Prompt User To Set Up MFA] contextualMFACheck --> |Context Check Fails| challenge[Challenge User] contextualMFACheck --> |Context Check Succeeds| trustPolicyMFACheck[What is the Application MFA Trust Policy?] contextualMFACheckRequired --> |Context Check Fails| challengeRequired[Challenge User] contextualMFACheckRequired --> |Context Check Succeeds| trustPolicyMFACheck trustPolicyMFACheck --> |Any| noChallengeTrustPolicyAny[Do Not Challenge User] trustPolicyMFACheck --> |This Application| trustSource[Is MFA Trust From This Application?] trustSource --> |This Application| noChallengeAppMatch[Do Not Challenge User] trustSource --> |Any Other Application| challengeTrustSource[Challenge User] trustPolicyMFACheck --> |None| challengeTrustPolicyNone[Challenge User] style noChallenge stroke:#00FF00,stroke-width:4px style noChallengeNoMFAConfigured stroke:#00FF00,stroke-width:4px style noChallengeTrustPolicyAny stroke:#00FF00,stroke-width:4px style noChallengeAppMatch stroke:#00FF00,stroke-width:4px style challenge stroke:#FF0000,stroke-width:4px style challengeRequired stroke:#FF0000,stroke-width:4px style challengeTrustSource stroke:#FF0000,stroke-width:4px style challengeTrustPolicyNone stroke:#FF0000,stroke-width:4px style forceUserToSetupMFA stroke:#FF0000,stroke-width:4px ``` 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. For more information, see [plans and features](https://4002.18-224-161-104.sslip.io/docs/get-started/core-concepts/plans-features.md). The following contextual MFA features are limited to the specified plan. ### Enterprise Only * Application MFA policies * Suspicious Login Contextual Check * MFA Requirement Lambda, Including Risk Score * Impossible Travel Intelligent MFA Signal * Client Risk Configuration ### Any Paid Plan * Email MFA * Intelligent MFA Policies * Nine Intelligent MFA Signals * 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](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers.md#account-security). You can override this by using an [MFA requirement lambda](https://4002.18-224-161-104.sslip.io/docs/extend/code/lambdas/mfa-requirement.md) and examining the `authenticationType` parameter. ## Intelligent MFA Available since `1.68.0` [Play](https://youtube.com/watch?v=WwVH_ODLIJU) Intelligent MFA uses [risk signals](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/risk-signals.md) integrated into FusionAuth to determine the risk level of a login attempt. To use these risk signals when determining whether to present an MFA challenge to a user, you can: * choose a tenant login policy of `ChallengeOnHighRisk` or `ChallengeOnMediumRisk` * manually use the aggregate risk level (`LOW`, `MEDIUM`, or `HIGH`) in the `context` of an [MFA requirement lambda](https://4002.18-224-161-104.sslip.io/docs/extend/code/lambdas/mfa-requirement.md) ### Roll Out Intelligent MFA Every user population is different. With Intelligent MFA, you want to reduce challenges for legitimate users, but still challenge when our proprietary algorithm indicates a possibility of an attacker or account takeover. The rollout options differ by plan, because only the Enterprise plan can observe risk without acting on it. #### With an Enterprise Plan On the Enterprise plan, any configured MFA requirement lambda logs `risk` and `riskSignals` to the event log when debug is enabled. You can use this behavior to measure first, then enforce. 1. Collect a baseline (optional). * Enable the `user.two-factor.challenge`, `user.two-factor.success`, and `user.two-factor.failed_attempt` webhooks and collect MFA metrics. You can also read the numbers on the Reactor tab. * Calculate your current challenge rate, which is the number of MFA challenges per DAU or logins. You can pull the denominator using the [reporting API](https://4002.18-224-161-104.sslip.io/docs/apis/reports.md) or the [login API, respectively](https://4002.18-224-161-104.sslip.io/docs/apis/login/export.md). * You can also collect the number of MFA-related customer support requests. 2. Gather the risk scores but do not apply the policy (optional). * Enable an [MFA requirement lambda](https://4002.18-224-161-104.sslip.io/docs/extend/code/lambdas/mfa-requirement.md), but mimic your existing policy so that behavior does not change for your users; see [below for sample lambdas](#mfa-requirement-lambda). * Enable the **debug** toggle on the tenant Multi-Factor tab to log the user Id, composite risk, and riskSignals. If you do not already use an MFA requirement lambda, adding one means the MFA requirement decision is delegated to the lambda. You can use the sample MFA requirement lambdas below. 3. Capture the logs (optional). * Set up an [event log create webhook](https://4002.18-224-161-104.sslip.io/docs/extend/events-and-webhooks/events/event-log-create.md) to capture the logs. Discard any that are not MFA composite risk log events. Store the values, including the composite score and the user Id in a database to analyze. 4. Analyze the logs (optional). * From the log data, compare the count of `HIGH` and `MEDIUM` composite scores to the count of challenges in your baseline. * Review a sample of `HIGH` scores to see if they are legitimate users and `LOW` scores to see if they are not. The two risk policies ignore "trust this device", so users currently skipped by a trusted device are re-evaluated on risk and may be challenged. 5. Pilot risk-based MFA. * Apply an application-level risk-based policy to one non-critical application. This will **require users who don't have MFA to enable it**. * Modify the lambda to challenge on `HIGH` risk for this application. * Keep reviewing the log data and verify challenge volume matches the shadow estimate. * Collect the number of MFA related customer support requests and compare it to the baseline, scaled based on the relative number of logins for this application. 6. Widen risk based MFA rollout. * Expand the application based configuration to more applications. Choose whether to challenge on high or medium/high per application. Use the MFA requirement lambda for any per-application exceptions. * Turn off MFA debugging as you roll risk scoring MFA out further and have more confidence in how your users interact with the MFA challenge. 7. Monitor the rollout. * Continue to calculate your challenge and challenge success rates. * You can also watch the suspicious login webhook (the `threatsDetected` value) for trends in which threats your users detect. To roll back, revert the policy or the lambda to the previous value. This is a configuration change only. #### Without an Enterprise Plan On other paid plans, risk signals are calculated only when a risk policy is enabled, and the policy enforces immediately. There is no shadow mode, so roll out small and reversibly. 1. Record baseline data. Record your current challenge rate from the Reactor tab counts. 2. Pilot risk based MFA. Set "Challenge On High Risk" on a dedicated low-traffic or internal tenant. 3. Measure the impact. Compare the Reactor counts for this tenant to your baseline. 4. Widen the rollout. Enable the policy on additional tenants, one at a time. To roll back, set the policy to your previous MFA policy. ### Example MFA Requirement Lambdas The following example MFA requirement lambda mimics the `Disabled` tenant policy: ```javascript function checkRequired(result, user, registration, context) { result.required = false; } ``` This lambda mimics the `Enabled` tenant policy: ```javascript function checkRequired(result, user, registration, context) { var methods = (user.twoFactor && user.twoFactor.methods) || []; result.required = methods.length > 0; } ``` The following lambda mimics the `Required` tenant policy: ```javascript function checkRequired(result, user, registration, context) { result.required = true; } ``` The following lambda mimics an application policy: ```javascript // Returns true when an existing two-factor trust should bypass the challenge, // per the application's applicationMultiFactorTrustPolicy. function hasValidTrust(context) { // Default to 'Any' to match FusionAuth's default trust behavior when unset. var trustPolicy = (context.policies && context.policies.applicationMultiFactorTrustPolicy) || 'Any'; // 'None' never honors an existing trust. if (trustPolicy === 'None') { return false; } var trust = context.mfaTrust; if (!trust) { return false; } // Reject an expired trust. if (trust.expirationInstant && trust.expirationInstant <= Date.now()) { return false; } // 'This' only honors a trust established by the current application. if (trustPolicy === 'This') { var currentAppId = context.application && context.application.id; return !!currentAppId && trust.applicationId === currentAppId; } // 'Any' honors a valid trust from any application. return true; } function checkRequired(result, user, registration, context) { var policies = context.policies || {}; // Effective login policy: the application overrides the tenant when set. var loginPolicy = policies.applicationLoginPolicy || policies.tenantLoginPolicy; // Does the user have a configured MFA method? var methods = (user.twoFactor && user.twoFactor.methods) || []; var hasMethod = methods.length > 0; // Base requirement from the login policy. var required; if (loginPolicy === 'Required') { required = true; // always challenge; FusionAuth forces enrollment if no method exists } else if (loginPolicy === 'Enabled') { required = hasMethod; // challenge only when the user has a method } else { required = false; // Disabled, or no policy set } // Honor the application trust policy. An existing trust only matters // when a challenge would otherwise occur. if (required && hasValidTrust(context)) { required = false; } result.required = required; } ``` ### Client Risk Configuration Under Tenants -> Your Tenant -> Security , navigate to the `Client risk configuration` section. Enable or disable individual signals with the `Customize risk signals` toggle. When a signal is disabled, it will not be included in any intelligent MFA risk calculations. ![The client risk configuration menu allows you to enable and disable individual risk signals.](https://4002.18-224-161-104.sslip.io/img/docs/lifecycle/authenticate-users/client-risk-configuration.png) ## 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': ```javascript function checkRequired(result, user, registration, context) { if (user.email.includes('gilfoyle')) { result.required = true; } } ``` For more information, see [the MFA requirement lambda documentation](https://4002.18-224-161-104.sslip.io/docs/extend/code/lambdas/mfa-requirement.md). ### 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](https://4002.18-224-161-104.sslip.io/docs/extend/events-and-webhooks/events/user/user-update.md) 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](https://4002.18-224-161-104.sslip.io/docs/apis/two-factor/start-multi-factor.md) to perform this process. For more information, see the [step-up authentication](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/multi-factor-authentication.md#step-up-auth) documentation. ## Limitations On MFA Challenges When you disable an MFA method, any users who previously configured that method can continue to use the method. However, users cannot register a new instance of the disabled MFA method. To remove existing registrations for an MFA method, you must [search for users](https://4002.18-224-161-104.sslip.io/docs/apis/users/search.md) who use that MFA method (e.g. a `queryString` of `twoFactor.methods.method:email` to detect every user registered for email MFA), then script a removal of the MFA method from each User object using the [update a user API](https://4002.18-224-161-104.sslip.io/docs/apis/users/update.md). Related [Lifecycle Risk Signals Learn about the risk signals that FusionAuth uses to identify suspicious activity and influence intelligent MFA decisionmaking. context mfacontextual mfacontext 2fa](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/risk-signals.md) --- ## Other pages in Authenticate Users > For the full index of this section, see [Lifecycle](https://4002.18-224-161-104.sslip.io/docs/llms-lifecycle.txt). - [Application Authentication Tokens](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/application-authentication-tokens.md): Leverage Application specific authentication tokens to speed up certain authentication tasks. - [Add a SAML v2 with ADFS IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/enterprise/adfs.md): Configure SAML v2 for Active Directory Federation Services (ADFS). - [Add an OpenID Connect with Azure AD IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/enterprise/azure-ad-oidc.md): Set up user login using Azure AD/Microsoft Entra ID as an OpenID Connect Identity Provider. - [Add a SAML v2 with Azure AD IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/enterprise/azure-ad-saml.md): Configure SAML v2 for Azure Active Directory (Azure AD)/Microsoft Entra ID. - [Add a OpenID Connect with Cognito IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/enterprise/cognito.md): Set up user login using Cognito as an OpenID Connect Identity Provider. - [Add a HYPR IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/enterprise/hypr.md): Set up user login with HYPR using the HYPR Identity Provider. - [Add an OpenID Connect with Okta IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/enterprise/okta-oidc.md): Learn how to set up user login using Okta as an OpenID Connect Identity Provider. - [Add a SAML v2 IdP-Initiated with Okta IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/enterprise/okta-samlv2-idp-initiated.md): Configure SAML v2 IdP-Initiated SSO With Okta. - [Add a SAML v2 with Okta IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/enterprise/okta-samlv2.md): Configure SAML v2 for Okta. - [Add a SAML v2 IdP-Initiated IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/enterprise/samlv2-idp-initiated.md): Set up user login using a SAML v2 IdP-Initiated Identity Provider. - [External JWT IdP Example Usage](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/external-jwt/example.md): Learn how to federate identity using the External JWT Identity Provider. - [Add an External JWT IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/external-jwt.md): Complete a FusionAuth login with an external JWT from a third party Identity Provider. - [Add an OpenID Connect with Discord IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/gaming/discord.md): Learn how to set up user log in using Discord as an OpenID Connect Identity Provider. - [Add an Epic Games IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/gaming/epic-games.md): Learn more about user login with Epic Games using the Epic Games Identity Provider. - [Add a Nintendo IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/gaming/nintendo.md): Learn more about user login with Nintendo using the Nintendo Identity Provider. - [Add a Sony PlayStation Network IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/gaming/sony.md): Learn more about user login with Sony PlayStation using the Sony PlayStation Identity Provider. - [Add a Steam IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/gaming/steam.md): Learn more about user login with Steam using the Steam Identity Provider. - [Add a Twitch IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/gaming/twitch.md): Learn more about user login with Twitch using the Twitch Identity Provider. - [Add an Xbox IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/gaming/xbox.md): Learn more about user login with Xbox using the Xbox Identity Provider. - [Add an Identity Provider (IdP)](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers.md): An overview of all FusionAuth Identity Providers, which allow authentication delegation. - [Add an OpenID Connect IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/overview-oidc.md): Learn more about user login using an OpenID Connect Identity Provider. - [Add an External SAML v2 IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/overview-samlv2.md): Learn how to set up user log in using the SAML v2 Identity Provider. - [Add an Apple IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/social/apple.md): Learn how to add a login with Apple button to your application. - [Add a Facebook IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/social/facebook.md): Learn how to add a login with Facebook button to your application. - [Add a Github IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/social/github.md): Set up user login using Github as an OpenID Connect Identity Provider. - [Add a Google IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/social/google.md): Learn how to add a login with Google button to your application. - [Add a LinkedIn IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/social/linkedin.md): Learn how to add a login with LinkedIn button to your application. - [Add a Twitter/X IdP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/identity-providers/social/twitter.md): Learn how to add a login with Twitter/X button to your application. - [OIDC & CockroachDB](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/integrations/oidc/cockroachdb.md): Learn how to set up CockroachDB to allow users to log in using FusionAuth via OIDC. - [OpenID Connect Integrations](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/integrations/oidc.md): Examples of OIDC integrations. - [OIDC & Salesforce](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/integrations/oidc/salesforce.md): Learn how to set up Salesforce to allow users to log in using FusionAuth via OIDC. - [OIDC & Tableau Cloud](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/integrations/oidc/tableau.md): Learn how to set up Tableau Cloud to allow users to log in using FusionAuth via OIDC. - [SAML v2 & Aiven](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/integrations/saml/aiven.md): Setting up Aiven to allow users to log in using FusionAuth via SAML v2. - [SAML v2 & Google](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/integrations/saml/google.md): Setting up Google to allow users to log in using FusionAuth via SAML v2. - [SAML](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/integrations/saml.md): Examples of SAMLv2 integrations. - [SAML v2 & PagerDuty](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/integrations/saml/pagerduty.md): Setting up PagerDuty to allow users to log in using FusionAuth via SAML v2. - [SAML v2 & SendGrid](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/integrations/saml/sendgrid.md): Setting up SendGrid to allow users to log in using FusionAuth via SAML v2. - [SAML v2 & Tableau Cloud](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/integrations/saml/tableau-cloud.md): Setting up Tableau Cloud to allow users to log in using FusionAuth via SAML v2. - [SAML v2 & Zendesk](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/integrations/saml/zendesk.md): Setting up Zendesk to allow users to log in using FusionAuth via SAML v2. - [Build a Login Page with the Login API](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/login-api.md): Learn about the Login API and when you would use it. - [JSON Web Tokens](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/login-api/json-web-tokens.md): Learn how FusionAuth provides and manages JSON Web Tokens. - [Logout And Session Management](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/logout-session-management.md): Learn about how FusionAuth handles logout and session management. - [Multi-Factor Authentication (MFA)](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/multi-factor-authentication.md): Learn about how to use multi-factor authentication (MFA) in FusionAuth as a developer. - [OAuth Client Registration | Static and CIMD](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/oauth/client-registration.md): Learn how FusionAuth registers OAuth clients, either ahead of time as Applications or just-in-time from a Client ID Metadata Document. - [OAuth DPoP](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/oauth/dpop.md): Learn how to enable sender-constrained OAuth tokens DPoP (Demonstration of Proof-of-Possession) with FusionAuth and validate DPoP proofs in your APIs. - [Host A Client ID Metadata Document (CIMD)](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/oauth/host-cimd-document.md): Publish a Client ID Metadata Document so your OAuth client can log in to FusionAuth without being registered ahead of time. - [OAuth](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/oauth.md): An overview of how FusionAuth provides an OAuth 2.0 and OpenID Connect SSO login system. - [OAuth Issuer Validation](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/oauth/issuer-validation.md): Learn how to validate the authorization response issuer parameter (RFC 9207) to prevent mix-up attacks. - [Modes](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/oauth/modes.md): An overview of OAuth modes and how OAuth is commonly used. - [OIDC Prompt](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/oauth/prompt.md): Learn about OpenID Connect prompt and example use cases. - [OAuth Response Modes](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/oauth/response-modes.md): Learn about OAuth 2.0 response modes (query, fragment, form_post) and when to use each one. - [Access Control with OAuth Scopes](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/oauth/scopes.md): Learn about OAuth scope policy configuration, managing custom scopes, and using scopes in an OAuth2 workflow. - [OAuth Token Exchange | RFC 8693](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/oauth/token-exchange.md): Learn how to use OAuth Token Exchange with FusionAuth to call downstream services on behalf of a user. - [Manage Software Tokens](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/oauth/tokens.md): Learn about OAuth2 and OpenID Connect Tokens and how they are used. - [URL Validation](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/oauth/url-validation.md): Learn about OAuth URL validation policies in FusionAuth. - [Configure One-Time Passwords](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/one-time-passwords/configure.md): Set up a passwordless experience using magic links and codes. - [Customize One-Time Passwords](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/one-time-passwords/customize.md): Customize the one-time password experience in your application. - [One-Time Passwords](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/one-time-passwords.md): Create a passwordless experience using magic links and one-time passwords. - [Configure Passkeys](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/passkeys/configure.md): Set up a passwordless experience using passkeys. - [Customize Passkeys](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/passkeys/customize.md): Customize the passkey experience in your application. - [Passkeys](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/passkeys.md): An overview of the passwordless capabilities of FusionAuth. - [Risk Signals](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/risk-signals.md): Learn about the risk signals that FusionAuth uses to identify suspicious activity and influence intelligent MFA decisionmaking. - [Host a SAML v2 Identity Provider](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/saml.md): An overview of the SAML Identity Provider capabilities of FusionAuth. - [Setting Up User Account Lockout](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/setting-up-user-account-lockout.md): Learn how to set up user account locking rules. - [Implementing Single Sign-on](https://4002.18-224-161-104.sslip.io/docs/lifecycle/authenticate-users/single-sign-on.md): Learn how to implement single sign-on between applications using FusionAuth.