Platform
Platform
Drop-In Authentication
Passkeys
Phishing-resistant, FIDO2/WebAuthn
Biometric authentication
Face and device-native biometrics
WhatsApp OTP
Global reach, lower cost than SMS
Email OTP
Universal second factor
App push authentication
Native device push notifications
Palm biometrics
Contactless identity verification
All authentication methods
KEY FEATURES
No-code rules engine
Step-up auth, risk policies, alerts
User observability
Audit trails, dynamic linking
Risk-based authentication
Adaptive MFA by context
Session management
Persistent sessions across channels
Digital credentials API
Verify sovereign digital IDs
Pre-built UI
Fastest deployment path
Passkeys
Deploy phishing-resistant passkeys across web and mobile in days
Solutions
Solutions
USE CASE
Account Takeover Prevention
Stop ATO without adding friction
Go Passwordless
Replace passwords with passkeys
Account Recovery
Secure self-service recovery flows
Call Centre Authentication
Verify callers without KBA
SMS Cost Optimisation
Cut OTP costs up to 90%
Existing Apps (Drop-In)
Add auth without re-architecting
Palm biometric payments
Contactless in-store payments
INDUSTRY
Financial Services & Banking
Secure high-value transactions
Healthcare
Authentication for ePHI access
Loyalty Programs
Protect points and member accounts
ROLE
Engineering
Fast integration, flexible SDKs
Product
No-code flows, conversion insights
Cybersecurity
Risk policies, compliance, audit trails
PricingCustomers
Resources
Resources
LEARN
Blog
Guides
Regulatory
Templates
Docs
COMPANY
About Us
Why Authsignal
Partners
Careers
Security
Contact
INTEGRATIONS
Amazon Cognito
Auth0
Azure AD B2C
Custom identity provider
Duende IdentityServer
All integrations
Docs
Start a trial
Book a callLogin
AUS Flag

Authsignal secures millions of passkey transactions out of our hosted Sydney region.

AUS Flag

Authsignal secures millions of passkey transactions out of our hosted Sydney region.

Join us today!
Right icon
Blog
/
Current article
Passkeys
Multi-factor authentication
Adaptive MFA
Implementation
Risk based authentication

How to implement adaptive MFA with passkeys for smarter, risk-based authentication

Ashutosh Bhadauriya
⬤
August 12, 2025
Share
How to implement adaptive MFA with passkeys for smarter, risk-based authentication

In our previous blog, we explored how you can use passkeys for step-up authentication, providing biometric verification for high-value transactions. Today, we're taking that concept further by diving into adaptive MFA, where security decisions are made intelligently based on real-time risk assessment rather than fixed rules.

Imagine you're using your banking app at home, transferring $500 to pay rent. The transaction goes through seamlessly. Later, you're on vacation connecting through a public WiFi to send $100 to a friend, and suddenly you're prompted for additional verification. That's adaptive MFA in action.

Unlike traditional step-up authentication that only looks at transaction amounts, adaptive MFA considers multiple risk factors: Are you connecting from an anonymous IP? Are you in an unusual location? Is this transaction pattern normal for you? A $10,000 transfer from your home IP might be perfectly safe, while a $50 transfer from an anonymous VPN could signal account compromise.

‍

What we're building

We’ll build a smart money transfer app that adapts its security based on real-time risk assessment. Here's how our adaptive MFA in the app works:

Anonymous/risky IPs: Always require passkey verification for connections from VPNs, Tor, or suspicious IP rangesTrusted IPs + high value: Require verification for transactions over $2,000 from known good IPsTrusted IPs + low value: Allow transactions to proceed seamlessly

This way, your regular IP addresses will become trusted over time, while suspicious network activity gets flagged immediately.

‍

Architecture overview

The system has four key components:

IP Risk Assessment: Authsignal automatically identifies anonymous IPs, VPNs, Tor networks, and suspicious IP ranges.

Risk Assessment: Every transaction is evaluated against configurable rules that consider IP reputation, transaction amount, and other risk factors.

Adaptive Challenge: When risk is detected, users get a passkey prompt. Low-risk transactions flow through without friction.

Continuous Learning: The system learns IP patterns over time, reducing false positives while maintaining security.

‍

Set up rules in Authsignal

Before we dive into the code, we need to configure our adaptive MFA rules in the Authsignal Portal.

Create the action: Navigate to the Actions section in your Authsignal dashboard and create a new action called adaptive-mfa-transfer.

Create and configure rules: Head to the Rules tab and set up your risk-based conditions. Set the outcome to "Challenge" and add these conditions. Don’t forget to set the rule outcome to ‘Challenge’.

  • IP is anonymous = True → Challenge
  • transactionValue > 2000 → Challenge

‍

This means users will be prompted for verification when connecting from anonymous IPs or when making high-value transfers from trusted networks.

‍

Implementation

Now, let's build the app:

Install packages:

npm install @authsignal/node @authsignal/browser

‍

Grab your Authsignal credentials:

// lib/authsignal.ts
import { Authsignal } from '@authsignal/node'

export const authsignal = new Authsignal({
  apiSecretKey: process.env.AUTHSIGNAL_API_SECRET_KEY,
  apiUrl: 'https://api.authsignal.com/v1', // your region api url
})

export const authsignalConfig = {
  tenantId: process.env.NEXT_PUBLIC_AUTHSIGNAL_TENANT_ID,
  baseUrl: 'https://api.authsignal.com/v1', // your region api url
}

‍

Passkey enrollment

Before adaptive MFA can work, users need passkeys enrolled.

Backend enrollment endpoint:

// api/passkey/enroll/route.ts
export async function POST(request: NextRequest) {
  const userId = await getUserId()

  // Tell Authsignal we want to start passkey enrollment
  const response = await authsignal.track({
    userId,
    action: 'enroll-passkey',
    attributes: { scope: 'add:authenticators' },
  })

  return NextResponse.json({ token: response.token })
}

‍

Frontend enrollment flow:

// components/passkey-manager.tsx
const enrollPasskey = async () => {
  try {
    // Step 1: Get enrollment token
    const challengeResponse = await fetch('/api/passkey/enroll', {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${authToken}` }
    })
    const { token } = await challengeResponse.json()

    // Step 2: Create passkey
    const passkeyResponse = await authsignalClient.passkey.signUp({
      token,
      username: userEmail,
    })

    // Step 3: Validate enrollment
    if (passkeyResponse.data?.token) {
      const validationResponse = await fetch('/api/passkey/validate', {
        method: 'POST',
        body: JSON.stringify({ token: passkeyResponse.data.token }),
      })

      if (validationResponse.ok) {
        setIsEnrolled(true)
        setMessage('Passkey successfully enrolled!')
      }
    }
  } catch (error) {
    console.error('Enrollment failed:', error)
  }
}

‍

Adaptive MFA Implementation

Transaction verification:

// api/passkey/verify-transaction/route.ts
export async function POST(request: NextRequest) {
  const userId = await getUserId()
  const { amount, recipient } = await request.json()
  
  // Get client context
  const userAgent = request.headers.get('user-agent') || ''
  const ipAddress = request.headers.get('x-forwarded-for') || 
                   request.headers.get('x-real-ip')

  // Let Authsignal evaluate risk and decide
  const response = await authsignal.track({
    userId,
    action: 'adaptive-mfa-transfer',
    attributes: {
      userAgent,
      ipAddress,
      custom: {
        transactionValue: amount
      }
    }
  })

  if (response.state === 'CHALLENGE_REQUIRED') {
    return NextResponse.json({
      requiresVerification: true,
      token: response.token,
      message: `Security verification required for ${amount.toFixed(2)} transfer`
    })
  } else if (response.state === 'ALLOW') {
    return NextResponse.json({
      requiresVerification: false,
      message: 'Transaction approved'
    })
  }
}

‍

Challenge the user

// components/passkey-challenge.tsx
const performPasskeyVerification = async () => {
  try {
    // Perform passkey authentication
    const passkeyResponse = await authsignalClient.passkey.signIn({
      action: 'adaptive-mfa-transfer'
    })

    if (passkeyResponse.data?.token) {
      // Validate the verification
      const validationResponse = await fetch('/api/passkey/validate', {
        method: 'POST',
        body: JSON.stringify({ token: passkeyResponse.data.token }),
      })

      const validationData = await validationResponse.json()

      if (validationData.isValid) {
        onVerificationComplete(true, 'Verification successful! Transaction approved.')
      }
    }
  } catch (error) {
    // Handle error
  
  }
}

‍

Different adaptive MFA scenarios

Scenario 1: Anonymous IP, any amount ($100)

  1. User connects via VPN and enters transfer details
  2. Authsignal detects anonymous/VPN IP address
  3. IP is anonymous = True rule triggers
  4. User prompted for passkey verification
  5. After successful verification, transaction proceeds

Scenario 2: Trusted IP, high amount ($3,000)

  1. User enters large transfer from home IP
  2. Authsignal recognizes trusted IP but sees high amount
  3. transactionValue > 2000 rule triggers
  4. User prompted for passkey verification
  5. Transfer proceeds after verification

Scenario 3: Trusted IP, normal amount ($500)

  1. User enters regular transfer from home/office IP
  2. Authsignal recognizes trusted IP and sees normal amount
  3. No rules trigger
  4. Transfer proceeds immediately

Scenario 4: Tor network, any amount

  1. User connects through Tor browser
  2. Authsignal detects Tor exit node IP
  3. IP is anonymous = True rule triggers
  4. Verification required regardless of amount

‍

Extensions and customization

You can enhance adaptive MFA with additional risk signals:

Geographic risk: New countries or impossible travel detection

Network analysis: VPN detection and IP reputation scoring

Velocity checks: Rapid successive transactions from different devices

Business context: Different thresholds for different user types or account balances

Wrapping up

That's it! We've built a smart money transfer app with adaptive MFA that responds intelligently to risk. A $10,000 transfer from your home IP is fundamentally different from a $100 transfer from an anonymous VPN. Adaptive MFA recognizes these differences and responds appropriately.

Check out the Authsignal adaptive MFA docs to start implementing it in your app!

Question icon
Have a question?
Talk to an expert
NewsletterDemo PasskeysView docs
Passkeys
Multi-factor authentication
Adaptive MFA
Implementation
Risk based authentication

You might also like

The passkey UX patterns that drive adoption in 2026
Passkeys
Passkeys implementation

The passkey UX patterns that drive adoption in 2026

July 2, 2026
What is silent network authentication, and how does it work?
Silent Network Authentication
SNA

What is silent network authentication, and how does it work?

June 26, 2026
HIPAA MFA requirements and what to do before the final rule lands
Passkeys
Step up authentication
Adaptive MFA
SMS Alternative

HIPAA MFA requirements and what to do before the final rule lands

July 4, 2026

Secure your customers’ accounts today with Authsignal

Passkey demoCreate free account
Authsignal Purple Logo

Authsignal is a drop-in authentication and orchestration layer for consumer-facing businesses. Passkeys, adaptive MFA, and omnichannel verification on top of your existing identity stack. Deployed in weeks, not quarters.

AICPA SOCFido Certified
LinkedInTwitter
Platform
Drop-In Authentication
PasskeysBiometric authenticationWhatsApp OTPEmail OTPApp push authenticationPalm biometricsSMS OTPEmail OTPMagic LinksAuthenticator apps (TOTP)
View all auth methods
KEY FEATURES
No-code rules engineUser observabilityRisk-based authenticationSession managementDigital credentials APIPre-built UI
All authentication methods
Pricing
Customers
Solutions
USE CASE
Account takeovers (ATO)
Go passwordless
Call center
SMS cost optimization
Existing apps
Palm biometric payments
View all use cases
industry
Financial services
Healthcare
Marketplace
View all use cases
ROLE
Engineering
ProductCybersecurityDocs
Compare
Twilio Verify vs AuthsignalAuth0 vs AuthsignalAWS Cognito vs Authsignal + AWS Cognito
Resources
LEARN
BlogGuidesRegulatoryTemplatesDocs
COMPANY
About usWhy AuthsignalPartnersCareersSecurityContact
Integrations
Amazon Cognito
Azure AD B2C
Duende IdentityServer
Keycloak
Auth0
NextAuth.js
Custom identity provider
All integrations
United States
+1 214 974-4877
Ireland
+353 12 676529
Australia
+61 387 715 810
New Zealand
+64 275 491 983
© 2026 Authsignal - All Rights Reserved
Terms of servicePrivacy policySecuritySystem statusCookies