# Create Firewall Rules with Rules Engine

import Tabs from '~/components/tabs/Tabs'
import Code from '~/components/Code/Code.astro'


Use [Rules Engine](/en/documentation/products/secure/firewall/rules-engine/) to define the conditions and behaviors your Firewall executes for each incoming request.

This guide walks you through creating a rule using a practical example: verifying whether a client certificate exists and returning a custom response when it doesn't. This is useful for enforcing mTLS policies, such as those required for BACEN compliance.

:::note
There are different criteria that require different Firewall modules. Make sure you have the [right module](/en/documentation/products/secure/firewall/rules-engine/#criteria) activated to create your rules.
:::

---

<Tabs client:visible>
    <Fragment slot="tab.console">Console</Fragment>
    <Fragment slot="tab.api">API</Fragment>

<Fragment slot="panel.console">
To create a rule:

1. Access [Azion Console](/en/documentation/products/guides/how-to-access-azion-console/) > **Firewall**.
2. Select the firewall in which you want to configure the rule.
3. Click the **Rules Engine** tab.
4. Click the **+ Rule** button.
5. Give your rule a name and, optionally, a description.
6. In the **Criteria** section, select the `SSL Verification Status` variable.
7. As a comparison operator, select `is equal`.
8. As an argument, select `Missing Client Certificate`.
9. In the **Behaviors** section, select **Set Custom Response**.
10. As arguments:
    - On **Status Code**, add `401`.
    - On **Content Type**, define the MIME type of the response body. Example: `application/json`.
    - On **Content Body**, pass the message you want to present to users.
11. Click the **Save** button.
</Fragment>

<Fragment slot="panel.api">
1. Run the following `POST` request to create a rule, replacing `[TOKEN VALUE]` with your [personal token](/en/documentation/products/guides/personal-tokens/) and the `<edge_firewall_id>` variable with your firewall id value:

<Code lang="bash" code={`
curl --request POST \
  --url https://api.azion.com/v4/edge_firewall/firewalls/<edge_firewall_id>/request_rules \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "SSL Verification",
    "active": true,
    "criteria": [
      [
        {
          "conditional": "if",
          "variable": "\${ssl_verification_status}",
          "operator": "is_equal",
          "argument": "MISSING_CLIENT_CERTIFICATE"
        }
      ]
    ],
    "behaviors": [
      {
        "type": "set_custom_response",
        "attributes": {
          "status_code": 401,
          "content_type": "application/json",
          "content_body": "{}"
        }
      }
    ]
  }'
`} />


| Key | Description |
| --- | --- |
| `name` | Name of the rule |
| `description` | Description of the rule |
| `behaviors` | Array that stores objects that define behaviors |
| `criteria` | Array that stores objects that define criteria |

Refer to the [Azion API documentation](https://api.azion.com/) for details on all available criteria and behavior objects.

2. You'll receive the following response:

<Code lang="json" code={`
{
  "results": {
    "name": "SSL Verification",
    "is_active": true,
    "behaviors": [
      {
        "status_code": 401,
        "content_body": "{}",
        "name": "set_custom_response",
        "content_type": "application/json"
      }
    ],
    "criteria": [
      [
        {
          "variable": "ssl_verification_status",
          "operator": "is_equal",
          "conditional": "if",
          "argument": "MISSING_CLIENT_CERTIFICATE"
        }
      ]
    ],
    "last_modified": "2023-11-23T23:54:14.941097Z",
    "last_editor": "your-email@example.com",
    "id": <id>,
    "order": 2
  },
  "schema_version": 3
}
`} />

3. Wait a few minutes for the changes to propagate.

:::tip
Check the [Azion API documentation](https://api.azion.com/) for details on all features available via API.
:::
</Fragment>

</Tabs>

---

:::tip
If you need to forward the authenticated client's identity to your origin server using mTLS — for example, passing the client certificate Common Name (CN) via the `client_cn` header — use [Rules Engine for Applications](/en/documentation/products/build/applications/rules-engine/) with the `${ssl_client_s_dn_parsed}` variable and the **Add Request Header** behavior. See [Specifying mTLS variables in HTTP headers](/en/documentation/products/guides/secure/mtls/#specifying-mtls-variables-in-http-headers) for a complete guide.
:::