---
name: azion-create-a-firewall-rule
description: >-
  Add a rule to the Rules Engine of a firewall from Azion Console, the Azion CLI, or the API, and confirm that it denies a request.
---

# Create a firewall rule

You can create a [firewall](/en/documentation/platform/firewall/) rule in [Rules Engine](/en/documentation/platform/firewall/rules-engine/) from Azion Console, the Azion CLI, or the API. The first rule on this page denies one test path, so a single request confirms that the firewall applies it. The second, created in Azion Console, refuses a client that presents no certificate.

An application carries a Rules Engine of its own. A rule that adds a request header for your origin belongs to [Rules Engine for Applications](/en/documentation/platform/applications/rules-engine/).

---

Select the interface you work in. The prerequisites and the steps that create the first rule switch with your selection.

## Prerequisites

- A firewall bound to your [workload](/en/documentation/platform/workloads/). To create one and bind it, refer to [Firewall quickstart](/en/documentation/platform/firewall/quickstart/).
- For the client-certificate rule, mutual TLS (mTLS) turned on for that workload. For more information, refer to [Support for mTLS for Secure](/en/documentation/platform/workloads/mtls/).

**Console**

- Access to Azion Console. To sign in, refer to [Access Azion Console](/en/documentation/guides/platform/account-and-billing/how-to-access-azion-console/).

**CLI**

- The Azion CLI, installed and authorized with your account. The commands on this page match Azion CLI 4.23.0.
- The ID of the firewall. Azion Console shows it in the address of the firewall's page, after `/firewalls/edit/`.

**API**

- A personal token, sent in the `Authorization` header as `Token [TOKEN VALUE]`. To create one, refer to [Manage a personal token](/en/documentation/guides/platform/account-and-billing/personal-tokens/).
- `curl`, or another HTTP client.
- The ID of the firewall. Azion Console shows it in the address of the firewall's page, after `/firewalls/edit/`.

---

## Deny requests to one path

The rule in this section matches requests whose path starts with `/deny-test` and refuses them with `403`. Requests to every other path still reach your application. The criterion also matches longer paths that begin with the same characters, such as `/deny-test-old`.

Neither the *Request Uri* criterion nor the *Deny (403 Forbidden)* behavior needs a Product on the firewall. Other criteria and behaviors need [Web Application Firewall (WAF)](/en/documentation/platform/firewall/how-it-works/#waf), [Network Shield](/en/documentation/platform/firewall/how-it-works/#network-shield), or Functions enabled on the firewall. For the full list, refer to [Rules Engine for Firewall](/en/documentation/platform/firewall/rules-engine/#criteria).

**Console**

To create the rule in Azion Console:

1. **Open the firewall bound to your workload**

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

2. **Select the Rules Engine tab**

3. **Start a new rule**

   Select **Rule**. The **Create Rule** drawer opens.

4. **Name the rule**

   In the **General** section, enter a **Name**, such as `deny-test-path`.

5. **(Optional) Describe the rule**

   In **Description**, enter a short note about what the rule does.

6. **Set the criterion**

   In the **Criteria** section, the first condition opens with the *Request Uri* variable and the *starts with* operator. Enter `/deny-test` as its argument.

7. **Add the behavior**

   In the **Behaviors** section, select *Deny (403 Forbidden)*.

8. **Save the rule**

   Select **Save**.

Azion Console shows `Rule successfully created`. The rule appears in the **Rules Engine** tab with *Active* in the **Status** column.

**CLI**

To create the rule with the Azion CLI, save its definition as `rule.json`. The file carries the rule's `name`, whether it is `active`, its `criteria`, and its `behaviors`:

```json
{
  "name": "deny-test-path",
  "active": true,
  "criteria": [
    [
      {
        "variable": "${request_uri}",
        "conditional": "if",
        "operator": "starts_with",
        "argument": "/deny-test"
      }
    ]
  ],
  "behaviors": [
    {
      "type": "deny"
    }
  ]
}
```

`criteria` is a list of groups, and each group is a list of conditions. The first condition takes `"conditional": "if"`, and each later one takes `and` or `or`.

Then create the rule on your firewall, with its ID in place of `<firewall-id>`:

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

The command prints the ID of the new rule:

```text
Created Firewall Rule with ID <rule-id>
```

The rule is active on the firewall, because the file sets `"active": true`. `azion create firewall-rule` accepts only `--firewall-id` and `--file`. The file holds the same body that the API accepts.

**API**

To create the rule with the API, send a `POST` request to the `request_rules` endpoint of your firewall. The body carries the rule's `name`, whether it is `active`, its `criteria`, and its `behaviors`:

```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 '{
  "name": "deny-test-path",
  "active": true,
  "criteria": [
    [
      {
        "variable": "${request_uri}",
        "conditional": "if",
        "operator": "starts_with",
        "argument": "/deny-test"
      }
    ]
  ],
  "behaviors": [
    {
      "type": "deny"
    }
  ]
}'
```

`criteria` is a list of groups, and each group is a list of conditions. The first condition takes `"conditional": "if"`, and each later one takes `and` or `or`. An optional `description` key holds a note about the rule.

The API answers `202` and returns the rule:

```text
{"state":"pending","data":{"id":<rule-id>,…,"behaviors":[{"type":"deny"}],"description":"","order":0}}
```

The response adds the rule's `id`, an empty `description`, and its `order`. The `order` is the rule's position among the firewall's rules, counted from `0`. Send the body as `application/json`: any other `Content-Type` is refused with `415` and the error `10009 Unsupported Media Type`.

For every variable, operator, and behavior the body accepts, refer to [Rules Engine for Firewall](/en/documentation/platform/firewall/rules-engine/#api) and the [Azion API reference](https://api.azion.com/).

The firewall processes its rules in list order, and a `deny` behavior ends that processing for the request it refuses. For more information, refer to [How Firewall works](/en/documentation/platform/firewall/how-it-works/#rule-order).

---

## Confirm that the rule denies the path

A new rule takes effect 6 min 29 s to 9 min 18 s after you create it. Until then, `/deny-test` answers as it did before. While the change spreads, requests can receive the old answer and the new one in turn. A workload newly bound to a firewall can take several minutes to enforce its first rule, and no duration is guaranteed.

To confirm the rule, send a request to the test path, with your workload's domain in place of `<your-domain>`:

```bash
curl -i https://<your-domain>/deny-test
```

The firewall refuses the request with `403`:

```text
HTTP/2 403
server: nginx
date: Thu, 01 Jan 2026 12:00:00 GMT
content-type: text/html; charset=utf-8
x-content-type-options: nosniff
x-azion-request-id: 0123456789abcdef0123456789abcdef
x-azion-edge-location: <edge-location>
alt-svc: h3=":443"; ma=86400
```

The body is Azion's default error page. It reads `Forbidden` and shows the same request ID as the `x-azion-request-id` header. A request to any other path still reaches your application.

If `/deny-test` still answers after 9 min 18 s, refer to [Troubleshoot Firewall](/en/documentation/platform/firewall/troubleshooting/). For more information on propagation, refer to [How Firewall works](/en/documentation/platform/firewall/how-it-works/#propagation).

---

## Require a client certificate

The rule in this section matches a request whose client presents no certificate and answers it with `401` and a JSON body. Use it to enforce an mTLS policy, such as one that BACEN compliance requires. The *Ssl Verification Status* criterion and the *Set Custom Response* behavior need no Product on the firewall.

To create the rule in Azion Console:

1. **Open the firewall bound to your workload**

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

2. **Select the Rules Engine tab**

3. **Start a new rule**

   Select **Rule**.

4. **Name the rule**

   In the **General** section, enter a **Name**, such as `require-client-certificate`.

5. **Set the criterion**

   In the **Criteria** section, select *Ssl Verification Status* as the variable and *is equal* as the operator. In **Select an SSL Status**, select *Missing Client Certificate*.

6. **Add the behavior**

   In the **Behaviors** section, select *Set Custom Response* as the behavior.

7. **Enter the status code**

   In **Status code**, enter `401`.

8. **Enter the content type**

   In **Content Type**, enter the MIME type of the response body, such as `application/json`.

9. **Enter the response body**

   In **Content Body**, enter the message the client receives, such as `{}`.

10. **Save the rule**

    Select **Save**.

Azion Console shows `Rule successfully created`. Once the rule takes effect, a request without a client certificate receives `401` and the body you entered.

For every option of this criterion and this behavior, refer to [Rules Engine for Firewall](/en/documentation/platform/firewall/rules-engine/#set-custom-response).

To forward the client certificate's Common Name (CN) to your origin instead, use [Rules Engine for Applications](/en/documentation/platform/applications/rules-engine/). There, a behavior that adds a request header, such as `client_cn`, sends the `${ssl_client_s_dn_parsed}` variable. For the complete setup, refer to [Pass client certificate details to the origin](/en/documentation/guides/application-security/tls-and-certificates/associate-an-mtls-certificate/#pass-client-certificate-details-to-the-origin).

---

## Next steps

- [Rules Engine for Firewall](/en/documentation/platform/firewall/rules-engine.md): Every criterion, operator, and behavior a firewall rule accepts, and the errors the API returns.
- [How Firewall works](/en/documentation/platform/firewall/how-it-works.md#how-rules-run): How a firewall runs its rules in order, and which behaviors end the list.
- [Apply a rule set to every request](/en/documentation/guides/application-security/firewall-and-waf/apply-rule-set.md): Add a rule whose Set WAF behavior hands every request to a WAF rule set.
- [Block requests by IP, ASN, or country](/en/documentation/guides/application-security/bots-and-network/blocklists-ip-addresses-edge.md): Deny the addresses, autonomous systems, or countries that a network list holds.
