Once an account is protected by MFA, the ability to add more authentication methods must only be possible after authenticating with at least two factors. If a user only has to authenticate with one factor in order to add another authentication method to their account, then an attacker can use this to bypass MFA.

In general, we consider a new authenticator as having a strong binding to an existing authenticator if the act of enrolling the new authenticator is authorized by the existing authenticator.

Using the pre-built UI

Requiring a challenge with an existing method

When using the pre-built UI, strong binding between authenticators is handled automatically. This is because the pre-built UI requires the user to complete a challenge with an existing authentication method in order to add a new method within a limited time window (10 minutes by default).

Completing an email OTP challenge to authorize adding a passkey

Skipping the prerequisite challenge

Although the default behavior of the Authsignal pre-built UI is to always require a challenge with an existing authentication method before a new method can be added, it’s possible to allow users to skip this prerequisite step. This can be achieved by passing additional scopes when tracking an action on your server to generate a short-lived pre-built UI URL.

With these additional scopes, the pre-built UI will assume that the user has already been strongly authenticated by another method and allow them to enroll, update or remove authenticators without first requiring a challenge to be completed.

Passing additional scopes to skip the pre-built UI’s prerequisite challenge step can act as an MFA bypass if not used correctly. We highly recommend only using this feature where you’re confident that the user has already been strongly authenticated by another method.

Using Client SDKs

To ensure a strong binding between authenticators, Authsignal Client SDKs for web and native mobile apps support two different ways of adding new authentication methods.

Presenting a challenge with an existing method

Similar to the pre-built UI, with this option you can present a challenge with an existing method (e.g. passkey) in order to enroll a user in a new method (e.g. authenticator app) within a limited time window (10 minutes by default).

Tracking an action to generate a token

Alternatively, you can track an action using a Server SDK or the Server API to generate a time-limited token (valid for 10 minutes by default). This token can be used to authorize adding the new authenticator.

If this is not the user’s first authenticator, you must specify the scope add:authenticators when generating the token.

You should only generate a token with the add:authenticators scope from a context where the user is strongly authenticated. This will ensure a strong binding between different authentication methods.

Then pass the token from your backend to the Client SDK. You can pass the token directly to the relevant method when creating a passkey or adding a push credential or else you can use the setToken method.