YARP IP Filters

Policies

Policy modes, IP address and CIDR network matching

A policy is a named set of matching rules. Each policy has a Mode, a list of individual IPAddresses, and a list of CIDR IPNetworks. Policies are defined once and referenced by name — either from a route's metadata or as the global policy.

Policy Modes

The Mode decides how a match is interpreted.

ModeBehaviour
AllowListBlocks all requests except those whose IP matches an entry. Use for "only these clients may reach this route."
BlockListAllows all requests except those whose IP matches an entry. Use for "everyone except these known-bad clients."
DisabledFiltering is off. Every request passes through. Handy for temporarily switching a policy off without deleting it.

AllowList is the default when Mode is omitted.

A newly constructed IPFilterPolicy with no addresses or networks and the default AllowList mode blocks everything — an empty allowlist matches no one. This is a deliberate fail-closed default.

Matching individual addresses

List individual IPv4 or IPv6 addresses under IPAddresses:

{
  "PolicyName": "Admins",
  "Mode": "AllowList",
  "IPAddresses": ["203.0.113.7", "203.0.113.8", "2001:db8::1"]
}

Addresses are parsed once and held in a HashSet<IPAddress>, so lookups are O(1) regardless of list size.

Matching CIDR networks

List CIDR ranges under IPNetworks. Each entry is a prefix and a length separated by /:

{
  "PolicyName": "Intranet",
  "Mode": "AllowList",
  "IPNetworks": ["192.168.0.0/24", "10.0.0.0/8", "2001:db8::/32"]
}

Networks are stored in a trie (see IPNetworkCollection), so a client IP is matched against every configured range in a single bit-wise walk rather than one comparison per range.

Each network string must be exactly prefix/length. A malformed entry (missing or extra /) throws ArgumentException the first time the policy's networks are evaluated.

Combining addresses and networks

A single policy may declare both lists. A request matches the policy if its IP is in IPAddresses or falls within any entry in IPNetworks:

{
  "PolicyName": "Trusted",
  "Mode": "AllowList",
  "IPAddresses": ["203.0.113.7"],
  "IPNetworks": ["192.168.0.0/24"]
}

How that "match" translates to allow/block depends on the mode:

  • In AllowList mode, matching → allowed, everything else → blocked.
  • In BlockList mode, matching → blocked, everything else → allowed.

IPv4 and IPv6

The middleware normalises IPv4-mapped IPv6 addresses (e.g. ::ffff:192.168.0.1) back to their IPv4 form before matching, so a policy listing 192.168.0.1 matches a client that arrives over a dual-stack socket. List genuine IPv6 clients using their IPv6 address or network.

Lazy parsing

Address and network parsing is deferred until the first request evaluates a policy, and the parsed results are cached for the lifetime of that policy instance. When configuration reloads, the provider builds fresh policy instances, so the next request re-parses the updated values.