# rules

> openwaf-cloud ctl rules commands to list, add and remove a zone's edge rules: IP, country, WAF exceptions and simple rate limits.

Edge rules apply to every name of the zone unless you limit them with `hosts`. Every change is a new zone version and accepts `--reason`, `--dry-run`, `--yes` and `--wait`.

## rules list

```text
rules list <zone> [--json]
```

The zone's rules with their id, kind, details, action, the names they are limited to and their note.

## rules add

```text
rules add <zone> kind=… key=value … [hosts:='["a.example.com"]'] [note=…] --reason "…"
```

| `kind` | Keys |
|---|---|
| `ip` | `ip` (an address or a CIDR range, such as `203.0.113.0/24`), `action` (`block` or `allow`). |
| `geo` | `country_code` (two letters, such as `ES`), `action` (`block` or `allow`). |
| `waf_exception` | `rule_id` (required: the WAF rule to skip), `path_pattern` (empty: every path). |
| `rate_limit` | `rpm` (required: requests per minute), `burst` (default 0), `path_pattern`, `method`. |

Every kind also takes:

| Key | Meaning |
|---|---|
| `hosts:='["a.example.com"]'` | Limit the rule to these names of the zone. Without it, it applies to all of them. |
| `note` | A note, up to 500 characters. |

```sh
openwaf-cloud ctl rules add example.com kind=ip ip=203.0.113.0/24 action=block note="Scanner" --reason "Block scanner"
openwaf-cloud ctl rules add example.com kind=geo country_code=ES action=allow --reason "Allow Spain"
openwaf-cloud ctl rules add example.com kind=waf_exception rule_id=941100 path_pattern='/wp-admin/*' \
  hosts:='["blog.example.com"]' --reason "Editor false positive"
```

For per-path rate limiting with more control (keys, periods, actions), use [`ratelimit`](https://developers.openwaf.dev/cli/reference/ratelimit/).

## rules rm

```text
rules rm <zone> <id> --reason "…"
```

Removes the rule with that id (from `rules list`).
