---
name: azion-block-addresses-until-a-date
description: >-
  Deny an address until a due date with a dated network list entry and a firewall rule, then end the block with a write of the list.
---

# Block addresses until a date

You can block an address until a date of your choice from Azion Console, the [Azion CLI](/en/documentation/devtools/cli/), or the API. For example, an address that abused a login form can stay blocked for one day. The entry for that address in an `ip_cidr` [network list](/en/documentation/platform/firewall/network-shield/network-lists/) carries the due date. One [firewall](/en/documentation/platform/firewall/) rule denies every address in the list. The date alone never lifts the block: the address stays denied until a write of the list's items drops its entry. To block an address with no end date, refer to [Block requests by IP, ASN, or country](/en/documentation/guides/application-security/bots-and-network/blocklists-ip-addresses-edge/).

---

Select the interface for this guide. Its prerequisites and every task on this page switch to that interface.

## Prerequisites

- A [workload](/en/documentation/platform/workloads/) bound to a firewall. The rule that denies the list goes on that firewall.
- [Network Shield](/en/documentation/platform/firewall/#network-shield) on for that firewall. It starts on in every firewall and stays on until someone turns it off.

**Console**

- An account that can sign in to [Azion Console](https://console.azion.com/).

**CLI**

- The Azion CLI, installed and authenticated with a [personal token](/en/documentation/fundamentals/personal-tokens/).
- The ID of the firewall that your workload is bound to.

**API**

- A [personal token](/en/documentation/fundamentals/personal-tokens/). Each request in this guide sends it in place of `[TOKEN VALUE]`.
- The ID of the firewall that your workload is bound to.

---

## Create a list with a dated entry

Only a list of the `ip_cidr` type, shown as *IP/CIDR* in Azion Console, accepts annotations on its items. An annotated item is refused with `22011` in an `asn` list and with `22015` in a `countries` list. A due date follows the address after a space. It is `--LT` in uppercase, then a UTC date and time in whole seconds that ends in `Z`, such as `--LT2030-01-01T00:00:00Z`. A comment starts with `#` and goes last on the line, after any due date. A line that starts with `#` is not a comment, and the API refuses it with `22005`.

The list in this guide holds two items. `198.51.100.7` carries a due date and the comment `#login abuse`, while `192.0.2.10` carries neither. The undated item keeps the list writable after the date passes. A write in which every item is past due is refused with `22019 All Network Items Are Expired`. For the annotation grammar, refer to [Item annotations](/en/documentation/platform/firewall/network-shield/network-lists/#item-annotations). For the fields of a list and its three types, refer to [Network list fields](/en/documentation/platform/firewall/network-shield/network-lists/#network-list-fields) and [List types](/en/documentation/platform/firewall/network-shield/network-lists/#list-types).

**Console**

To create the list with the dated entry in Azion Console:

1. **Open the Network Lists page**

   Access [Azion Console](https://console.azion.com/) > **Edge Libraries** > **Network Lists**.

2. **Select Network List**

3. **Name the list**

   In the **General** section, enter a **Name**. For example: `Blocked addresses`.

4. **Select the IP/CIDR type**

   In the **Network List Settings** section, select *IP/CIDR*. When the form opens, *ASN* is the selected type.

5. **Enter the two entries**

   In the **List** field, enter each entry on its own line. The first one carries a due date and a comment, and the second carries neither:

   ```text
   198.51.100.7 --LT2030-01-01T00:00:00Z #login abuse
   192.0.2.10
   ```

   Write the UTC date and time when the block should end in place of `2030-01-01T00:00:00Z`. A date that is not in the future is flagged with `the --LT date must be in the future`.

6. **Save the list**

   Select **Save**.

Azion Console confirms with the message `Your network list has been created`. In **Network Lists**, the **List Type** column of the list reads *IP/CIDR*.

**CLI**

To create the list with the Azion CLI, write it to a file named `network-list.json`. Write the UTC date and time when the block should end in place of `2030-01-01T00:00:00Z`:

```json
{
  "name": "Blocked addresses",
  "type": "ip_cidr",
  "items": [
    "198.51.100.7 --LT2030-01-01T00:00:00Z #login abuse",
    "192.0.2.10"
  ]
}
```

Create the list from that file:

```bash
azion create network-list --file network-list.json
```

The output carries the ID of the list:

```text
Created Network List with ID <network-list-id>
```

The list stores both items as the file writes them, due date and comment included. Keep the ID, because the rule refers to the list by it.

**API**

To create the list with the API, send it in a `POST` request to `/v4/workspace/network_lists`. Put your personal token in place of `[TOKEN VALUE]`. Write the UTC date and time when the block should end in place of `2030-01-01T00:00:00Z`:

```bash
curl -X POST https://api.azion.com/v4/workspace/network_lists \
  -H "Authorization: Token [TOKEN VALUE]" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"Blocked addresses","type":"ip_cidr","items":["198.51.100.7 --LT2030-01-01T00:00:00Z #login abuse","192.0.2.10"]}'
```

The API answers `201`, and it stores both items exactly as sent, annotations included. This excerpt of the response keeps the fields that the rule and the removal use:

```json
{
  "state": "executed",
  "data": {
    "id": <network-list-id>,
    "name": "Blocked addresses",
    "type": "ip_cidr",
    "items": ["198.51.100.7 --LT2030-01-01T00:00:00Z #login abuse", "192.0.2.10"],
    ...
  }
}
```

Keep the value of `data.id`. The rule sends it as a number.

---

## Create the rule that denies the listed addresses

The rule reads the list through the *Network* criterion with its *matches* operator. Its *Deny (403 Forbidden)* behavior refuses each client that matches. It denies both addresses for as long as their items stay stored in the list. A due date that passes does not change what the rule matches. For every criterion and behavior a rule takes, refer to [Rules Engine for Firewall](/en/documentation/platform/firewall/rules-engine/#criteria).

**Console**

To create the deny rule in Azion Console:

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

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

2. **Select the Rules Engine tab**

3. **Select Rule**

   Azion Console opens the **Create Rule** drawer.

4. **Name the rule**

   In the **General** section, enter a **Name**. For example: `Deny listed addresses`.

5. **Set the Network criterion**

   In the **Criteria** section, select the *Network* variable and the *matches* operator.

   A variable that reads *Network - required Network Shield* means that Network Shield is off on this firewall. Turn it on in **Main Settings** > **Modules** and save the firewall, and the variable becomes selectable.

6. **Select the list**

   In the **Select a Network** dropdown, select `Blocked addresses`.

7. **Add the Deny behavior**

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

8. **Save the rule**

   Select **Save**.

Azion Console confirms with the message `Rule successfully created`.

**CLI**

To create the deny rule with the Azion CLI, write it to a file named `rule.json`. Put the ID of the list in place of `<network-list-id>`, as a number with no quotes:

```json
{
  "name": "Deny listed addresses",
  "active": true,
  "criteria": [
    [
      { "variable": "${network}", "conditional": "if", "operator": "is_in_list", "argument": <network-list-id> }
    ]
  ],
  "behaviors": [
    { "type": "deny" }
  ]
}
```

Create the rule from that file on the firewall bound to your workload. Put the ID of that firewall in place of `<firewall-id>`:

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

The output carries the ID of the rule:

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

The rule is active on the firewall, and it reads `Blocked addresses` by its ID.

**API**

To create the deny rule with the API, send a `POST` request to `/v4/workspace/firewalls/{firewall_id}/request_rules`. Write the ID of the firewall bound to your workload in place of `<firewall-id>`. Put `data.id` from the list response in place of `<network-list-id>`, as a number with no quotes:

```bash
curl -X POST https://api.azion.com/v4/workspace/firewalls/<firewall-id>/request_rules \
  -H "Authorization: Token [TOKEN VALUE]" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Deny listed addresses",
  "active": true,
  "criteria": [
    [
      { "variable": "${network}", "conditional": "if", "operator": "is_in_list", "argument": <network-list-id> }
    ]
  ],
  "behaviors": [
    { "type": "deny" }
  ]
}'
```

The API answers `202` and returns the rule as the firewall stores it:

```json
{
  "state": "pending",
  "data": {
    "id": <rule-id>,
    "name": "Deny listed addresses",
    "active": true,
    "criteria": [[{ "conditional": "if", "variable": "${network}", "operator": "is_in_list", "argument": <network-list-id> }]],
    "behaviors": [{ "type": "deny" }],
    "description": "",
    "order": 0
  }
}
```

The firewall holds the rule, active.

With the rule in traffic, a request from either address receives `403`. A rule you add can take from 6 minutes 29 seconds to 9 minutes 18 seconds to get there across Azion's distributed infrastructure. Send a request from a listed address again until it answers `403`.

> **Note**
>
> In the JSON body of the CLI and the API, `${network}` names the *Network* criterion and `is_in_list` its *matches* operator. `deny` names the *Deny (403 Forbidden)* behavior. The `argument` is the list ID as a JSON integer. For the operators and errors of the criterion, refer to [The Network criterion](/en/documentation/platform/firewall/network-shield/network-lists/#the-network-criterion). For the response a denied client gets, refer to [Deny (403 Forbidden)](/en/documentation/platform/firewall/rules-engine/#deny-403-forbidden).

---

## Remove the entry after its due date

Azion reads a due date only when the items of a list are written, and each write drops the items already past due. An item whose date passes after the write stays stored and keeps matching. Giving the list another name does not remove the item either.

A write of the list's items is what ends the block. Send it from the interface you use, or from a job of your own. That job can be a scheduled script, or the security information and event management (SIEM) system that flagged the address. Sent after each due date, the write drops every item past due by then.

**Console**

To remove the dated entry in Azion Console:

1. **Open the list**

   Access [Azion Console](https://console.azion.com/) > **Edge Libraries** > **Network Lists**, and select `Blocked addresses`.

2. **Delete the dated line**

   In the **List** field, delete the line for `198.51.100.7`. Once its date has passed, the form flags that line with `the --LT date must be in the future`.

3. **Save the list**

   Select **Save**.

Azion Console confirms with the message `Your Network List has been updated.`, and the list holds `192.0.2.10` alone.

**CLI**

The Azion CLI removes the dated entry with `--remove-item`, which matches the item exactly as the list stores it. To read the stored items, describe the list:

```bash
azion describe network-list --network-list-id <network-list-id>
```

The `Items` row still lists the dated entry:

```text
Items:           ["198.51.100.7 --LT2030-01-01T00:00:00Z #login abuse","192.0.2.10"]
```

Given the address alone, `--remove-item` removes nothing, yet it prints the same line as a removal. Pass the entry exactly as the `Items` row shows it, with its due date and comment:

```bash
azion update network-list --network-list-id <network-list-id> --remove-item "198.51.100.7 --LT2030-01-01T00:00:00Z #login abuse"
```

The output carries the ID of the list that changed:

```text
Updated Network List with ID <network-list-id>
```

The list holds `192.0.2.10` alone, and a second describe of the list reads that one item back.

**API**

The API drops the dated item when the list's items are written again. To read the stored items, send a `GET` request to `/v4/workspace/network_lists/{network_list_id}`:

```bash
curl https://api.azion.com/v4/workspace/network_lists/<network-list-id> \
  -H "Authorization: Token [TOKEN VALUE]" \
  -H "Accept: application/json"
```

The API answers `200`, and the dated item is still in `items`:

```json
{
  "data": {
    "id": <network-list-id>,
    ...
    "items": ["198.51.100.7 --LT2030-01-01T00:00:00Z #login abuse", "192.0.2.10"],
    ...
  }
}
```

Send those same items back in a `PATCH` request. The write drops each item whose due date has passed:

```bash
curl -X PATCH https://api.azion.com/v4/workspace/network_lists/<network-list-id> \
  -H "Authorization: Token [TOKEN VALUE]" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"items":["198.51.100.7 --LT2030-01-01T00:00:00Z #login abuse","192.0.2.10"]}'
```

The API answers `200`. The `items` array it returns keeps only the undated item:

```json
{
  "state": "executed",
  "data": {
    "id": <network-list-id>,
    ...
    "items": ["192.0.2.10"],
    ...
  }
}
```

The list holds `192.0.2.10` alone. A `PATCH` that carries only a `name` is no substitute, because the dated item stays stored after it.

Once the write reaches traffic, the rule no longer denies `198.51.100.7`. A change to the items of a list takes 46 seconds to about 100 seconds to get there, less than a rule you add. Until it settles, answers can switch between the old items and the updated ones. Repeat a request from that address until the answers agree. To try a list and a rule against your own address first, refer to [Network Shield quickstart](/en/documentation/platform/firewall/network-shield/quickstart/).

---

## Next steps

- [Network Lists](/en/documentation/platform/firewall/network-shield/network-lists.md#item-annotations): The grammar of a due date and a comment, and the error that each malformed item returns.
- [How Firewall works](/en/documentation/platform/firewall/how-it-works.md#network-shield): Its Network Shield section explains why a due date applies when the items are written, not when the date arrives.
- [Firewall best practices](/en/documentation/platform/firewall/best-practices.md#replace-a-network-list-from-your-own-source-of-truth): Its Network Shield section covers a SIEM or a script that pushes the whole list, so each push drops the expired items.
- [Troubleshoot Firewall](/en/documentation/platform/firewall/troubleshooting.md#an-entry-past-its-due-date-still-blocks): Its Network Shield section covers an entry that still refuses its client after the due date.
- [Guard one path with a network list](/en/documentation/guides/application-security/bots-and-network/guard-one-path.md): Chain a Request Uri criterion in the same block, so a deny rule covers one path and leaves the others open.
- [Firewall guides and tutorials](/en/documentation/platform/firewall/guides.md): Every guide for a firewall, with the other network list configurations among them.
