Skip to main content

Getting started and concepts

MFA (Multi-Factor Authentication):
  • Requires additional authentication after primary credentials (username/password)
  • Applied consistently to all users or specific groups
  • Example: Always require SMS OTP after password login
Adaptive MFA:
  • Uses rules to intelligently determine when to challenge users based on risk factors
  • Challenges users only when necessary (new device, suspicious location, etc.)
  • Balances security with user experience
Step-up Authentication:
  • Requires additional verification for sensitive operations, even if already logged in
  • Applied to specific high-risk actions (payments, account changes)
  • Example: Require passkey verification before processing a large transaction
Learn more about implementing MFA and adaptive MFA.
Actions represent security events in your application that may require additional verification:
  • Login attempts, payments, account changes, data access
  • Each action returns one of four outcomes: ALLOW, CHALLENGE, REVIEW, or BLOCK
  • Have configurable default outcomes
Rules are conditional logic that determine when and how to challenge users:
  • Evaluate risk factors like device characteristics, IP data, user behavior
  • Can override action default outcomes based on context
  • Enable adaptive authentication policies
Together, Actions define what to protect, while Rules define when to challenge users. See our guides for Actions and Rules.
When you track an action, Authsignal returns one of four possible states:
  • ALLOW - Action is permitted without additional authentication. Proceed with the user’s request.
  • CHALLENGE_REQUIRED - User must complete an authentication challenge before proceeding.
  • BLOCK - Action is blocked for security reasons. Deny the user’s request.
  • REVIEW - Action requires manual review before proceeding.
Your application logic should handle each outcome appropriately. Most commonly, you’ll redirect users to complete challenges when CHALLENGE_REQUIRED is returned.

Configuration and setup

Custom domains are a pre-requisite when using passkeys. Outside of this scenario, custom domains are optional but highly recommended as they help to create a more branded and trusted user experience.
As a standalone authentication method:
  • Users receive OTP codes directly via WhatsApp as their primary phone-based authentication
  • Configured independently in the Authenticators section
  • Follow our WhatsApp OTP guide for implementation
As a fallback for SMS OTP:
  • WhatsApp automatically delivers OTP codes when SMS delivery fails or is unavailable
  • Helps reduce messaging costs while maintaining reliable delivery
  • Configured within the SMS OTP settings as a backup channel
  • See the SMS OTP guide for setup instructions

Passkeys

The approach differs between web and mobile platforms:For web applications: Use the WebAuthn API’s conditional UI feature (passkey autofill) which only shows passkeys when they’re available on the device. This provides a seamless experience without requiring explicit detection.For mobile applications: Handle error codes when passkey authentication fails to provide graceful fallback experiences. Present a “Sign in” button that immediately displays the passkey prompt for the optimal experience when passkeys are available, then gracefully fall back to email authentication when they’re not.For detailed implementation guidance and code examples, see our web best practices and mobile best practices guides.
Unlike traditional methods where you type your username first, passkeys can show you available accounts automatically without any typing.Traditional sign-in (username-initiated):
  • You enter your username/email first
  • The site looks up your account
  • Then sends you a code or prompts for a password
Passkey sign-in (device-initiated):
  • Your device shows available passkeys automatically
  • You select which account to use
  • Authentication happens instantly with biometrics or device PIN
Passkey autofill showing available accounts
This shift from username-initiated to device-initiated authentication allows for more seamless flows, especially with passkey autofill that can populate sign-in forms automatically.
Passkey uplift is the process of prompting users to create a passkey after they’ve successfully signed in using a traditional method like email OTP or password. This helps transition users gradually from legacy authentication to passkeys.When to show passkey uplift:
  • After a user completes email/SMS OTP authentication
  • When a user signs in on a new device without a passkey
  • During onboarding flows for new users
  • After password-based sign-ins
Best practices for uplift:
  • Explain the benefits clearly (faster, more secure, no passwords to remember)
  • Make it optional, not mandatory
  • Use timed cooldowns to avoid being intrusive
  • Show the prompt at natural transition points in your app
Example passkey uplift prompt
This approach helps increase passkey adoption while maintaining a smooth user experience for those not ready to switch immediately.
Passkeys may not be available on a device for several reasons:
  • User created a passkey on one device but switched to a new device where it can’t be synced
  • User deleted the passkey from their password manager
  • Switching between iOS and Android devices (cross-platform sync limitations)
Always provide backup authentication options and avoid leading users into dead ends. Your UI should clearly present alternatives like email OTP or SMS when passkeys aren’t available.For detailed implementation guidance, see our web best practices and mobile best practices.
Both approaches have their benefits:Passkey Autofill (Recommended for Web)
  • Unobtrusive way to support passkeys while maintaining familiar UX
  • Only shows passkeys if already created and available on device
  • Users can manually enter username if no passkey is available
  • Particularly good option when you already have a username input on your existing username and password login page
Passkey autofill integration
Dedicated Sign-in Button
  • Clear alternative authentication option
  • Launches passkey prompt regardless of availability
  • May show QR code if no passkey available (can be confusing for some users)
Passkey sign-in button options
We recommend restricting QR code flows to explicit user interactions where they’ve chosen to use passkeys, as the QR code prompt can be jarring for unfamiliar users.
For MFA (Secondary Factor):
  • Use allowCredentials parameter to restrict passkeys to the specific user’s credentials
  • Only show passkeys for one account to avoid confusion on shared devices
  • Still provide backup options as the device may not have the user’s passkeys
For Primary Authentication:
  • Can show all available passkeys on device
  • Device-initiated flow allows users to select from available credentials
  • Focus on smooth fallback experience when no passkeys are present
Multiple passkeys available for different accounts
The Authsignal pre-built UI automatically handles MFA scenarios by restricting credentials and providing clear fallback options.
Gradual Introduction:
  • Prompt users to create passkeys after they sign in with existing methods
  • Provide clear explanations of passkey benefits (faster, more secure, no passwords)
  • Use gentle prompts rather than forcing immediate adoption
Prompt to add passkey to device
Improve Device Coverage:
  • Prompt users to create passkeys when they authenticate on new devices
  • Consider enrollment flows that create backup authentication methods first
  • Use timed cooldowns or behavior-based prompts to avoid being intrusive
Better Passkey Management:
  • Display passkeys using credential manager names (iCloud Keychain, Google Password Manager)
  • Show appropriate icons using webauthnCredential.aaguidMapping data
  • Help users understand which devices their passkeys are available on
Display list of user's passkeys with credential manager icons
See our complete guides for web and mobile implementation strategies.
Best practice: Create backup authentication first, then passkeys.Unlike web where users can easily switch between devices, mobile users often switch between iOS and Android where passkeys don’t sync. Always ensure users have a backup option:Recommended flow:
  1. User signs up and completes email OTP or SMS OTP enrollment
  2. After successful enrollment, prompt to create a passkey
  3. User now has both a backup method and a convenient passkey
This approach prevents users from getting locked out when switching between platforms or devices where their passkey isn’t available.
This parameter controls whether to show the passkey prompt when no credentials are available on the device.When set to true (recommended):
  • Only shows passkey prompt if credentials exist on the current device
  • Avoids confusing QR code prompts for users without passkeys
  • Enables smooth fallback to email/SMS authentication
When set to false:
  • Always shows passkey prompt, even with no local credentials
  • May display QR code for cross-device authentication
  • Can be confusing for users unfamiliar with passkey cross-device flows
Best practice: Keep this true for most mobile apps to ensure users aren’t presented with QR codes when they don’t have passkeys available locally.

Push notifications

It’s a common misconception that Push Authentication relies on push notifications (like FCM or APNs) to function. In fact, Authsignal’s Push Authentication is built to work even without them.Push authentication uses device credentials and public key cryptography - the push notification is only used to prompt users to open the app. If the notification doesn’t arrive, users can still open the app manually and complete authentication.
Yes, Authsignal allows you to plug in your own push infrastructure. Through our webhooks or SDKs, you can trigger push events via your existing provider while still using Authsignal, device enrollment, and risk-based logic.
Yes, you have full control over push notifications’ content, language, and appearance. Since Authsignal integrates with your existing push infrastructure via webhooks, you control all aspects of the notification including the message text, images, sounds, and branding.

Authenticators and user management

In order to deter and protect challenge flows from abuse and high volume attacks, Authsignal has built-in rate limits for different authenticator types.These limits are in place to deter and stop bad actors and typically will not be noticed by legitimate users on your platform.Rate limits for sendingThe following limits apply when sending emails or SMS to initiate a challenge.
Authenticator typeRate limit
Email magic link12 per 10 mins
Email OTP12 per 10 mins
SMS OTP6 per 10 mins
Rate limits for verificationThe following limits apply when submitting OTP codes to complete a challenge.
Authenticator typeRate limit
Email OTP10 per 5 mins
SMS OTP10 per 5 mins
Time-based OTP (TOTP)10 per 5 mins
Yes, you can remove authenticators for users in two ways:Through the Authsignal Portal:
  1. Navigate to the user details page
  2. Click the “Remove authenticators” button
  3. Select which authenticators you want to remove and submit
See our administrative removal guide for detailed steps.Programmatically using APIs: You can also remove authenticators programmatically using our APIs. See our programmatic authenticator management guide for implementation details.

API and integration

Please check your API secret key and API URL are correct. You can find the values for your tenant in the Authsignal Portal under Settings -> API keys. Ensure that the API URL corresponds to your tenant’s region.
This error is returned when no authenticators have been configured for your tenant.
If you’re using the Authsignal Web SDK, a cookie named __as_aid is set on the user’s browser.When tracking an action on your server, you can extract the deviceId from this cookie:
Server
const deviceId = req.cookies["__as_aid"]; // Or however you access cookies in your framework of choice

const { url } = await authsignal.track({
  action: "signIn",
  userId,
  attributes: {
    deviceId,
  },
});
If reading the request cookie is not an option, you can use retrieve the deviceId on the client via authsignal.anonymousId and pass it to your server in the request body:
Client
async function handleSignIn(username: string, password: string) {
  const deviceId = authsignal.anonymousId;

  const signInResponse = await fetch("/signIn", {
    method: "POST",
    body: JSON.stringify({
      deviceId,
      username,
      password,
    }),
  });
}

Webhooks

The most common cause is framework manipulation of the request body. The Authsignal SDK requires the raw body to verify signatures.Common issues:
  • Framework parsing JSON and converting back to string
  • Body compression/decompression
  • Character encoding changes
  • Middleware modifying the request
Solution: Ensure your webhook endpoint receives the raw, unmodified request body. Many frameworks provide ways to access the raw body before parsing.For implementation examples, see our Server SDK webhook documentation.
For IP whitelisting, Authsignal sends webhooks from these addresses:
RegionIP Addresses
US (Oregon)44.224.97.232
44.230.210.235
44.236.208.22
52.33.85.88
AU (Sydney)13.210.81.243
3.105.80.107
54.252.129.142
EU (Dublin)34.247.148.106
34.253.116.90
54.171.116.55
Make sure to whitelist the IP addresses for your tenant’s region.

Error handling and troubleshooting

There are currently only two scenarios where this can occur:
  1. In push notification auth when the user presses “Deny” instead of “Accept” in the in-app notification
  2. In SMS or email OTP auth when the number of code submission attempts exceeds rate limit thresholds
In other cases when an action is incomplete or abandoned it will remain in a CHALLENGE_FAILED state.
invalid_configuration: Your tenant configuration is invalid. Check that authenticators are properly configured in the Authsignal Portal.invalid_credential: The credential (e.g., passkey) is invalid for the user. This may happen if the credential was deleted or is being used on the wrong device.invalid_request: Request failed due to invalid parameters. Check your request payload and ensure all required fields are provided.too_many_requests: Rate limit exceeded. Implement back-off and retry logic.unauthorized: Invalid tenant credentials or wrong region. Verify your API secret key and API URL match your tenant’s region.See our error handling documentation for implementation examples.
You can find your region information in the Authsignal Portal under Settings -> API Keys. The API URL will indicate your region:
  • US (Oregon): https://api.authsignal.com/v1
  • AU (Sydney): https://au.api.authsignal.com/v1
  • EU (Dublin): https://eu.api.authsignal.com/v1
Make sure your Server SDK and API calls use the correct URL for your region to avoid unauthorized errors.
Authsignal APIs are designed to be called from your backend, not directly from frontend JavaScript in browsers.Correct flow:
  1. Frontend sends request to your backend
  2. Your backend calls Authsignal APIs
  3. Your backend returns response to frontend
For frontend authentication challenges:Direct browser calls to Authsignal APIs will fail due to CORS restrictions.
I