# Rules Engine para Firewall

Uma regra no Rules Engine para Firewall combina critérios, que decidem se uma requisição corresponde, com comportamentos, que agem sobre cada requisição que corresponde. Uma regra cujos critérios não correspondem não aplica nada. Para acompanhar uma requisição pelas regras de um [firewall](/pt-br/documentacao/plataforma/firewall/), consulte [Como Firewall funciona](/pt-br/documentacao/plataforma/firewall/como-funciona/).

Uma regra de firewall decide se uma requisição chega ou não à aplicação, porque o firewall recebe cada requisição antes da aplicação. Uma regra que escolhe como a aplicação serve uma requisição permitida, como o connector ou o cache setting dela, pertence ao [Rules Engine para Applications](/pt-br/documentacao/plataforma/applications/rules-engine/).

---

## Campos da regra

Cada firewall tem a sua própria lista de regras. Azion Console as mostra na aba **Rules Engine** do firewall, onde **Rule** abre o drawer **Create Rule**. A API as disponibiliza em `/v4/workspace/firewalls/<firewall-id>/request_rules`. Uma regra carrega dez campos: cinco que uma requisição define e cinco que a plataforma define e retorna.

| Campo           | Tipo                                                              | Obrigatório     | Padrão               | Descrição                                                                                                                                                                              |
| --------------- | ----------------------------------------------------------------- | --------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`            | integer                                                           | Somente leitura | —                    | O identificador que toda chamada posterior sobre a regra usa                                                                                                                           |
| `name`          | string, de 1 a 250 caracteres                                     | Sim             | —                    | O nome da regra. Azion Console o mostra como o campo **Name** e pede um nome único e descritivo                                                                                        |
| `description`   | string, até 1.000 caracteres                                      | Não             | `""`                 | Um comentário sobre a regra, mostrado na coluna **Description** da lista de regras. Com mais de 1.000 caracteres, Azion Console mostra `Description should not exceed 1000 characters` |
| `active`        | boolean                                                           | Não             | `true`               | Se a regra está ativa. Azion Console o mostra como o switch **Active** na seção **Status**, e a lista de regras mostra *Active* ou *Inactive*                                          |
| `criteria`      | array de 1 a 5 blocos, cada um sendo um array de 1 a 10 critérios | Sim             | —                    | As condições que uma requisição precisa atender. Cada valor está listado em Critérios                                                                                                  |
| `behaviors`     | array de objetos de comportamento, no mínimo 1                    | Sim             | —                    | O que a regra faz com uma requisição que corresponde. Cada valor está listado em Comportamentos                                                                                        |
| `order`         | integer                                                           | Somente leitura | Atribuído na criação | A posição da regra na lista de regras do firewall                                                                                                                                      |
| `last_editor`   | string                                                            | Somente leitura | —                    | A conta que alterou a regra pela última vez, mostrada na coluna **Last Editor**                                                                                                        |
| `last_modified` | date-time                                                         | Somente leitura | —                    | Quando a regra foi alterada pela última vez, mostrado na coluna **Last Modified**                                                                                                      |
| `created_at`    | date-time                                                         | Somente leitura | —                    | Quando a regra foi criada                                                                                                                                                              |

A plataforma atribui `order` na ordem de criação: a primeira regra de um firewall carrega `0`, e a décima primeira carrega `10`. A lista de regras do Azion Console permite reordenar as regras.

---

## Critérios

Os critérios decidem sobre quais requisições uma regra age. Cada critério nomeia uma variável, um operador de comparação e, para a maioria dos operadores, um argumento com o qual a variável é comparada. O drawer **Create Rule** abre com um critério já definido como *Request Uri* e *starts with*, e `${request_uri}` `starts_with` `/` corresponde a toda requisição que o workload recebe.

A tabela lista as variáveis na ordem do Azion Console. Nove delas exigem Web Application Firewall (WAF) habilitado no firewall, `Network` exige Network Shield e as outras cinco não exigem nenhum produto.

| Variável                      | Variável na API                    | Requer         | O que contém                                                                                                                       | Exemplo                            |
| ----------------------------- | ---------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| Header Accept                 | `${header_accept}`                 | WAF            | Os media types que o cliente aceita na resposta                                                                                    | `application/json`                 |
| Header Accept Encoding        | `${header_accept_encoding}`        | WAF            | As codificações de conteúdo, em geral algoritmos de compressão, que o cliente aceita na resposta                                   | `gzip`                             |
| Header Accept Language        | `${header_accept_language}`        | WAF            | O idioma que o cliente espera                                                                                                      | `en-US`                            |
| Header Cookie                 | `${header_cookie}`                 | WAF            | Os cookies que o cliente envia com a requisição                                                                                    | `session_id=abc123`                |
| Header Origin                 | `${header_origin}`                 | WAF            | A origem de uma requisição cross-site ou de uma requisição preflight: uma URI que nomeia o servidor, sem caminho                   | `https://example.com`              |
| Header Referer                | `${header_referer}`                | WAF            | O endereço do documento, ou do elemento nele, de onde a URI da requisição foi obtida                                               | `https://example.com/landing-page` |
| Header User Agent             | `${header_user_agent}`             | WAF            | A string que identifica a aplicação cliente, o sistema operacional, o fornecedor ou a versão                                       | `Mozilla/5.0`                      |
| Host                          | `${host}`                          | Nenhum         | Em ordem de precedência: o hostname na linha da requisição, o valor do header `Host` ou o nome do servidor que atende a requisição | `api.example.com`                  |
| Network                       | `${network}`                       | Network Shield | O endereço IP do cliente, comparado com os endereços IP e intervalos CIDR, os ASNs ou os países de uma network list                | `2`                                |
| Request Args                  | `${request_args}`                  | WAF            | Os argumentos na query string da requisição                                                                                        | `page=1`                           |
| Request Method                | `${request_method}`                | WAF            | O método HTTP da requisição                                                                                                        | `POST`                             |
| Request Uri                   | `${request_uri}`                   | Nenhum         | A URI da requisição                                                                                                                | `/api/v1/`                         |
| Scheme                        | `${scheme}`                        | Nenhum         | O esquema da requisição, HTTP ou HTTPS                                                                                             | `https`                            |
| Ssl Verification Status       | `${ssl_verification_status}`       | Nenhum         | O resultado da validação do certificado do cliente                                                                                 | `CERTIFICATE_VERIFICATION_ERROR`   |
| Client Certificate Validation | `${client_certificate_validation}` | Nenhum         | O processo do servidor que autentica o certificado digital do cliente                                                              | `true`                             |

Quando o firewall não tem o produto que uma variável exige, Azion Console ainda lista a variável, mas não permite selecioná-la. O rótulo então carrega um sufixo, como *Header Accept - required WAF* ou *Network - required Network Shield*. A API recusa uma regra que usa `${network}` em um firewall sem Network Shield, com `400` e o código `25047`.

`Network` compara o endereço IP do cliente com uma [network list](/pt-br/documentacao/plataforma/firewall/network-shield/network-lists/). No Azion Console, o argumento passa a ser a lista **Select a Network**, que mostra todas as network lists da conta e termina com **Create Network List**. Na API, o argumento é o ID da lista, enviado como um inteiro JSON. Por exemplo, `2` é a lista de exit nodes do Tor que a Azion fornece, e qualquer regra pode referenciá-la. O mesmo ID enviado como string é recusado com `400` e o código `25042`.

Depois que uma regra do firewall usa `${network}`, Network Shield não pode ser desativado nesse firewall. A API responde `400` com o código `24005` e nomeia as regras que o mantêm.

`Request Args` não contém nada quando a requisição não tem query string, e uma variável vazia não corresponde. Por exemplo, uma regra com `${request_args}` `matches` `.*` ignora todo POST que carrega o payload no corpo e nada na query string.

`Ssl Verification Status` recebe um de três valores, que Azion Console oferece na lista **Select an SSL Status**:

| Valor                            | Argumento na API                 | Significado                                       |
| -------------------------------- | -------------------------------- | ------------------------------------------------- |
| *Success*                        | `SUCCESS`                        | O certificado do cliente passou na validação      |
| *Certificate Verification Error* | `CERTIFICATE_VERIFICATION_ERROR` | O certificado do cliente não era válido           |
| *Missing Client Certificate*     | `MISSING_CLIENT_CERTIFICATE`     | A requisição não carregava certificado de cliente |

### Operadores

Um critério compara a sua variável com o seu argumento por meio de um operador. Azion Console rotula cada operador em letras minúsculas, e a API envia o valor da segunda coluna como `operator`.

| Operador            | Valor na API          | O critério corresponde quando                                                                          | Argumento         |
| ------------------- | --------------------- | ------------------------------------------------------------------------------------------------------ | ----------------- |
| is equal            | `is_equal`            | O valor é igual ao argumento, comparado caractere por caractere                                        | String            |
| is not equal        | `is_not_equal`        | O valor não é exatamente o argumento                                                                   | String            |
| starts with         | `starts_with`         | O valor começa com o argumento                                                                         | String            |
| does not start with | `does_not_start_with` | O valor não começa com o argumento                                                                     | String            |
| matches             | `matches`             | O valor corresponde à expressão regular do argumento                                                   | Expressão regular |
| does not match      | `does_not_match`      | O valor não corresponde à expressão regular do argumento                                               | Expressão regular |
| exists              | `exists`              | A variável tem um valor. `Request Args` existe quando a query string carrega um argumento              | Nenhum            |
| does not exist      | `does_not_exist`      | A variável não tem valor. `Request Args` não existe quando a query string não carrega nenhum argumento | Nenhum            |

Azion Console oculta o campo de argumento para *exists* e *does not exist*, e o substitui por uma lista para `Network` e `Ssl Verification Status`.

`Network` é a exceção à tabela. Os seus *matches* e *does not match* carregam os valores de API `is_in_list` e `is_not_in_list`, e os dois comparam o endereço IP do cliente com a network list que o argumento nomeia. A API recusa `matches` em `${network}` com `400` e o código `25039`.

Cada variável oferece apenas alguns dos operadores:

| Variável                                                                                                                       | Operadores                                                                        |
| ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- |
| Header Accept, Header Accept Encoding, Header Accept Language, Header Cookie, Header Origin, Header Referer, Header User Agent | matches, does not match                                                           |
| Host                                                                                                                           | is equal, is not equal, matches, does not match                                   |
| Network                                                                                                                        | matches (`is_in_list`), does not match (`is_not_in_list`)                         |
| Request Args                                                                                                                   | is equal, is not equal, matches, does not match, exists, does not exist           |
| Request Method                                                                                                                 | is equal, is not equal                                                            |
| Request Uri                                                                                                                    | is equal, is not equal, starts with, does not start with, matches, does not match |
| Scheme, Ssl Verification Status, Client Certificate Validation                                                                 | is equal, is not equal                                                            |

### Condicionais

Os critérios se combinam dentro de blocos, e uma regra tem de 1 a 5 blocos de 1 a 10 critérios cada. Dentro de um bloco, o primeiro critério carrega o condicional `if`, e cada critério seguinte carrega `and` ou `or`. Os blocos são unidos por And, que Azion Console exibe entre eles, então uma requisição corresponde à regra somente quando corresponde a todos os blocos.

No Azion Console, **And** e **Or** adicionam um critério a um bloco, e **Add Criteria** adiciona um bloco. Azion Console desabilita **And** e **Or** quando um bloco chega a 10 critérios, e **Add Criteria** quando a regra chega a 5 blocos. Os divisores entre critérios mostram o condicional como If, And ou Or.

Na API, `criteria` é uma lista de blocos, e cada bloco é uma lista de objetos de critério. A regra deste exemplo tem um bloco de dois critérios. Ela nega uma requisição somente quando o endereço IP do cliente está na network list e a URI começa com `/ip-deny`:

```json
{
  "name": "ip-deny",
  "active": true,
  "criteria": [
    [
      { "variable": "${network}", "conditional": "if", "operator": "is_in_list", "argument": <network-list-id> },
      { "variable": "${request_uri}", "conditional": "and", "operator": "starts_with", "argument": "/ip-deny" }
    ]
  ],
  "behaviors": [{ "type": "deny" }]
}
```

O placeholder `<network-list-id>` representa um inteiro, sem aspas ao redor.

---

## Comportamentos

Os comportamentos são o que uma regra faz com uma requisição que corresponde aos seus critérios. Azion Console rotula a primeira linha de comportamento como **Then** e cada linha seguinte como **And**, e **Add Behavior** adiciona uma linha. Na API, cada comportamento é um objeto com um `type`, e os comportamentos que recebem configurações as carregam em `attributes`.

A coluna Requer nomeia o produto que o firewall precisa ter habilitado para que Azion Console ofereça o comportamento. Quando ele está desativado, Azion Console mostra *Set WAF - required WAF* ou *Run Function - required Functions* e não permite selecioná-lo. Nenhum dos seis comportamentos exige Network Shield.

| Comportamento                 | `type` na API         | Requer    | Atributos                                                      | O que o cliente recebe                                                                                                   |
| ----------------------------- | --------------------- | --------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Deny (403 Forbidden)          | `deny`                | Nenhum    | Nenhum                                                         | `403`, com a página de erro padrão da Azion intitulada Forbidden                                                         |
| Drop (Close Without Response) | `drop`                | Nenhum    | Nenhum                                                         | Nenhuma resposta: nem linha de status nem corpo                                                                          |
| Set Rate Limit                | `set_rate_limit`      | Nenhum    | `type`, `limit_by`, `average_rate_limit`, `maximum_burst_size` | `429` para uma requisição que o limite não admite, com a página de erro padrão intitulada Too Many Requests              |
| Set WAF                       | `set_waf`             | WAF       | `waf_id`, `mode`                                               | `400` para uma requisição que o rule set bloqueia no modo `blocking`, com a página de erro padrão intitulada Bad Request |
| Run Function                  | `run_function`        | Functions | `value`                                                        | O que o código da instância de função fizer com a requisição                                                             |
| Set Custom Response           | `set_custom_response` | Nenhum    | `status_code`, `content_type`, `content_body`                  | O status code, o `Content-Type` e o corpo que os atributos definem                                                       |

Azion Console também limita como os comportamentos se combinam. Somente *Run Function* e *Set WAF* podem ser seguidos por outro comportamento, e cada um aparece no máximo uma vez em uma regra. Escolher *Deny (403 Forbidden)*, *Drop (Close Without Response)*, *Set Rate Limit* ou *Set Custom Response* remove todas as linhas de comportamento depois dele.

### Deny (403 Forbidden)

*Deny (403 Forbidden)* recusa a requisição com `403` e não recebe atributos. O corpo é a página de erro padrão da Azion intitulada Forbidden, com cerca de 10,6 KB de HTML, que mostra o endereço IP do cliente e o ID da requisição. Nenhum header de resposta nomeia o firewall ou a regra. Na API, o comportamento é `{ "type": "deny" }`.

### Drop (Close Without Response)

*Drop (Close Without Response)* encerra a requisição sem respondê-la e não recebe atributos. O cliente não recebe linha de status nem corpo, de imediato. Um script que lê o status code vê `000`, e um navegador mostra um erro de conexão. Na API, o comportamento é `{ "type": "drop" }`.

Em HTTP/2, o curl informa o reset do stream e sai com o código 92:

```text
curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)
```

Em HTTP/1.1 e em HTTP simples, o curl sai com o código 52:

```text
curl: (52) Empty reply from server
```

### Set Rate Limit

*Set Rate Limit* limita a taxa das requisições a que a regra corresponde. Uma requisição que a taxa e o burst não admitem recebe `429`, com a página de erro padrão intitulada Too Many Requests. Nenhuma resposta carrega um header de rate limit, como `retry-after` ou um header `x-ratelimit-`.

| Atributo             | Campo no Console       | Valores                                                  | Descrição                                                                                                                                  |
| -------------------- | ---------------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `type`               | **Rate Limit Type**    | `second` (*Req/s*) ou `minute` (*Req/min*)               | O período em que a taxa é contada. O padrão é `second`                                                                                     |
| `limit_by`           | **Limit By**           | `client_ip` (*Client IP address*) ou `global` (*Global*) | Se a taxa é contada por endereço IP do cliente ou sobre todas as requisições. Obrigatório. Azion Console pré-seleciona *Client IP address* |
| `average_rate_limit` | **Average Rate Limit** | Inteiro, no mínimo 1                                     | As requisições permitidas por segundo ou por minuto, conforme `type` define. Obrigatório                                                   |
| `maximum_burst_size` | **Maximum Burst Size** | Inteiro, no mínimo 1                                     | As requisições extras toleradas em um pico curto. Vale apenas para `second`: Azion Console oculta o campo para *Req/min* e não o envia     |

Um rate limit de 10 requisições por segundo por endereço IP do cliente, com burst de 10:

```json
{
  "type": "set_rate_limit",
  "attributes": { "type": "second", "limit_by": "client_ip", "average_rate_limit": 10, "maximum_burst_size": 10 }
}
```

Para saber como a taxa e o burst admitem requisições, consulte [Como Firewall funciona](/pt-br/documentacao/plataforma/firewall/como-funciona/).

### Set WAF

*Set WAF* aplica um [rule set](/pt-br/documentacao/plataforma/firewall/waf/rule-sets/) de WAF às requisições a que a regra corresponde, e exige WAF habilitado no firewall. Um rule set só é executado quando uma regra carrega esse comportamento, e uma regra carrega no máximo um. Os rule sets ficam no Azion Console em **Edge Libraries** > **WAF Rules**.

| Atributo | Controle no Console   | Valores                                          | Descrição                                                         |
| -------- | --------------------- | ------------------------------------------------ | ----------------------------------------------------------------- |
| `waf_id` | **Select a WAF**      | Inteiro                                          | O ID do rule set a aplicar. Obrigatório                           |
| `mode`   | **Select a WAF mode** | `logging` (*Logging*) ou `blocking` (*Blocking*) | Se WAF recusa as requisições que o rule set sinaliza. Obrigatório |

No modo `blocking`, uma requisição que o rule set bloqueia recebe `400` com a página de erro padrão intitulada Bad Request, e nenhum header de resposta nomeia WAF. No modo `logging`, WAF não recusa a requisição. A API recusa um comportamento `set_waf` sem `mode` e qualquer `mode` diferente de `logging` ou `blocking`, inclusive `learning`.

Um comportamento que aplica um rule set no modo `blocking`:

```json
{ "type": "set_waf", "attributes": { "waf_id": <waf-rule-set-id>, "mode": "blocking" } }
```

### Run Function

*Run Function* executa uma [instância de função](/pt-br/documentacao/plataforma/firewall/functions-instances/) do firewall nas requisições a que a regra corresponde, e exige [Functions](/pt-br/documentacao/plataforma/functions/) habilitado no firewall. Um firewall criado pela API, pela CLI ou pela página de criação do Azion Console tem Functions ativado, e o drawer de criação do Azion Console começa com ele desativado.

O atributo `value` contém o ID da instância de função, não o da função. As instâncias ficam na aba **Functions Instances** do firewall. No Azion Console, **Select a Function** lista as instâncias ativas deste firewall, e **Create Function Instance** cria uma a partir dessa lista. Uma regra carrega no máximo um comportamento *Run Function*. Para criar uma instância, consulte [Instancie uma função em um firewall](/pt-br/documentacao/guias/seguranca-de-aplicacoes/firewall-e-waf/instanciar-functions/).

Um comportamento que executa uma instância de função:

```json
{ "type": "run_function", "attributes": { "value": <function-instance-id> } }
```

Para o código que uma função de firewall executa, consulte [Functions no Firewall](/pt-br/documentacao/plataforma/firewall/functions/).

### Set Custom Response

*Set Custom Response* responde à requisição com o status code, o content type e o corpo que define, e não exige nenhum produto. As três configurações vão em `attributes`, como em todo comportamento que recebe configurações.

| Atributo       | Campo no Console | Valores                    | Descrição                                                     |
| -------------- | ---------------- | -------------------------- | ------------------------------------------------------------- |
| `status_code`  | **Status code**  | Inteiro, de 200 a 499      | O status code da resposta. Obrigatório                        |
| `content_type` | **Content Type** | String, até 255 caracteres | O valor do header `Content-Type`. O padrão é uma string vazia |
| `content_body` | **Content Body** | String, até 500 caracteres | O corpo da resposta. O padrão é uma string vazia              |

---

## API

Toda operação de regra é autenticada e fica em `https://api.azion.com/v4/workspace/firewalls/<firewall-id>/request_rules`. Uma requisição carrega um personal token no header `Authorization`, com o esquema `Token`, e uma requisição com corpo também carrega `Content-Type: application/json`.

| Operação                        | Método e caminho                          |
| ------------------------------- | ----------------------------------------- |
| Criar uma regra                 | `POST /request_rules`                     |
| Listar as regras de um firewall | `GET /request_rules`                      |
| Consultar uma regra             | `GET /request_rules/{request_rule_id}`    |
| Atualizar parte de uma regra    | `PATCH /request_rules/{request_rule_id}`  |
| Excluir uma regra               | `DELETE /request_rules/{request_rule_id}` |

Uma criação e uma exclusão respondem `202`, e uma leitura responde `200`.

Esta chamada cria uma regra que nega toda requisição cuja URI começa com `/deny-test`:

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

A resposta carrega `202` e um `state` igual a `pending`. Este trecho da resposta mantém os campos que a plataforma adicionou:

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

A plataforma adiciona `description`, uma string vazia quando a criação não envia nenhuma, e `order`, a posição da regra no firewall. O `id` em `data` é o identificador que toda chamada posterior sobre a regra usa.

---

## CLI

Azion CLI gerencia regras com o substantivo `firewall-rule`. `azion create firewall-rule` recebe apenas `--firewall-id` e `--file`, então os critérios e os comportamentos de uma regra ficam no mesmo corpo JSON que a API recebe.

| Comando                        | O que faz                                                                                                            |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| `azion create firewall-rule`   | Cria uma regra a partir de um arquivo JSON, com `--firewall-id` e `--file`                                           |
| `azion list firewall-rule`     | Lista as regras de um firewall, com `--firewall-id`. `--details` adiciona as colunas `LAST EDITOR` e `LAST MODIFIED` |
| `azion describe firewall-rule` | Retorna uma regra, com `--firewall-id` e `--rule-id`. `--format json` imprime o registro completo                    |

Este arquivo descreve uma regra que nega, em `/cli-rule`, as requisições dos países de uma network list:

```json
{
  "name": "cli-rule",
  "description": "Deny requests from countries in the list on /cli-rule.",
  "active": true,
  "criteria": [
    [
      { "variable": "${network}", "conditional": "if", "operator": "is_in_list", "argument": <network-list-id> },
      { "variable": "${request_uri}", "conditional": "and", "operator": "starts_with", "argument": "/cli-rule" }
    ]
  ],
  "behaviors": [
    { "type": "deny" }
  ]
}
```

Salve-o como `rule.json`, substitua `<network-list-id>` pelo ID da lista como inteiro e crie a regra:

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

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

---

## Erros

Uma regra rejeitada retorna um array `errors`. Cada entrada carrega um `code`, um `title`, um `detail`, o `status` e um ponteiro `source` que nomeia o campo, e algumas entradas adicionam um objeto `meta`:

```json
{
  "errors": [
    {
      "code": "25047",
      "title": "Missing Required Modules",
      "detail": "variable \"${network}\" is not available for this Edge Firewall. It requires ANY of the following modules to be enabled: ['network_protection_enabled'].",
      "status": "400",
      "source": { "pointer": "/data/criteria" },
      "meta": {
        "message_prefix": "variable \"${network}\" is not available for this Edge Firewall.",
        "owner_modules": "ANY",
        "missing_required_modules": ["network_protection_enabled"]
      }
    }
  ]
}
```

| Código  | Título                                            | Status | O que causa                                                                                                                                                                                                                                    | O que fazer                                                                                                               |
| ------- | ------------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `10039` | Invalid Choice                                    | 400    | Um valor fora de um enum: uma `variable` como `$(network)`, uma grafia que a especificação da API v4 lista, um `conditional` diferente de `if`, `and` ou `or`, ou um `mode` como `learning`. O `detail` diz `"<value>" is not a valid choice.` | Envie um valor listado. O ponteiro `source` nomeia o campo, como `/data/criteria/0/0/conditional`                         |
| `10059` | Required Field                                    | 400    | Um campo obrigatório ausente, como um comportamento `set_waf` sem `mode`, em `/data/behaviors/0/attributes/mode`                                                                                                                               | Adicione o campo que o ponteiro `source` nomeia                                                                           |
| `24005` | Cannot Disable Firewall Network Protection Module | 400    | Desativar Network Shield em um firewall cujas regras usam `${network}`                                                                                                                                                                         | Altere ou exclua as regras que o `detail` lista e, depois, desative Network Shield                                        |
| `25030` | Entity Not Found                                  | 400    | Um argumento de `${network}` que nomeia uma network list inexistente. O `detail` diz `Network List '<network-list-id>' not found.`                                                                                                             | Envie o ID de uma lista existente                                                                                         |
| `25031` | Entity Not Active                                 | 400    | Um argumento de `${network}` que nomeia uma network list inativa. O `detail` diz `Network List '<network-list-id>' is not active.`                                                                                                             | Ative a lista e, depois, crie a regra                                                                                     |
| `25036` | Invalid Informed WAF                              | 400    | Um `waf_id` que não nomeia nenhum rule set. O `detail` diz `The informed WAF (<waf-id>) is not valid.`, e `meta.waf_id` repete o valor                                                                                                         | Envie o ID de um rule set existente                                                                                       |
| `25039` | Invalid Operator                                  | 400    | `${network}` com o operador `matches`. O `detail` diz `The operator 'matches' is not valid for the '${network}' variable.`                                                                                                                     | Envie `is_in_list` ou `is_not_in_list`                                                                                    |
| `25042` | Invalid Operator Argument Type                    | 400    | Um argumento de `${network}` enviado como string, como `"57102"`, o tipo que a especificação da API v4 dá a ele. O `detail` diz `The argument type '<network-list-id>' is not valid for the operator 'is_in_list'.`                            | Envie o ID da network list como inteiro JSON                                                                              |
| `25047` | Missing Required Modules                          | 400    | Uma regra que usa `${network}` em um firewall sem Network Shield                                                                                                                                                                               | Habilite Network Shield no firewall, com `modules.network_protection.enabled` definido como `true`, e depois crie a regra |

Duas recusas da CLI não carregam código. Uma regra cujo comportamento `run_function` nomeia uma instância de função inexistente falha com `Error: failed to create the Firewall Rule: ["Function Instance '99999999' not found."]`, com o ID que o arquivo enviou. Um comportamento escrito com `name` em vez de `type` falha com `Error: Failed to decode the given 'json' file. Verify if the file format is JSON or fix its content according to the JSON format specification at https://www.json.org/json-en.html`, embora o arquivo seja um JSON válido: a chave que a plataforma lê é `type`.

---

## Recursos relacionados

- [Como Firewall funciona](/pt-br/documentacao/plataforma/firewall/como-funciona.md): Como um firewall executa as suas regras em uma requisição, em que ordem e quando um comportamento interrompe as demais.
- [Crie uma regra de firewall](/pt-br/documentacao/guias/seguranca-de-aplicacoes/firewall-e-waf/trabalhar-com-rules-engine.md): O procedimento que cria uma regra no Azion Console.
- [Configurações principais do firewall](/pt-br/documentacao/guias/seguranca-de-aplicacoes/firewall-e-waf/firewall-definir-main-settings.md): Onde habilitar WAF, Network Shield e Functions em um firewall antes que uma regra os use.
- [Crie e aplique um WAF rule set](/pt-br/documentacao/guias/seguranca-de-aplicacoes/firewall-e-waf/criar-waf-rule-set.md): O procedimento que cria um rule set e o aplica com um comportamento Set WAF.
