crates/trusted-server-adapter-cloudflare/src/platform.rs sets region: None unconditionally when it builds GeoInfo, and build_geo reads no region header at all.
The consequence, traced rather than assumed
detect_jurisdiction in consent/jurisdiction.rs reaches its US branch only when the country is US and a region is present. With no region the guard fails and the request falls through to the non-regulated jurisdiction.
In allows_ec_creation, the non-regulated arm returns true outright and never reads the privacy signal. The US state arm is the one that reads Global Privacy Control first and returns false, then checks the GPP US sale opt-out and the US Privacy string.
So on Cloudflare a visitor in a US privacy state had an Edge Cookie created regardless of their signal. All three signals failed open, not only Global Privacy Control, because the GPP sale opt-out and the US Privacy opt-out are consulted on that same arm.
How it is fixed in this stack
PR #1044, the device
and geo provider selection PR, reads the region from cf-region-code as a
request header, the same way the adapter already reads cf-ipcountry and
cf-ipcity.
One detail matters and is easy to get wrong. cf-region is the subdivision name, for example California, while [consent.us_states] privacy_states holds two-letter codes. Using cf-region would look like a fix and match nothing. cf-region-code carries the ISO 3166-2 code, for example CA. Like the other location headers it requires the Enterprise visitor-location managed transform, which the doc comment now says.
The test asserts the header reaches GeoInfo.region, and that jurisdiction detection returns the US state with it and non-regulated without it. Restoring region: None fails it.
Produced with AI assistance and needs human review. Verified against upstream/main.
crates/trusted-server-adapter-cloudflare/src/platform.rssetsregion: Noneunconditionally when it buildsGeoInfo, andbuild_georeads no region header at all.The consequence, traced rather than assumed
detect_jurisdictioninconsent/jurisdiction.rsreaches its US branch only when the country isUSand a region is present. With no region the guard fails and the request falls through to the non-regulated jurisdiction.In
allows_ec_creation, the non-regulated arm returnstrueoutright and never reads the privacy signal. The US state arm is the one that reads Global Privacy Control first and returns false, then checks the GPP US sale opt-out and the US Privacy string.So on Cloudflare a visitor in a US privacy state had an Edge Cookie created regardless of their signal. All three signals failed open, not only Global Privacy Control, because the GPP sale opt-out and the US Privacy opt-out are consulted on that same arm.
How it is fixed in this stack
PR #1044, the device
and geo provider selection PR, reads the region from
cf-region-codeas arequest header, the same way the adapter already reads
cf-ipcountryandcf-ipcity.One detail matters and is easy to get wrong.
cf-regionis the subdivision name, for exampleCalifornia, while[consent.us_states] privacy_statesholds two-letter codes. Usingcf-regionwould look like a fix and match nothing.cf-region-codecarries the ISO 3166-2 code, for exampleCA. Like the other location headers it requires the Enterprise visitor-location managed transform, which the doc comment now says.The test asserts the header reaches
GeoInfo.region, and that jurisdiction detection returns the US state with it and non-regulated without it. Restoringregion: Nonefails it.Produced with AI assistance and needs human review. Verified against
upstream/main.