Network access control
NetworkPolicy
Network access-control policy. Set it config-wide (top-level network:, applies
to every interface as a baseline) and/or per-interface (interface.network:,
which inherits and tightens the config-wide policy).
Inheritance (tighten-only)
denylists (ip/geo/asn) union across levels — a config-level deny can never be weakened by an interface.allowlists intersect — the request must satisfy every level that declares an allow list.- An interface sets
inherit: falseto ignore the config-wide policy entirely (a deliberate public exception, e.g. a health route). - Scalar settings (
mode,source,trusted_proxies,on_deny) are taken from the interface when present, otherwise inherited from the config level.
Evaluation order (per level)
ip.deny → geo.deny → asn.deny → *.allow → rate_limit. The first rule
that rejects wins. In monitor mode nothing is blocked; matches are logged.
Example
network: # config-wide baseline
mode: enforce # enforce (default) | monitor
source: client # client (default) | socket | real_ip
trusted_proxies: # validate XFF chain (anti-spoofing)
- "10.0.0.0/8"
ip:
allow: ["203.0.113.0/24", "2001:db8::/32"]
deny: ["1.2.3.4"]
deny_check: source # source (default) | all
geo: { deny: ["RU", "KP"] }
asn: { deny: [13335] }
rate_limit: { per: ip, requests: 100, window: "60s" }
on_deny: { status: 403, body: { error: "forbidden" } }
interfaces:
admin:
network: # inherits + tightens the baseline
ip: { allow: ["198.51.100.10"] }
health:
network: { inherit: false } # public exception
| Field | Type | Description |
|---|---|---|
mode | NetworkMode (nullable) | enforce (default) blocks denied requests; monitor logs only. |
inherit | boolean (nullable) | Interface-level only: when false, ignore the config-wide policy for this interface. Defaults to true. Ignored at the config level. |
source | IpFilterSource (nullable) | Which captured IP to treat as authoritative. Defaults to client. |
trusted_proxies | Array<string> (nullable) | Trusted proxy CIDRs. When set, the client IP is resolved by walking the X-Forwarded-For chain from the right and skipping these hops, which defeats client-supplied header… |
ip | IpRule (nullable) | IP allow/deny rules. |
geo | GeoRule (nullable) | Country-level allow/deny rules (requires a GeoIP provider). |
asn | AsnRule (nullable) | ASN allow/deny rules (requires an ASN provider). |
rate_limit | RateLimitRule (nullable) | Per-source request rate limit. |
on_deny | DenyResponse (nullable) | Response to return when a request is denied in enforce mode. |
NetworkMode
Operating mode for a [NetworkPolicy]. Defaults to enforce.
One of:
- string — Block requests that fail any rule, returning the
on_denyresponse. Default. - string — Never block. Evaluate every rule and log what would have been blocked. Use this to validate a policy against live traffic before enforcing it (equivalent to a WAF…
IpRule
IP-based allow/deny rule. Single addresses or CIDR ranges; IPv4 and IPv6.
Within a single level, rules evaluate as: deny match → block;
else allow present and no match → block; else pass.
| Field | Type | Description |
|---|---|---|
allow | Array<string> (nullable) | Allowed IPs / CIDR ranges. If set, only matching requests pass (evaluated against the policy source IP). Across levels these intersect. |
deny | Array<string> (nullable) | Blocked IPs / CIDR ranges. Matching requests are denied. Across levels these union (a config-level deny always applies). deny_check controls scope. |
deny_check | DenyCheckMode (nullable) | Which IPs are checked against deny: source (default) checks only the resolved source IP; all checks every IP in the request chain. |
IpFilterSource
Which IP field from the incoming request is used as the authoritative source
when evaluating allow and deny rules in an [IpRule].
Defaults to client when not specified.
One of:
- string — Leftmost X-Forwarded-For entry (best-guess real client). Default.
- string — Raw TCP socket peer address (reliable when no proxy is involved).
- string — X-Real-IP header value, falling back to
clientif not present.
DenyCheckMode
Controls which IPs are checked against the deny list.
Defaults to source when not specified.
One of:
- string — Only check the configured
sourceIP against the deny list. Default. - string — Check deny rules against every IP in the full chain: client, socket, X-Real-IP, and all X-Forwarded-For hops. Useful for blocking known bad actors even when they route through…
GeoRule
Country-level (GeoIP) allow/deny rule. Requires a configured GeoIP provider. Country codes are ISO 3166-1 alpha-2 (e.g. "US", "GB"), case-insensitive.
| Field | Type | Description |
|---|---|---|
allow | Array<string> (nullable) | Allowed country codes. If set, only requests resolving to one of these pass. |
deny | Array<string> (nullable) | Denied country codes. Requests resolving to one of these are blocked. |
require_resolution | boolean (nullable) | When the country cannot be resolved: true blocks (fail-closed), false (default) skips the rule (fail-open). |
AsnRule
Autonomous System Number allow/deny rule. Requires a configured ASN provider.
| Field | Type | Description |
|---|---|---|
allow | Array<number> (nullable) | Allowed ASNs. If set, only requests resolving to one of these pass. |
deny | Array<number> (nullable) | Denied ASNs. Requests resolving to one of these are blocked. |
require_resolution | boolean (nullable) | When the ASN cannot be resolved: true blocks, false (default) skips. |
RateLimitRule
Per-identifier request rate limit using a sliding window.
| Field | Type | Description |
|---|---|---|
per | RateLimitScope (nullable) | What to bucket requests by. Defaults to ip. |
requests | number | Required. Maximum requests permitted per window. |
window | string (nullable) | Window length as a humantime string ("60s", "1m", "1h"). Defaults to "60s". |
burst | number (nullable) | Optional short-term burst allowance above requests. Reserved for the token-bucket backend; ignored by the sliding-window default. |
RateLimitScope
Identifier a [RateLimitRule] buckets requests by. Defaults to ip.
One of:
- string — Bucket by the policy's resolved
sourceIP address. Default.
DenyResponse
Response returned when a request is denied in enforce mode.
| Field | Type | Description |
|---|---|---|
status | number (nullable) | HTTP status code. Defaults to 403. Set to 404 to hide a route's existence. |
body | any | Response body. Defaults to {"error":"forbidden"}. |
headers | Map<string, string> (nullable) | Extra response headers to attach (e.g. Retry-After for rate limits). |