> ## Documentation Index
> Fetch the complete documentation index at: https://auth0-actions-triggers-prototype.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Learn about how Highly Regulated Identity enables transactional authorization with the Authorization Code Flow.

# Transactional Authorization with Authorization Code Flow

Highly Regulated Identity enables Transactional Authorization with the [Authorization Code Flow](/docs/get-started/authentication-and-authorization-flow/authorization-code-flow) by applying step-up <Tooltip tip="Multi-factor authentication (MFA): User authentication process that uses a factor in addition to username and password such as a code via SMS." cta="View Glossary" href="/docs/glossary?term=multi-factor+authentication">multi-factor authentication</Tooltip> (MFA) to authorize a transaction. Step-up MFA challenges the user with a second authentication factor to explicitly authorize the transaction details of a one-time operation, which is useful in use cases that require financial-grade security:

* Securing sensitive operations executed from your own services, such as approving bank transfers, access to operations history, and changes in access credentials.
* Securing sensitive operations requested from third-party services, such as approving digital payments and allowing one-time access for account verification.

This article walks you through the end-to-end journey of approving a bank transfer. The same transactional <Tooltip tip="Authorization Flow: Authorization grant (or workflow) specified in the OAuth 2.0 framework." cta="View Glossary" href="/docs/glossary?term=authorization+flow">authorization flow</Tooltip> can be applied to other use cases.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  You must configure transactional authorization for each API. Once activated, it applies to the scopes and `authorization_details.types` for that API.
</Callout>

## Prerequisites

<Warning>
  Do not pass fine-grained transaction authorization data or other sensitive or regulated data outside of `authorization_details`.
</Warning>

Before getting started, follow the instructions in [Configure Rich Authorization Requests](/docs/get-started/apis/configure-rich-authorization-requests) to register the `authorization_details.types` for your API or <Tooltip tip="Resource Server: Server hosting protected resources. Resource servers accept and respond to protected resource requests." cta="View Glossary" href="/docs/glossary?term=resource+server">resource server</Tooltip>.

## End-to-end flow

The following diagram shows the end-to-end flow for Transactional Authorization with Contextual SCA. There are four main phases:

1. Securely redirect the user to Auth0 with the transaction details. In this step, avoid revealing sensitive information on the front channel (e.g. the browser).
2. Apply dynamic policy after the user authenticates. Using [Actions](/docs/customize/actions), you can dynamically decide on the next steps based on the transaction details and other information you may get from sources such as external APIs. To learn more, read [Apply dynamic policy](#apply-dynamic-policy).
3. Challenge the user with a second authentication factor and show transaction details for the user to explicitly approve. This step depends on the authentication factor you chose to apply using Actions.
4. Get the access token and proceed with the sensitive operation. Your API validates the approved transaction details associated with the access token.

<Frame>
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/auth0-actions-triggers-prototype/docs/images/cdy7uua7fh8z/6VYcY5YJRT9Ngaomj5f9yi/ea5f0caa41a7db330a1c1d980ce7116c/Transactional_Authorization__1_.png" alt="" />
</Frame>

We will go through each phase in detail in the following sections.

### Communicate transaction details and redirect to Auth0

The user first accesses your web application after authenticating with Auth0. Following our example use case, the user then requests a money transfer to one of their contacts.

To meet financial-grade security standards, Highly Regulated Identity uses Pushed Authorization Requests (PAR) to hide transaction details from the browser. Instead of sending query parameters through the browser to the `/authorize` endpoint, PAR directly sends parameters from your backend to a special `/par` endpoint using a POST request. To learn how to set it up, read [Configure Pushed Authorization Requests](/docs/get-started/applications/configure-par).

In the PAR request body, transaction details are sent as part of the `authorization_details` JSON object:

```json lines theme={null}
"authorization_details": [
 {
   "type": "money_transfer",
   "instructedAmount": {
     "amount": 150,
     "currency": "USD"
   },
   "sourceAccount": "xxxxxxxxxxx1234",
   "destinationAccount": "xxxxxxxxxxx9876",
   "beneficiary": "Hanna Herwitz",
   "subject": "A Lannister Always Pays His Debts"
 }
]
```

Use Actions to inspect the `authorization_details` to determine which authentication factors to use based on the transaction. To learn more about `authorization_details` and how to use it along PAR, read [Authorization Code Flow with Rich Authorization Requests](/docs/get-started/authentication-and-authorization-flow/authorization-code-flow/authorization-code-flow-with-rar).

If you want to meet FAPI 1 Advanced Security compliance requirements, you must also use public key cryptography to authenticate the backend against the `/par` or the `/token` endpoint. This is more secure than sending a <Tooltip tip="Client Secret: Secret used by a client (application) to authenticate with the Authorization Server; it should be known to only the client and the Authorization Server and must be sufficiently random to not be guessable." cta="View Glossary" href="/docs/glossary?term=Client+Secret">Client Secret</Tooltip>. Auth0 offers the following public key cryptography authentication methods:

* [Private Key JWT](/docs/get-started/authentication-and-authorization-flow/authenticate-with-private-key-jwt)
* [mutual-TLS (mTLS) for OAuth](/docs/get-started/authentication-and-authorization-flow/authenticate-with-mtls)

After receiving a successful response to your PAR request, redirect the user to your Auth0 tenant’s `/authorize` endpoint. Add the `request_uri` parameter received in the PAR response and the `client_id` as the only query parameters, thus effectively hiding any sensitive information from the browser.

### Apply dynamic policy

When the user logs in without using <Tooltip tip="Single Sign-On (SSO): Service that, after a user logs into one applicaton, automatically logs that user in to other applications." cta="View Glossary" href="/docs/glossary?term=SSO">SSO</Tooltip> and the browser hits your Auth0 tenant’s `/authorize` endpoint, Auth0 will attempt to authenticate the user. In our example of approving a bank transfer, Auth0 has already authenticated the user to access your web application. However, when a third party redirects the user, such as for a digital payment, Auth0 presents a login screen to the user. To learn more about the authentication flow, read the [Authenticate](/docs/authenticate) documentation.

Once Auth0 has successfully authenticated the user, Auth0 triggers post-login [Actions](/docs/customize/actions), which expose transaction details about the user, app, authentication factor(s) used, and more in the [post-login event object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object). Within the post-login event object, the `event.transaction.requested_authorization_details` property contains details about the authorization request that were received in the previous step.

Use the [post-login event object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object) to decide how you want to proceed with the transaction. For example, you can send transaction details to an external risk engine, and after evaluating the risk level, determine whether to request step-up authentication using sms, as illustrated in the following code sample.

```js lines expandable theme={null}
exports.onExecutePostLogin = async (event, api) => {
  if (event.transaction?.requested_authorization_details.some(e => e.type === 'money_transfer')) {
      const axios = require('axios');

      //details to contact risk evaluation engine
      const risk_url = 'https://risk.example.org/score';
      const risk_options = {
        headers: {
          'Content-Type': 'application/json'
        }
      };

      const tx_data = {
        email: event.user.email,
        authorization_details: event.transaction?.requested_authorization_details
      };

      //send operation details to risk evaluation engine
      var risk = await axios.post(risk_url, tx_data, risk_options);

      //if it is a risky operation use push to authorize
      if (risk.data.score >= 2) {
        api.authentication.challengeWith({ type: 'push-notification', options: {otpFallback: false}});

      }
    }
};
```

### Challenge the user to get transaction details approval

You can customize what authentication factor to use depending on factors enrolled by the user, factors already satisfied by the session, and/or your own preferences. You can also provide alternatives for the user to choose from. To learn more, read [Customize MFA Selection in New Universal Login](/docs/secure/multi-factor-authentication/customize-mfa/customize-mfa-selection-universal-login).

Additionally, for SMS, email, and WebAuthn, you can customize the consent screen that Auth0 presents to the user with the information you want to show from authorization\_details and other transaction details. To learn more, read [Configure Rich Authorization Requests](/docs/get-started/apis/configure-rich-authorization-requests). For push notifications, this does not apply as the mobile application is the one showing the transaction details to the end user.

The following sections explain the different authentication factors that you can configure for transactional authorization.

#### Push notifications

Send a push notification to a user’s enrolled mobile device while Auth0 prompts the user with the Multi-Factor Authentication (MFA) waiting screen on the consumption device (e.g. the laptop where the transaction originated).

<Frame>
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/auth0-actions-triggers-prototype/docs/images/cdy7uua7fh8z/4mEJTT4VsAAAb6I0HhJI6r/851fe5ff489bfc9e5aaa2c52b4644f2c/Mobile_Push_-_English.png" alt="" />
</Frame>

For push notifications, the mobile application is responsible for showing the transaction details to the user for explicit approval. When triggering a push notification, you can forbid the option to fallback by manually entering an OTP by adding the option `otpFallback: false`.

To display the `authorization_details` to the user, the mobile application must retrieve them from the `txlnkid` parameter. The [Auth0 Guardian SDK](/docs/secure/multi-factor-authentication/auth0-guardian) passes the `txlnkid` parameter from the tenant to the mobile application via a push notification.

After the mobile application receives the push notification via the Guardian SDK, it can fetch the consent details, which includes the `authorization_details`, from the Auth0 Consent API:

<Tabs>
  <Tab title="iOS">
    ```swift lines theme={null}
    let device: AuthenticationDevice = // the object you obtained when enrolling
    if let consentId = notification.transactionLinkingId {
        Guardian
            .consent(forDomain: {yourTenantDomain}, device: device)
            .fetch(consentId: consentId, notificationToken: notification.transactionToken)
            .start{result in
                switch result {
                case .success(let payload):
                    let authorizationDetails = payload.requestedDetails.authorizationDetails
                case .failure(let cause):
                    // something went wrong
            }
        }
    }
    ```
  </Tab>

  <Tab title="Android">
    ```kotlin lines theme={null}
    if (notification.getTransctionLinkingId() != null) {
        guardian
          .fetchConsent(notification, enrollment)
          .start(new Callback<Enrollment> {
            @Override
            void onSuccess(RichConsent consentDetails) {
              List<Map<String, Object>> authorizationDetails = consentDetails
                    .getRequestedDetails()
                    .getAuthorizationDetails();
            }

            @Override
            void onFailure(Throwable exception) {
              if (exception instanceof GuardianException) {
                GuardianException guardianException = (GuardianException) exception;
                if (guardianException.isResourceNotFound()) {
                  // there is no consent associated with the transaction
                }
              }
              // something went wrong
            }
          });
    }
    ```
  </Tab>
</Tabs>

From the post-login Action, you can call `api.multifactor.enable()` before `api.authentication.challengeWith()` to remove the option to remember this device and force the user to validate the push challenge for all transactions. To learn more, read [Action Triggers: post-login - API object](/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object).

Once the user approves or declines the operation, the mobile application can allow or reject the MFA challenge. The transaction progresses to the **Complete the operation** phase.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  To verify the identity of the user opening the push notification, you can add biometric authentication to the mobile application. To learn more, read [Configure WebAuthn with Device Biometrics for MFA](/docs/secure/multi-factor-authentication/fido-authentication-with-webauthn/configure-webauthn-device-biometrics-for-mfa).
</Callout>

#### SMS, Email, or WebAuthn

You can also set up phone, email, or WebAuthn as authentication factors to challenge the user. For these authentication factors, Auth0 prompts the user with the corresponding MFA waiting screen. After the user validates the challenge on the MFA waiting screen, Auth0 shows the transaction details to the user for explicit approval. Remember you have to [Configure Rich Authorization Requests](/docs/get-started/apis/configure-rich-authorization-requests) for the approval step to work properly.

For the phone authentication factor, Auth0 sends a verification code to the user through SMS or voice. The following screenshot shows the MFA waiting screen after Auth0 sent the code through SMS:

<Frame>
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/auth0-actions-triggers-prototype/docs/images/cdy7uua7fh8z/kYn2A0p2jTY5CUn1FsjVf/b926a1689ee9722e6b902e433a77223b/Phone_Challenge_-_English.png" alt="" />
</Frame>

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  From Actions, you can call `api.multifactor.enable('any', { allowRememberBrowser: false })` before `api.authentication.challengeWith` to remove the option to remember this device and force the user to validate the push challenge for all transactions.
</Callout>

The user then receives the SMS with the verification code.

After the user inputs the verification code in the MFA waiting screen, Auth0 prompts the user with the transaction details on a consent screen. Once the user approves or declines the transaction details, the transaction progresses to the [Complete the operation](#complete-the-operation) phase.

Email and WebAuthn use the same transactional approval flow and similar MFA waiting and explicit approval screens.

<Warning>
  Under PSD2, [email is not a valid authentication factor](https://www.eba.europa.eu/sites/default/documents/files/documents/10180/2622242/4bf4e536-69a5-44a5-a685-de42e292ef78/EBA%20Opinion%20on%20SCA%20elements%20under%20PSD2%20.pdf) for Strong Customer Authentication. We recommend you use another authentication factor to challenge users to meet PSD2 compliance.
</Warning>

#### No Challenge

If you don’t challenge the user with a second authentication factor, Auth0 prompts the user with the consent screen to get explicit approval for the transaction details.

### Complete the operation

To complete the operation, Auth0 follows the standard [Authorization Code Flow](/docs/get-started/authentication-and-authorization-flow/authorization-code-flow). If the transaction is approved, the user browser is redirected to your application with an authorization code, which is then exchanged for an <Tooltip tip="Access Token: Authorization credential, in the form of an opaque string or JWT, used to access an API." cta="View Glossary" href="/docs/glossary?term=access+token">access token</Tooltip> encrypted using [JSON Web Encryption](/docs/secure/tokens/access-tokens/json-web-encryption). The access token contains the `authorization_details` that you originally passed. The following code sample shows the contents of a decrypted access token:

```json lines theme={null}
{
 "iss": "https://my_tenant.auth0.com/",
 "sub": "auth0|me",
 "aud": "https://myapi.zewobnak.com",
 "iat": 1683661385,
 "exp": 1683747785,
 "azp": "my_client",
 "transaction_linking_id": "ce4842e8-2894-418a-b1f9-39a330cd4911",
 "authorization_details": [
   {
     "type": "money_transfer",
     "instructedAmount": {
       "amount": 150,
       "currency": "USD"
     },
     "sourceAccount": "xxxxxxxxxxx1234",
     "destinationAccount": "xxxxxxxxxxx9876",
     "beneficiary": "Hanna Herwitz",
     "subject": "A Lannister Always Pays His Debts",
   }
 ]
}
```

Pass the access token to the API that facilitates the money transfer. The API then checks the access token’s `authorization_details` to verify the transaction details, such as the amount, sender, destination, and more. Once verified, the money transfer successfully executes, and you should see the approval screen.

If the transaction is rejected at any step, the user browser displays an `access_denied` error code.
