Learn how Authsignal actions enable risk-based authentication and how to implement them in your app.
Authsignal actions are the building blocks that let you create contextual, risk-based authentication flows.
Actions represent specific user activities or events in your application that might require authentication. These can range from routine operations like sign-in to high-risk activities like withdrawing funds, changing account settings, or making large purchases.
Every action in Authsignal results in one of four possible outcomes that determine how to handle the user’s request:
ALLOW: Let the action proceed without additional authentication
CHALLENGE: Require the user to complete an authentication challenge
REVIEW: Place the action in a queue for manual review
BLOCK: Prevent the action from proceeding entirely
Each action has a configurable default outcome that determines what happens when no rules are triggered. However, when you create rules for an action, those rules can override the default outcome.
The conditional logic that determines which outcome to apply based on risk factors and context. Rules can override the action’s default outcome.
When you track an action, you provide the context needed for evaluation:
await authsignal.track({ userId: "0272c312-e181-4cad-a494-43647b503a0a", // Unique identifier for the user action: "withdraw-funds", // The action code (what the user is doing) attributes: { // Contextual information for rule evaluation deviceId: "device-abc", ipAddress: "203.0.113.1", userAgent: "Mozilla/5.0...", },});
In your frontend, call setToken with the client token obtained, then use the relevant SDK methods to progress the user through a challenge.
// Set the token from the track resultauthsignal.setToken(token);// Show the appropriate challenge based on the user's enrolled methodsconst result = await authsignal.passkey.signIn({ action: "withdraw-funds"});// Send the result token back to your server for validationif (result.token) { await validateChallenge(result.token);}
In your frontend, call setToken with the client token obtained, then use the relevant SDK methods to progress the user through a challenge.
// Set the token from the track resultauthsignal.setToken(token);// Show the appropriate challenge based on the user's enrolled methodsconst result = await authsignal.passkey.signIn({ action: "withdraw-funds"});// Send the result token back to your server for validationif (result.token) { await validateChallenge(result.token);}
In your frontend, pass the url from the track call to the Authsignal Web SDK to launch an enrollment or re-authentication flow.
// Launch the Pre-built UIauthsignal.launch({ url: challengeUrl, mode: "popup" // or "redirect"});
After the user completes the challenge, you’ll receive a token that you can validate on your backend to verify the authentication result.
For pre-built UI, this token is appended to your redirect URL as a query parameter, while for custom UI implementation, you’ll get the token directly from the challenge completion result.
Pass the token obtained from the challenge result to your backend and validate it server-side to complete authentication.
const request = { token: "eyJhbGciOiJ...", // Token from challenge completion};const response = await authsignal.validateChallenge(request);if (response.state === "CHALLENGE_SUCCEEDED") { // The user completed the challenge successfully // Proceed with authenticated action or create authenticated session return { success: true, userId: response.userId };} else { // The user did not complete the challenge successfully return { error: "Challenge validation failed" };}
Pass the token obtained from the challenge result to your backend and validate it server-side to complete authentication.
const request = { token: "eyJhbGciOiJ...", // Token from challenge completion};const response = await authsignal.validateChallenge(request);if (response.state === "CHALLENGE_SUCCEEDED") { // The user completed the challenge successfully // Proceed with authenticated action or create authenticated session return { success: true, userId: response.userId };} else { // The user did not complete the challenge successfully return { error: "Challenge validation failed" };}
const result = await authsignal.validateChallenge({ token: "eyJhbGciOiJ..." // Token from redirect URL query parameter});if (result.state === "CHALLENGE_SUCCEEDED") { // The user completed the challenge successfully // Proceed with the action return { success: true };}