@gfargo/doorman 3.15.0 → 3.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gfargo/doorman",
3
- "version": "3.15.0",
3
+ "version": "3.15.1",
4
4
  "description": "Manage firewall rules as code across multiple providers",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -58,25 +58,26 @@ Doorman translates its unified rule format (`conditions`/`enabled`/`action: {typ
58
58
 
59
59
  ### Field Mapping
60
60
 
61
- Cloudflare supports all 15 unified condition fields:
62
-
63
- | Doorman Field | Cloudflare Field | Notes |
64
- | ------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
65
- | `ip` | `ip.src` | |
66
- | `country` | `ip.geoip.country` | |
67
- | `region` | `ip.geoip.subdivision_1` | |
68
- | `city` | `ip.geoip.city` | |
69
- | `asn` | `ip.geoip.asnum` | |
70
- | `path` | `http.request.uri.path` | |
71
- | `host` | `http.host` | |
72
- | `method` | `http.request.method` | |
73
- | `header` | `http.request.headers["key"]` | Requires `key` (the header name) |
74
- | `query` | `http.request.uri.query` | ⚠️ `key` is currently ignored — matches the whole query string, not one parameter ([doorman#263](https://github.com/gfargo/doorman/issues/263)) |
75
- | `cookie` | `http.cookie["key"]` | Requires `key` (the cookie name) |
76
- | `user_agent` | `http.user_agent` | |
77
- | `referer` | `http.referer` | |
78
- | `scheme` | `ssl` (boolean) | |
79
- | `port` | `cf.edge.server_port` | |
61
+ Cloudflare supports all 16 unified condition fields:
62
+
63
+ | Doorman Field | Cloudflare Field | Notes |
64
+ | -------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
65
+ | `ip` | `ip.src` | |
66
+ | `country` | `ip.geoip.country` | |
67
+ | `region` | `ip.geoip.subdivision_1` | Client geo subdivision (e.g. `"CA"`) — see the legacy-field note below for how this differs from Vercel's own `region` |
68
+ | `city` | `ip.geoip.city` | |
69
+ | `asn` | `ip.geoip.asnum` | |
70
+ | `path` | `http.request.uri.path` | |
71
+ | `host` | `http.host` | |
72
+ | `method` | `http.request.method` | |
73
+ | `header` | `http.request.headers["key"]` | Requires `key` (the header name) |
74
+ | `query` | `http.request.uri.query` | ⚠️ `key` is currently ignored — matches the whole query string, not one parameter ([doorman#263](https://github.com/gfargo/doorman/issues/263)) |
75
+ | `cookie` | `http.cookie["key"]` | Requires `key` (the cookie name) |
76
+ | `user_agent` | `http.user_agent` | |
77
+ | `referer` | `http.referer` | |
78
+ | `scheme` | `ssl` (boolean) | |
79
+ | `port` | `cf.edge.server_port` | |
80
+ | `threat_score` | `cf.threat_score` | Cloudflare bot/attack threat score (0-100) |
80
81
 
81
82
  ### Operator Mapping
82
83
 
@@ -112,7 +113,10 @@ Without `CLOUDFLARE_ACCOUNT_ID`, IP blocking falls back to individual WAF rules
112
113
 
113
114
  ## Limitations & Differences
114
115
 
115
- `environment`, `ja3_digest`, `ja4_digest` are **legacy-format-only concepts** — they exist on Vercel's native rule type but have no unified-format equivalent at all, so they're not reachable through a `provider`/`providers`-tagged config for _any_ provider, not just Cloudflare. Every other unified field maps to something on Cloudflare — see Field Mapping above.
116
+ `protocol`, `target_path`, `environment`, `geo_continent`, `ja3_digest`, `ja4_digest`, `rate_limit_api_id` are **Vercel-native-only concepts** with no Cloudflare equivalent. Unlike what this doc previously claimed, they _are_ reachable through a `provider`/`providers`-tagged config — `UnifiedCondition.field` accepts arbitrary strings, and a Vercel rule using any of them translates straight through into the unified layer unchanged. Cloudflare's translator drops each one from the generated expression with a `TranslationWarning` rather than emitting invalid wirefilter ([doorman#271](https://github.com/gfargo/doorman/issues/271)); if _every_ condition on a rule falls into this set, translation throws rather than syncing a conditionless (match-everything) rule. Two related fields are handled specially, not dropped:
117
+
118
+ - Vercel's own `region` (the edge/deployment location a request was served from, e.g. `"sfo1"`) is namespaced internally to `vercel_region` so it can't collide with the unified `region` field in the table above (client geo subdivision) — before [doorman#270](https://github.com/gfargo/doorman/issues/270) the two silently shared one name, so a Vercel edge-region condition became a Cloudflare `ip.geoip.subdivision_1` check that could never match. `vercel_region` itself is still Cloudflare-unsupported and gets dropped-with-warning like the rest of this list.
119
+ - Vercel's `geo_country_region` ("Region/state code", e.g. `"CA"`) _is_ the same concept as the unified `region` field — it maps there directly and translates to `ip.geoip.subdivision_1` normally, unlike the rest of this list.
116
120
 
117
121
  | Feature | Cloudflare | Notes |
118
122
  | ------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------- |
@@ -73,30 +73,33 @@ Each condition has:
73
73
 
74
74
  ### Condition Types
75
75
 
76
- | Type | Description | Example Value |
77
- | -------------------- | -------------------------------- | ----------------------- |
78
- | `path` | URL path | `"/api/users"` |
79
- | `method` | HTTP method | `"POST"` |
80
- | `host` | Hostname | `"example.com"` |
81
- | `user_agent` | User-Agent header | `"Googlebot"` |
82
- | `ip_address` | Client IP | `"192.168.1.1"` |
83
- | `header` | HTTP header (requires `key`) | `"application/json"` |
84
- | `query` | Query parameter (requires `key`) | `"true"` |
85
- | `cookie` | Cookie value (requires `key`) | `"session_abc"` |
86
- | `geo_country` | Country code (ISO 3166-1) | `"US"` or `["US","CA"]` |
87
- | `geo_city` | City name | `"New York"` |
88
- | `geo_continent` | Continent code | `"NA"` |
89
- | `geo_country_region` | Region/state code | `"CA"` |
90
- | `geo_as_number` | ASN number | `13335` |
91
- | `scheme` | URL scheme | `"https"` |
92
- | `protocol` | HTTP protocol version | `"HTTP/2"` |
93
-
94
- **Vercel-only types** (not available on Cloudflare):
95
-
76
+ These translate cleanly to the unified format's condition fields (`mapVercelTypeToUnified` in `src/lib/providers/vercel/translator.ts`), so a rule built from them survives migration to Cloudflare or Fastly:
77
+
78
+ | Type | Description | Example Value |
79
+ | --------------- | -------------------------------- | ----------------------- |
80
+ | `path` | URL path | `"/api/users"` |
81
+ | `method` | HTTP method | `"POST"` |
82
+ | `host` | Hostname | `"example.com"` |
83
+ | `user_agent` | User-Agent header | `"Googlebot"` |
84
+ | `ip_address` | Client IP | `"192.168.1.1"` |
85
+ | `header` | HTTP header (requires `key`) | `"application/json"` |
86
+ | `query` | Query parameter (requires `key`) | `"true"` |
87
+ | `cookie` | Cookie value (requires `key`) | `"session_abc"` |
88
+ | `geo_country` | Country code (ISO 3166-1) | `"US"` or `["US","CA"]` |
89
+ | `geo_city` | City name | `"New York"` |
90
+ | `geo_as_number` | ASN number | `13335` |
91
+ | `scheme` | URL scheme | `"https"` |
92
+
93
+ **Vercel-only types** — these round-trip fine between the legacy shape and the unified format (Vercel stays Vercel), but have no _other_ provider's equivalent: migrating to Fastly drops them with a translation warning, while migrating to Cloudflare currently produces a broken filter expression with no warning at all (`mapUnifiedFieldToCloudflare` in `src/lib/translators/ExpressionBuilder.ts` has no entry for them and falls through to the bare field name, which isn't valid Wirefilter syntax) — avoid these in a rule you intend to sync to Cloudflare:
94
+
95
+ - `geo_continent` — continent code (`"NA"`)
96
+ - `geo_country_region` — region/state code (`"CA"`) — distinct from `region` below, not interchangeable
97
+ - `protocol` — HTTP protocol version (`"HTTP/2"`) — distinct from `scheme` above, not interchangeable
98
+ - `target_path` — URL path, alternate to `path` (no unified mapping despite the similar name)
99
+ - `region` — Vercel edge region (e.g. `"sfo1"`)
96
100
  - `environment` — deployment environment (`"production"`, `"preview"`)
97
101
  - `ja3_digest` — TLS fingerprint
98
102
  - `ja4_digest` — TLS fingerprint v4
99
- - `region` — Vercel edge region
100
103
  - `rate_limit_api_id` — rate limit API identifier
101
104
 
102
105
  ### Operators