How Do I Configure Cloudflare To Proxy Both My Website And My SGTM Domain?
The question we’re going to be looking at today is inspired by our course, Server-side Tagging In Google Tag Manager.
The WebKit browser engine, running Safari and iOS/iPadOS browser apps, has a tracking prevention mechanism called CNAME Cloaking defense.
When a website communicates with another site, the WebKit browser checks the DNS records of both sites. If the DNS records point to significantly different addresses (either canonical names or IP address subnets), WebKit restricts the lifetime of cookies set in the HTTP response from the second site to a maximum of 7 days.
This means that deploying a service like server-side Google Tag Manager in Google Cloud Platform, for example, will no longer guarantee an extended lifetime for first-party cookies set through the service.
In this article, I’ll share with you a workaround for how to help WebKit consider the website and the service to be first-party to each other.
Huge thanks to Vladyslav Iukhnovych for working with me on this one in the Simmer Community.
If you prefer this walkthrough in video format, you can check out the video below.
Don’t forget to subscribe to the Simmer YouTube channel for more content like this.
When are server-set cookies restricted?
You can use the Online Dig tool to check the DNS records for any given domain.
For example, let’s say you are browsing a website like www.site.example. Let’s say you manage its DNS records through Cloudflare, because you want to make use of Cloudflare’s super fast edge caching capabilities to improve the performance of your website.
In this case, the DNS records of this domain would point to Cloudflare’s network, for example to something like 188.114.X.X.
On this site, you are running requests through server-side Google Tag Manager. One of the use cases for deploying server-side GTM is to rewrite the site’s first-party cookies through HTTP responses to ensure a longer lifetime for them.
You’ve deployed server-side GTM in the Google Cloud Platform, and you’ve mapped the custom domain sst.site.example to GCP’s servers. Thus, the subdomain resolves to a bunch of IP addresses all within the 216.239.X.X subnet.
In this case, WebKit would actually consider sst.example.com to be “third-party” to site.example.com, even though they are subdomains of the same naked domain.
Why? Because the IP address subnets that cover the first half of the address (the first two octets) are different.
Any cookies you try to set in the HTTP response from sst.example.com would be restricted to a maximum lifetime of 7 days, even though technically they are first-party cookies.
Make the IP address subnets match
To force WebKit to grant longer expiration times for the cookies set in the HTTP response from sst.example.com, you have to somehow make site.example.com and sst.example.com both resolve to the same IP address subnet.
In this article, I’ll share with you how to do this using Cloudflare. The main caveat is that you need to delegate your server-side GTM DNS records to Cloudflare first, because that’s the only way you can setup the proxy.
If you’re already pointing the main website’s DNS records to Cloudflare’s name servers, you’re probably hosting your server-side GTM DNS records in Cloudflare, too.
To route the server-side GTM DNS traffic through Cloudflare’s proxy (instead of just hosting the DNS records), you need to go to the DNS -> Records configuration in the Cloudflare dashboard, search for all the A/AAAA records for your server-side GTM subdomain name, and edit each to toggle Proxy status to Proxied.
Once you’ve done this, the list of 8 records for Google Cloud Platform should look like this:
Finally, visit the Dig tool again to make sure that the subnet range for your subdomain now matches that of the main domain:
Remember that just the first half of the IP address needs to match between the two domains.
Bypass cache for the SGTM subdomain
In the case of server-side Google Tag Manager, it’s important that Cloudflare doesn’t cache the responses, which it defaults to when you proxy traffic through the service.
There are certain processes within Google Tag Manager, especially in Preview mode, which can break if the responses from the service are cached.
To prevent Cloudflare from caching SGTM responses, you need to go to Caching -> Cache Rules in the Cloudflare admin view to create a new bypass cache rule for your server-side GTM subdomain like this:
Once you’ve done all this, your setup should be ready. Remember to test carefully to make sure nothing is broken. Working with DNS records is always a bit tricky, so if you’re overwhelmed make sure you have someone from your DevOps team to help you out.
I’m always torn when writing articles like this.
I genuinely do not believe it’s worth the time and effort to always jump through hoops to make services like server-side Google Tag Manager resilient to browsers’ tracking preventions.
Relying on first-party cookies for identity persistence has been a bad idea for a long, long time, even before the dreaded ITP 2.1 came and took our cookie lifetimes away.
That being said, if you’re already hosting your DNS in Cloudflare, setting up this proxy is very easy, and there might even be additional benefits to doing so.
Cloudflare has an impressive toolkit of things like Workers, Firewalls, and Bot Management that could help make your proxied services even more reliable.
Toggling the DNS settings from DNS Only to Proxied is such a simple yet powerful move. It’s much more elegant than building your own reverse proxy on the edge, for example, especially since reverse proxies would have a hard time forwarding cookie headers among other things.
In summary: give this solution a try, but don’t spend an enormous amount of time and resources to migrate your entire domain architecture to Cloudflare just for the sake of getting first-party cookie lifetimes back for a while.
It seems pretty likely that WebKit is moving towards an end-game state where all first-party storage is restricted in expiration unless the user opts in to allow for longer storage. In this case, there’s nothing you would be able to do with service configuration.