---
name: azion-run-bot-manager-on-every-request
description: >-
  Create the Rules Engine rule that hands every request a firewall receives to one Bot Manager instance, from Azion Console, the Azion CLI, or the API.
---

# Run Bot Manager on every request

You can run a Bot Manager instance on every request a firewall receives with one [Rules Engine for Firewall](/en/documentation/platform/firewall/rules-engine/) rule, from Azion Console, the Azion CLI, or the API. A function instance scores nothing until a rule hands it a request; for where the rule sits in the path a request travels, refer to [Bot scoring](/en/documentation/platform/firewall/bot-manager/bot-scoring/).

---

## Prerequisites

- A [firewall](/en/documentation/platform/firewall/) bound to the workload that serves your application. Refer to the [Bot Manager quickstart](/en/documentation/platform/firewall/bot-manager/quickstart/).
- A Bot Manager function instance on that firewall, and its id. To create one, refer to [Run Bot Manager in observation mode](/en/documentation/guides/application-security/bots-and-network/observation-mode/).
- The [Azion CLI](/en/documentation/devtools/cli/) installed and a configured personal token, for the CLI procedure.
- A personal token, for the API procedure. To create one, refer to [Personal Tokens](/en/documentation/fundamentals/personal-tokens/).

---

## Create the rule

The rule below matches every request its firewall receives and runs one instance on each of them. `value` holds the id of the **function instance** on this firewall, so replace `12347` with your own. It never holds the id of the installed function, which is the same for every instance of it in the account.

```json
{
  "name": "Run Bot Manager on every request",
  "active": true,
  "criteria": [
    [
      {
        "conditional": "if",
        "variable": "${request_uri}",
        "operator": "starts_with",
        "argument": "/"
      }
    ]
  ],
  "behaviors": [
    {
      "type": "run_function",
      "attributes": {
        "value": 12347
      }
    }
  ]
}
```

**Console**

To create the rule from Azion Console:

1. **Open the firewall that carries the instance**

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

2. **Select the Rules Engine tab**

3. **Select + Rule**

4. **Name the rule**

   Enter `Run Bot Manager on every request` as the name. The description is optional.

5. **Set the criterion**

   In the **Criteria** section, select `Request Uri` as the variable and *starts with* as the operator, then enter `/` as the argument.

6. **Add the Run Function behavior**

   In the **Behaviors** section, select **Run Function**. Doing so adds a second control, which carries no label and the placeholder `Select an function`. That control holds the function instances on this firewall; select the one to run.

7. **Select Save**

The firewall now holds the rule, and the instance scores every request the firewall receives. The behavior selector lists instances, not functions, and only the active ones. A rule carries at most one **Run Function** behavior, which Azion Console enforces by disabling the option once one is in the rule. The `Request Uri` variable needs nothing else turned on, while `Header User Agent` and `Request Args` are offered only while [WAF](/en/documentation/platform/firewall/#waf) is on for the firewall.

**CLI**

To create the rule with the Azion CLI, save the rule above as `rule.json`. `azion create firewall-rule` reads the whole rule from that file and carries no flag for a criterion or a behavior:

```bash
azion create firewall-rule --firewall-id <firewall-id> --file rule.json
```

```text
Created Firewall Rule with ID 123458
```

The Azion CLI confirms the rule with the id it received. Read the rule back and the platform has added one key it assigns itself, `"order": 0`, which is the position the rule holds among the rules of that firewall. `criteria` is a list of lists, and the behavior takes the key `type`. A file that writes `name` instead is refused with `Failed to decode the given 'json' file`, a message that names neither the field nor the reason: the file is valid JSON and the defect is the shape.

**API**

Send a `POST` request to the `request_rules` collection of the firewall that carries the instance, with `rule.json` as the body:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/firewalls/<firewall-id>/request_rules \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data @rule.json
```

The API answers `202` and returns the rule with one key it assigned: the `order` the rule holds among the rules of that firewall, `0` for the first one.

> **Note**
>
> Key the criterion on the request URI. The `${request_args}` variable with the `matches` operator and `.*` as the argument looks like a match on everything and is not: the variable is empty whenever a request carries no query string, and an empty variable matches nothing. A rule keyed that way passes silently over every `POST` whose payload sits in the body. Running a second instance on the same request takes a second rule, because a rule carries at most one `run_function` behavior.

---

## Next steps

- [Read the report log for one instance](/en/documentation/guides/application-security/bots-and-network/read-the-report-log.md): The scores the instance produces once the rule hands it every request.
- [Rules Engine for Firewall](/en/documentation/platform/firewall/rules-engine.md): The criteria and behaviors a firewall rule accepts, beyond the two this rule uses.
