---
name: azion-install-the-leakstream-integration
description: >-
  Install Axur Leakstream from Azion Marketplace and run it on a firewall to flag login requests that use leaked credentials.
---

# Install the Leakstream integration

You install the Axur Leakstream integration from Azion Marketplace and run it on a [Firewall](/en/documentation/platform/firewall/), from Azion Console. Leakstream monitors the internet for leaked credentials, and checks whether a username and password combination was exposed in a known data breach. Use it to protect your e-commerce from checker attacks and your users' credentials. The function extracts the username and password from the body of a login request, queries the Axur Leakstream API, and adds custom headers to the request. A second function reads those headers and blocks the request, redirects the user, or starts a secondary verification flow.

Six objects have to exist before a request is checked: the installed function, a firewall carrying the **Functions** module, a Leakstream function instance, a response function instance, two Rules Engine rules with the **Run Function** behavior, and a workload deployment bound to the firewall. Each section below creates them.

---

## Prerequisites

- An Azion account. To sign in, refer to [How to access Azion Console](/en/documentation/guides/platform/account-and-billing/how-to-access-azion-console/).
- An application served by a [workload](/en/documentation/platform/workloads/), whose deployment you bind to the firewall in the last section.
- An [Axur account](https://www.axur.com/en-us/) with a Leakstream plan that matches the size of your customer base.
- An Axur **API Token**, which you get after Axur enables your account.
- The [Azion CLI](/en/documentation/devtools/cli/) installed and authorized, for the last section.
- Turning on a product or a module can generate usage costs. For more information, refer to [Pricing](/en/documentation/fundamentals/pricing/).

---

## Install the integration

The function is installed once per account. To install it:

1. **Open Marketplace**

   Access [Azion Console](https://console.azion.com/) > **Marketplace**.

2. **Find the integration**

   Enter `Leakstream` in the **Search on Marketplace** field, then select the integration's card. Browsing the cards and the categories reaches the same page.

3. **Select Install**

The card shows `Successfully installed!` and `Latest version installed!`, and the function appears in the **Function** list of the **Create Instance** drawer.

---

## Create the firewall

The firewall is where the functions are instanced and where the rules that run them live. To create one:

1. **Open the Firewalls page**

   Access [Azion Console](https://console.azion.com/) > **Firewalls**, then create a firewall.

2. **Name the firewall**

   In the **General** section, enter a **Name**. For example: `leakstream-firewall`.

3. **Turn on the Functions module**

   In the **Modules** section, turn on the **Functions** switch.

4. **Save the firewall**

The firewall shows a **Functions Instances** tab while the **Functions** module stays on. To use an existing firewall instead, turn on its **Functions** module and save it. For every setting on this form, refer to [Set a firewall's main settings](/en/documentation/guides/application-security/firewall-and-waf/firewall-configure-main-settings/).

---

## Create the function instance

The instance holds your Axur API Token and the names of the login fields. To create it:

1. **Open the Functions Instances tab**

   In **Firewalls**, select your firewall, then select the **Functions Instances** tab.

2. **Select + Function**

   A firewall that has no instance shows the same action as **Function Instance**. The **Create Instance** drawer opens.

3. **Name the instance**

   In **Name**, enter a name. For example: `leakstream`.

4. **Select the installed function**

   In **Function**, select the Axur Leakstream function. The list holds only the functions that run on a firewall.

5. **Enter the arguments**

   In **Arguments**, the editor is prefilled with the integration's default arguments in JSON. Enter your values, as the next section describes.

6. **Select Save**

The instance is listed in the **Functions Instances** tab.

### Arguments

The instance takes your API Token and the fields to read:

```json
{
  "api_key": "YourAxurAPIKey",
  "username_field": "user",
  "password_field": "password",
  "password_hash_type": "sha256",
  "execute_hashing": false,
  "leakstream_timeout": 60000
}
```

| Variable             | Required | Description                                                                                                                                                  |
| -------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `api_key`            | Yes      | The API Token from your Axur account. Required unless the `AXUR_API_V1_LEAKSTREAM_API_KEY` environment variable is set                                       |
| `username_field`     | Yes      | The name of the request body field that holds the username. Required unless the `AXUR_API_V1_LEAKSTREAM_USERNAME_FIELD` environment variable is set          |
| `password_field`     | No       | The name of the request body field that holds the password                                                                                                   |
| `password_hash_type` | No       | The hashing algorithm of the password. Accepted values: `md5`, `sha1`, `sha224`, `sha256`, `sha384`, `sha512`                                                |
| `execute_hashing`    | No       | When `true`, the function hashes the password with SHA-256 before it sends the password to the Axur API. Use it when the frontend does not hash the password |
| `leakstream_timeout` | No       | The connection timeout, in milliseconds, for requests to the Axur API. The default is `60000` (60 seconds)                                                   |

> **Note**
>
> The function supports three request content types: `application/json`, `application/x-www-form-urlencoded`, and `multipart/form-data`. A request with another content type passes through without a call to the Axur API.

### Headers the function adds

The Leakstream function adds these headers to the request object:

| Header                             | Value                                                     | Description                                                      |
| ---------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------------- |
| `axur-leakstream-leaked`           | `true`                                                    | The username and password combination was found in a data breach |
| `axur-leakstream-username-leaked`  | `true`                                                    | The username alone was found in a data breach                    |
| `axur-leakstream-missing-username` | `true`                                                    | The username field was not found in the request body             |
| `axur-leakstream-error`            | `timeout`, `invalid-content-type`, or an HTTP status code | An error occurred during the call to the Axur API                |

---

## Create the response function instance

The Firewall Rules Engine criteria cannot match custom request headers. For this reason, the blocking logic lives in a second function, which reads the `axur-leakstream-leaked` header from the request object and returns a response.

The function below returns an HTML warning page when the header is `true`:

```javascript
async function handleRequest(request) {
  const leaked = request.headers.get('axur-leakstream-leaked');

  if (leaked === 'true') {
    const html = `<!DOCTYPE html>
<html lang="en">
<head>
  <title>Warning!</title>
</head>
<body>
  <h1>Warning!</h1>
  <p>The combination of username and password provided was found in a data breach. You cannot use it.</p>
</body>
</html>`;
    return new Response(html, {
      status: 403,
      headers: { 'content-type': 'text/html;charset=UTF-8' },
    });
  }

  return fetch(request);
}

addEventListener('fetch', event => {
  return event.respondWith(handleRequest(event.request));
});
```

Create a firewall function with this code, then instance it on the same firewall, with the steps of the previous section. For how to create a function that runs on a firewall, refer to [Run a function on a firewall](/en/documentation/guides/application-development/functions-and-runtime/firewall/).

> **Tip**
>
> Your response function can also read the `axur-leakstream-username-leaked` header, and ask users to change their password when the username alone was found in a data breach.

---

## Create the rules

The integration uses two rules on the same endpoint. The first rule runs the Leakstream function, and the second rule runs the response function that acts on the headers. A [Rules Engine for Firewall](/en/documentation/platform/firewall/rules-engine/) rule selects the requests that reach an instance, through a **Run Function** behavior.

To create the rule that runs the Leakstream function:

1. **Open the Rules Engine tab**

   In **Firewalls**, select your firewall, then select the **Rules Engine** tab.

2. **Select + Rule**

3. **Name the rule**

   In **Name**, enter a name. For example: `Run Leakstream`.

4. **Set the criteria**

   In the **Criteria** section, limit the check to your login or account-creation endpoint, not every request. For example: if `Request Method` *is equal to* `POST` **and** `Request URI` *matches* `/login`.

5. **Add the Run Function behavior**

   In the **Behaviors** section, select **Run Function**, then select the Leakstream instance.

6. **Select Save**

To create the rule that acts on the result:

1. **Select + Rule**

2. **Name the rule**

   In **Name**, enter a name. For example: `Block leaked credentials`.

3. **Set the criteria**

   In the **Criteria** section, match the same endpoint as the first rule. For example: if `Request Method` *is equal to* `POST` **and** `Request URI` *matches* `/login`.

4. **Add the Run Function behavior**

   In the **Behaviors** section, select **Run Function**, then select the response function instance.

5. **Select Save**

> **Note**
>
> The Firewall Rules Engine processes rules in order. The Leakstream rule must have a **lower order number** than the response function rule, so the headers exist before the second function reads them.

---

## Bind the firewall to the workload

The binding is on the workload's deployment, so create a deployment that names both the application and the firewall:

```bash
azion create workload-deployment --workload-id <workload-id> --name <deployment-name> \
  --application-id <application-id> --firewall-id <firewall-id> --strategy-type default \
  --active true --current true
```

The command prints the id of the new deployment:

```text
Created Workload Deployment with ID 123456
```

Requests to the workload's domain reach the firewall, and the rules run the Leakstream instance and the response function instance on the login endpoint.

---

## Next steps

- [Marketplace integrations](/en/documentation/platform/marketplace/integrations.md): Every integration Azion Marketplace offers, and where each one runs.
- [Rules Engine for Firewall](/en/documentation/platform/firewall/rules-engine.md): Every criterion and behavior a firewall rule accepts.
- [Run a function on a firewall](/en/documentation/guides/application-development/functions-and-runtime/firewall.md): Create and instance your own function on a firewall.
- [Update an integration](/en/documentation/guides/application-development/integrations/update-an-integration.md): Move an installed integration to its latest version.
