> ## Documentation Index
> Fetch the complete documentation index at: https://docs.authsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Implementing MFA

> Learn how to implement MFA and step-up authentication across your application using Authsignal actions.

Actions are the foundation for implementing multi-factor authentication (MFA) and step-up authentication in your application. By tracking specific user activities as actions, you can apply contextual security policies that challenge users when needed.

## MFA on login

The most common MFA scenario is requiring additional authentication after a user's primary credentials (username and password) have been validated.

Here's how the flow works with Authsignal:

```mermaid theme={null}
sequenceDiagram
    participant F as Your frontend
    participant B as Your backend
    participant A as Authsignal
    Note left of F: 1st authentication step in your app<br />(e.g. username + password)
    F->>B: Primary user credentials
    Note over B: Validate credentials
    B->>A: Track action
    A->>B: Pre-built UI URL
    B->>F: Pre-built UI URL
    Note left of F: 2nd authentication step via Authsignal<br />(e.g. Passkey, TOTP, or SMS OTP)
    F->>B: Check result
    B->>A: Validate challenge
    A->>B: Challenge result
    Note over B: Create login session
```

### Implementation

1. **Track the login action** after validating primary credentials:

<CodeGroup>
  ```ts Node.js theme={null}
  const request = {
    userId: "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
    action: "signIn",
    attributes: {
      redirectUrl: "https://yourapp.com/callback",
    },
  };

  const response = await authsignal.track(request);

  const url = response.url;
  ```

  ```csharp C# theme={null}
  var request = new TrackRequest(
      UserId: user.Id,
      Action: "signIn",
      Attributes: new TrackAttributes(
          RedirectUrl: "https://yourapp.com/callback"
      )
  );

  var response = await authsignal.Track(request);

  var url = response.Url;
  ```

  ```java Java theme={null}
  TrackRequest request = new TrackRequest();
  request.userId = "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833";
  request.action = "signIn";
  request.attributes = new TrackAttributes();
  request.attributes.redirectUrl = "https://yourapp.com/callback";

  TrackResponse response = authsignal.track(request).get();

  String url = response.url;
  ```

  ```ruby Ruby theme={null}
  response = Authsignal.track({
    user_id: "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
    action: "signIn",
    attributes: {
      redirect_url: "https://yourapp.com/callback",
    }
  })

  url = response[:url]
  ```

  ```python Python theme={null}
  response = authsignal.track(
      user_id="dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
      action="signIn",
      attributes={
          "redirectUrl": "https://yourapp.com/callback"
      }
  )

  url = response["url"]
  ```

  ```php PHP theme={null}
  $response = Authsignal::track([
      'userId' => "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
      'action' => "signIn",
      'attributes' => [
          'redirectUrl' => "https://yourapp.com/callback"
      ]
  ]);

  $url = $response["url"]
  ```

  ```go Go theme={null}
  response, err := client.Track(
      TrackRequest{
          UserId: "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
          Action: "signIn",
          Attributes: &TrackAttributes{
              RedirectUrl: "https://yourapp.com/callback",
          },
      },
  )

  url := response.Url
  ```
</CodeGroup>

2. **Handle the response** based on the action state:
   * If `CHALLENGE_REQUIRED`: Redirect user to the authentication flow
   * If `ALLOW`: Proceed with login
   * If `BLOCK`: Deny access
   * If `REVIEW`: Review the challenge

3. **Follow the standard integration steps** covered in [actions getting started](/actions-rules/actions/getting-started#2-challenging-the-user) to launch the challenge URL and validate the result.

## Step-up authentication

Step-up authentication challenges users when they perform sensitive operations, even if they're already logged in. This is ideal for high-risk actions like financial transactions, account settings changes, or data exports.

```mermaid theme={null}
sequenceDiagram
    participant F as Your frontend
    participant B as Your backend
    participant A as Authsignal
    Note left of F: User initiates a sensitive action<br />(e.g. payment, settings change)
    F->>B: User action input (e.g. amount)
    B->>A: Track action
    A->>B: Pre-built UI URL
    B->>F: Pre-built UI URL
    Note left of F: User completes challenge<br />via Authsignal pre-built UI
    F->>B: Check result
    B->>A: Validate challenge
    A->>B: Challenge result
    Note over B: Proceed with action<br />(e.g. process payment)
```

### Common step-up scenarios

* **Financial transactions**: Challenge for payments above a certain threshold
* **Account changes**: Require authentication for email/password changes
* **Administrative actions**: Challenge admin users for sensitive operations
* **Data access**: Authenticate before accessing sensitive information

## Combining with rules for adaptive MFA

While actions define *what* to protect, rules define *when* to challenge users. You can create adaptive MFA flows by combining actions with rules:

* Challenge only on new devices
* Require stronger authentication for high-risk IP addresses
* Skip MFA for trusted locations
* Apply different requirements based on user risk scores

Learn more about implementing adaptive MFA with [rules](/actions-rules/rules/adaptive-mfa).
