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

# Triggering Custom Authentication

> Require specific authentication methods before performing a custom action

Use a custom authentication flow when an action in your application requires fresh proof of a user's identity. For example, you might require authentication before changing account details, viewing sensitive information, or completing a high-risk transaction.

The OwnID Web SDK can require one or more authentication or verification methods and, after the user completes the flow, return an OwnID access-token (JWT) in the `accessToken` field. Send the OwnID access-token to your server with the custom-action request. Your server must [verify and validate the OwnID access-token](/building-blocks/advanced-use-cases/custom-actions-authentication) before it performs the action.

<Warning>
  Receiving an OwnID access-token (JWT) in the browser does not authorize the action by itself. Always verify the OwnID access-token and enforce the required authentication methods on your server.
</Warning>

## Trigger the flow

The following example starts a flow when the user selects a custom-action button. It allows the user to complete any one of passkey authentication, phone number verification, or identity document verification.

```typescript theme={null}
document.querySelector<HTMLButtonElement>('#customAction.btn')!.onclick = async () => {
  const controller = await ownid
    .withContext({ loginId: 'user@example.com' })
    .buildFlow({ name: 'Custom-Action' })
    .requireAuth({
      oneOf: [
        'PasskeyAuth',
        'PhoneNumberVerification',
        'IdDocVerification',
      ],
    })
    .start();

  if ('error' in controller) {
    console.error('Error starting authentication:', controller.error);
    return;
  }

  const result = await controller.whenSettled;
  if ('error' in result) {
    console.error('Authentication did not complete:', result.error);
    return;
  }

  const response = await fetch('/customAction', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ accessToken: result.accessToken }),
  });

  if (!response.ok) {
    console.error('The custom action was not authorized');
    return;
  }

  alert('Action complete!');
};
```

The example performs these steps:

1. `withContext()` identifies the account for which authentication is required.
2. `buildFlow()` creates a custom flow. The flow name is included in metrics, so use a stable, descriptive name for each action.
3. `requireAuth()` defines the acceptable authentication evidence.
4. `start()` presents an available method to the user and begins the flow.
5. `whenSettled` resolves after the flow succeeds or fails. A successful result contains the OwnID access-token in `accessToken`.
6. The browser sends the OwnID access-token to the endpoint responsible for the custom action.

## Choose authentication requirements

Pass a policy to `requireAuth()` that reflects the sensitivity of the action:

* Use a method name to require that specific method.
* Use `oneOf` to accept at least one method from a list.
* Use `allOf` to require every method in a list.

```typescript theme={null}
// Require a passkey.
.requireAuth('PasskeyAuth')

// Accept either a passkey or phone verification.
.requireAuth({
  oneOf: ['PasskeyAuth', 'PhoneNumberVerification'],
})

// Require both phone and identity document verification.
.requireAuth({
  allOf: ['PhoneNumberVerification', 'IdDocVerification'],
})
```

Supported methods include:

| Method                    | Evidence required                        |
| ------------------------- | ---------------------------------------- |
| `PasskeyAuth`             | Authentication with a registered passkey |
| `EmailVerification`       | Verification of an email address         |
| `PhoneNumberVerification` | Verification of a phone number           |
| `IdDocVerification`       | Identity document verification           |

Only methods available for the account and configured for your OwnID application can be completed. For example, phone verification requires an [SMS provider](/explore/customize-sms/introduction), and email verification requires an [email provider](/explore/customize-emails/introduction).

## Authorize the action on your server

Treat the OwnID access-token (JWT) as a short-lived credential for the requested action. Send it over HTTPS in the request body or an authorization header, and do not store it in browser persistence or log it.

On your server, verify the JWT signature and standard claims on the OwnID access-token, prevent replay, confirm the expected authentication evidence in `authorization_details`, and identify the account from the subject claim. See [Custom Actions Authentication](/building-blocks/advanced-use-cases/custom-actions-authentication) for a complete server-side implementation.
