Adaptive MFA uses rules to intelligently determine when to challenge users based on risk factors and context. Instead of challenging every user every time, you can create policies that balance security with user experience.

How adaptive MFA works

Rules evaluate contextual information about each action to determine the appropriate response:

Common adaptive MFA scenarios

New device detection

Challenge users only when they’re signing in from an unrecognized device:

Implementation:

const response = await authsignal.track({
  userId: user.id,
  action: "signIn",
  attributes: {
    redirectUrl: "https://yourapp.com/callback",
    deviceId: "user-device-id", // Required for device tracking
  },
});

Location-based policies

Apply different authentication requirements based on user location:

  • Known locations: Allow without challenge
  • New countries: Require MFA
  • High-risk regions: Block or require strong authentication

Risk-based authentication

Create rules that consider multiple risk factors:

  • User behavior: Login patterns, time of day, frequency
  • Device characteristics: Known vs unknown devices, device type
  • Network information: IP reputation, VPN detection
  • Transaction context: Amount, recipient, frequency

Business-specific adaptive MFA

You can create rules based on your application’s specific data points. For example, challenge users only for high-value transactions:

Implementation:

const result = await authsignal.track({
  userId: user.id,
  action: "payment",
  attributes: {
    redirectUrl: "https://yourapp.com/callback",
    custom: {
      paymentAmount: 1000,
    },
  },
});

const url = result.url;

Learn more about creating and using business-specific data in rules with custom data points.

Rule examples

Device and location combination

Device is new AND (IP country is not United States OR VPN detected is true)

Transaction pattern analysis

Payment amount is greater than 500 AND 
(daily transaction count is greater than 10)

Integration example

Financial transactions

Progressive authentication for different risk levels:

// Low risk: Allow
// Medium risk: SMS OTP
// High risk: Passkey
const response = await authsignal.track({
  action: "transfer-funds",
  userId,
  attributes: {
    custom: {
      amount: transferAmount,
      dailyTotal: userDailyTotal,
    },
  },
});