Rule Lists¶
Core Concepts
Rule Lists let you keep IP addresses, IP ranges, and domain names in one reusable place, then use them in alert rules across every monitoring module. They are particularly useful for exemptions: define a trusted network or known domain set once, rather than repeating a long condition in each rule.
How rule lists work¶
Create a list from Rule Lists in the account menu. Choose one list type:
| Type | Accepted entries | Matching behaviour |
|---|---|---|
| IP address / CIDR | IPv4, IPv6, IPv4 CIDR, IPv6 CIDR | An event IP matches when it falls within any entry’s network. A single IP is treated as /32 (IPv4) or /128 (IPv6). |
| Domain | Fully-qualified domain names, including subdomains | Exact, case-insensitive domain matching. api.example.com and example.com are separate entries. |
The service normalizes entries when you save them. For example, 192.0.2.10 is stored as 192.0.2.10/32, and a trailing dot in a domain name is ignored. Wildcards and URLs are not valid domain-list entries.
List names¶
Choose a clear, lowercase name such as maintenance_networks, approved_domains, or partner_ranges. Names may contain lowercase letters, numbers, underscores, and hyphens.
Use the name in a CEL expression as a literal lookup:
in_list(ip_address, lists["maintenance_networks"])
Once a rule uses a list, its name cannot be changed and the list cannot be deleted. You can still update its description and entries.
Tip
Use a positive name that describes the contents, such as approved_domains or trusted_addresses. It makes negated exemption rules much easier to read later.
Using lists in CEL rules¶
in_list(value, lists["list_name"]) returns true when a string value matches the selected list. Prefix it with ! when the rule should apply only outside that list.
# Trigger only when an address is in a high-risk network.
in_list(ip_address, lists["high_risk_networks"])
# Exempt known maintenance targets from certificate connection alerts.
has_error && !in_list(ip_address, lists["maintenance_networks"])
The rule editor offers list names as autocomplete suggestions. List lookups must use a quoted, literal list name; computed lookups are not supported.
If an event field is not a valid IP address for an IP list, or is not a valid domain for a domain list, it simply does not match. It does not cause the rest of the rule to fail.
Useful rule patterns¶
Exempt known certificate names from CT alerts¶
cert.dns_names.exists(name,
name.endsWith(".example.com") && !in_list(name, lists["known_certificate_names"])
)
This avoids alerts for expected names while continuing to alert on unexpected names under your domain. Because domain lists are exact, add each approved hostname explicitly.
Alert on unapproved DNS A or AAAA targets¶
changed_records.exists(record,
(record.type == "A" || record.type == "AAAA") &&
record.new_values.exists(value,
!in_list(value, lists["approved_origin_networks"])
)
)
This is useful for detecting DNS changes that redirect traffic outside approved address ranges, while allowing CDNs, load balancers, and internal networks that you have explicitly approved.
Suppress certificate-monitor noise during maintenance¶
has_error && !in_list(ip_address, lists["maintenance_networks"])
Use this when scheduled work, private infrastructure, or known test targets should not generate an alert. Remove an entry when maintenance is complete to restore normal alerting without editing every rule.
Give critical RDAP changes extra attention¶
in_list(domain, lists["priority_domains"]) &&
current.rdap.nameservers != previous.rdap.nameservers
This lets one rule focus on a subset of high-value domains, even when your RDAP monitoring covers a much larger portfolio.
See the Alerting Model and module CEL references for the fields available in each type of event.
Managing entries¶
Enter one value per line in the list editor. Bulk entry updates are validated as a group: an invalid or duplicate value prevents the batch from being saved, so a list is never left partly updated.
List changes are included in the alert processor’s normal configuration refresh. Allow up to 60 seconds for an entry change to affect new events.
Limits¶
| Subscription tier | Lists | Entries per list |
|---|---|---|
| Free | 2 | 10 |
| Pro | 10 | 500 |
| Enterprise | 100 | 1,000 |
All lists count toward the list limit, including empty lists. If your subscription changes to a lower limit, existing lists remain available, but you cannot add lists or entries beyond the new limit until usage is reduced or the subscription is upgraded.
Permissions¶
| Permission | Allows |
|---|---|
view_lists |
View lists and use their names in the rule editor. |
manage_lists |
Create, update, and delete lists and entries. |
All organization users can view lists. Administrators and users who can create alert rules can manage them.
API reference¶
The Rule Lists API uses the same authenticated API token format as the rest of NOB.center. Replace nob_<your-token> and placeholder IDs in the examples below.
AUTH='Authorization: Bearer nob_<your-token>'
BASE='https://app.nob.center/api/lists'
All responses use a top-level success field. Read operations require lists:view_lists; write operations require lists:manage_lists.
List lists¶
GET /api/lists
Returns every list, including id, name, list_type, description, entry count, per-list entry limit, and timestamps. It does not include individual entries.
curl -H "$AUTH" "$BASE"
Get one list and its entries¶
GET /api/lists/{list_id}
curl -H "$AUTH" "$BASE/42"
The response includes an entries array. Each entry has an id, normalized value, and created_at timestamp.
Create a list¶
POST /api/lists
curl -X POST -H "$AUTH" -H 'Content-Type: application/json' \
-d '{
"name": "approved_origin_networks",
"list_type": "ip",
"description": "CDN and approved origin ranges",
"entries": ["192.0.2.0/24", "2001:db8:1234::/48"]
}' \
"$BASE"
list_type is either ip or domain. entries is optional and may be an empty array. The response includes the new id and current entry_limit.
Update a list description¶
PUT /api/lists/{list_id}
curl -X PUT -H "$AUTH" -H 'Content-Type: application/json' \
-d '{"description": "Approved public ingress ranges"}' \
"$BASE/42"
List names and types are intentionally not editable. Create a new list if you need a different type.
Add entries¶
POST /api/lists/{list_id}/entries
curl -X POST -H "$AUTH" -H 'Content-Type: application/json' \
-d '{"entries": ["198.51.100.0/24", "203.0.113.14"]}' \
"$BASE/42/entries"
The request adds all supplied entries or none. It rejects invalid values, duplicates, and changes that would exceed the per-list limit.
Replace all entries¶
PUT /api/lists/{list_id}/entries
curl -X PUT -H "$AUTH" -H 'Content-Type: application/json' \
-d '{"entries": ["login.example.com", "admin.example.com"]}' \
"$BASE/57/entries"
This replaces the complete entry set atomically. Send {"entries": []} to empty a list.
Delete one entry¶
DELETE /api/lists/{list_id}/entries/{entry_id}
curl -X DELETE -H "$AUTH" "$BASE/42/entries/314"
Delete a list¶
DELETE /api/lists/{list_id}
curl -X DELETE -H "$AUTH" "$BASE/42"
Deletion succeeds only when no alert rule references the list. Remove or update the dependent rules first.
Errors¶
| Status | Meaning |
|---|---|
400 |
Invalid list name, entry value, or unsupported computed CEL lookup. |
403 |
Missing permission or a list/entry quota would be exceeded. |
404 |
The requested list or entry does not exist. |
409 |
Duplicate list name/entry, or an attempt to delete a list still used by a rule. |