First-Party Cookie Restoration: ITP-Überleben mit Cloudflare Workers & ssGTM

Inhalt
- First-Party Cookie Restoration: ITP-Überleben mit Cloudflare Workers & ssGTM
- 1. Das Architektur-Konzept: Server-Managed Edge Cookies
- 2. Cookie-Wiederherstellung über Cloudflare Workers und ssGTM
- 3. Google Tag Gateway (GTG): Die perfekte Ergänzung an der Edge
- Zusammenfassung
- Variante: das eigene _ga-Cookie des Google-Tags verlängern
- Fragen und Antworten
- Quellen
First-Party Cookie Restoration: ITP-Überleben mit Cloudflare Workers & ssGTM
Safaris Intelligent Tracking Prevention (ITP) und moderne Browser-Privacy-Engines limitieren die Gültigkeitsdauer clientseitiger Cookies massiv. Identifikatoren, die per JavaScript (über document.cookie) gesetzt werden, erhalten eine maximale Lebensdauer von 7 Tagen – bei Erkennung von Ad-Click-Parametern im URL-String wird diese Laufzeit häufig auf 24 Stunden reduziert. Auch klassische CNAME-Cloaking-Verfahren werden von WebKit-Algorithmen erkannt und abgewertet, wenn der DNS-Eintrag auf bekannte Drittanbieter-Tracker verweist.
Um die Datenqualität und Attributionsgenauigkeit über längere Customer Journeys aufrechtzuerhalten, muss die Architektur von clientseitigem JavaScript auf echtes First-Party Edge Routing über serverseitig verwaltete HTTP-Cookies umgestellt werden.
1. Das Architektur-Konzept: Server-Managed Edge Cookies
Die Umgehung der 7-Tage-Limitierung erfordert es, Identifikatoren direkt am Netzwerkrand (Edge) per HTTP-Response-Header (Set-Cookie) zu generieren. Da Browser-Restriktionen strikt zwischen Skript-Cookies und legitimen Server-Session-Headern unterscheiden, können Edge-generierte Cookies bis zu 365 Tage bestehen bleiben, sofern eine gültige datenschutzrechtliche Zustimmung vorliegt und die Antwort von der eigenen Infrastruktur der Website kommt: Wird der antwortende Host über einen CNAME oder eine IP-Adresse eines Drittanbieters erreicht, begrenzt WebKit auch per HTTP-Antwort gesetzte Cookies auf 7 Tage.
| Cookie-Attribut | Erforderlicher Wert | Technische Begründung |
|---|---|---|
HttpOnly | true | Verhindert JavaScript-Zugriff und immunisiert das Cookie gegen ITP-Skript-Limits sowie XSS-Diebstahl. |
Secure | true | Erzwingt eine verschlüsselte HTTPS-Übertragung für alle Endpunkte. |
SameSite | Lax / Strict | Stellt sicher, dass das Cookie als nativer First-Party-Kontext verarbeitet wird. |
Domain | Apex Domain (z. B. example.com) | Verhindert CNAME-Mismatch-Strafen zwischen Subdomains. |
2. Cookie-Wiederherstellung über Cloudflare Workers und ssGTM
Eine robuste Wiederherstellungs-Pipeline nutzt Cloudflare Workers als Reverse Proxy vor einem Server-Side Google Tag Manager (ssGTM) Container. Wird ein HTTP-Request an der Edge abgefangen, prüft der Worker, ob ein gültiger Server-Managed-Identifikator existiert. Fehlt dieser, injiziert der Worker einen neuen Set-Cookie-Header in die Response.
// Cloudflare Worker Edge Script: Server-Managed Identifier Restoration
function getCookieValue(cookieHeader, name) {
if (!cookieHeader) return null;
for (const part of cookieHeader.split("; ")) {
const eq = part.indexOf("=");
if (eq !== -1 && part.slice(0, eq) === name) return part.slice(eq + 1);
}
return null;
}
export default {
async fetch(request, env) {
const response = await fetch(request);
const newResponse = new Response(response.body, response);
// Anonymen First-Party-Identifikator auslesen oder erzeugen
let fpId = getCookieValue(request.headers.get("Cookie"), "fp_id");
if (!fpId) {
fpId = crypto.randomUUID();
// Set-Cookie-Header mit 1 Jahr Laufzeit nur bei fehlendem Identifikator setzen
newResponse.headers.append(
"Set-Cookie",
`fp_id=${fpId}; Max-Age=31536000; Path=/; Domain=example.com; Secure; HttpOnly; SameSite=Lax`
);
}
return newResponse;
}
};
Im ssGTM wird dieser persistente Edge-Identifikator mit dem Standard-Client-ID-Feld von GA4 oder Google Ads gemappt, wodurch Multi-Touch-Attributionsmodelle auch bei langen Konversionszyklen konsistente Daten liefern.
3. Google Tag Gateway (GTG): Die perfekte Ergänzung an der Edge
Das Google Tag Gateway (GTG) stellt einen spezialisierten First-Party-Routing-Mechanismus dar, der Analytics-Traffic direkt über die Hauptdomain leitet. Die Bereitstellung des GTG über Cloudflare Workers erzeugt eine perfekte Synergie mit der Cookie-Wiederherstellung:
- Same-Origin-Kontext: Das GTG routet Skript-Bibliotheken (z. B.
/gtg/gtm.js) und Daten-Payloads (/gtg/collect) über exakt dieselbe IP-Adresse und Autonomous System Number (ASN) wie die eigentliche Website. - Immunität gegen CNAME-Abwehr: Da das GTG direkt auf der Infrastruktur der Hauptdomain via Edge-Proxying läuft statt über externe DNS-Delegationen, stufen WebKit-Tracking-Filter den Traffic als reguläre Backend-Kommunikation ein.
- Keine eigene Tracking-Verbindung: Da GTG-Routing und Cookie-Wiederherstellung im selben Cloudflare-Worker unter dem Hostnamen der Website laufen, kann der Browser seine bestehende Verbindung weiterverwenden und braucht keinen eigenen TLS-Handshake zu einer separaten Tracking-Domain; die Weiterleitung des Workers an den Server-Container bleibt ein zusätzlicher Netzwerkschritt.
Zusammenfassung
Die Überwindung von ITP-Restriktionen erfordert die Verlagerung des Identifikator-Managements von Browser-Skripten auf Edge-Infrastrukturen. Die Kombination aus serverseitigen HttpOnly-Cookies via Cloudflare Workers und dem Same-Origin-Routing des Google Tag Gateways (GTG) etabliert eine rechtskonforme, datenschutzfreundliche und technisch absolut hochverfügbare Tracking-Architektur.
Variante: das eigene _ga-Cookie des Google-Tags verlängern
Der Worker oben legt eine eigene Kennung an, fp_id, die im Server-Container auf die Client-ID gemappt wird. Eine schmalere Variante überlässt die Kennung dem Google-Tag und erneuert nur das vorhandene _ga-Cookie per HTTP-Response, etwa über einen eigenen Endpunkt auf demselben Hostnamen. Ob das funktioniert, hängt an vier Details.
- Kein
HttpOnlybei_ga: Das Google-Tag liest die Client-ID per JavaScript, und einHttpOnly-Cookie ist überdocument.cookienicht zugänglich. Die Attributtabelle oben gilt für eine eigene Server-Kennung, nicht für_ga. - Passende
Domain: Ein neues Cookie ersetzt ein vorhandenes nur, wenn Name, Domain und Pfad übereinstimmen. Mitcookie_domain: 'auto'schreibt das Google-Tag seine Cookies auf die höchstmögliche Domain, bei www.example.com also auf example.com. Ein Worker, der_gamitDomain=www.example.comschreibt, legt ein zweites Cookie an, statt das erste zu verlängern. cookie_update: falseim Google-Tag: Mit dem Standardwerttruedarf das Tag seine Cookies bei jedem Seitenaufruf aktualisieren und die Laufzeit ab dem letzten Besuch neu setzen, in Safari also wieder als Skript-Cookie. Mitfalsewerden die Cookies nicht bei jedem Seitenaufruf aktualisiert.- Verlängern, nie erzeugen: Kommt die Anfrage ohne
_ga, antwortet der Endpunkt ohneSet-Cookie. Andernfalls vergeben beim ersten Besuch Worker und Tag je eine ID, und aus einem Besucher können zwei Nutzer werden.
Google gibt für _ga eine Standardlaufzeit von zwei Jahren an, das entspricht Max-Age=63072000. Chrome begrenzt die Laufzeit von Cookies seit Version 104 (August 2022) auf 400 Tage: Längere Werte werden nicht abgewiesen, sondern auf 400 Tage gekürzt, und jede Erneuerung bei einem späteren Besuch startet die Frist neu.
Der Weg über einen Response-Header ändert nichts an der Einwilligungspflicht. Artikel 5 Absatz 3 der ePrivacy-Richtlinie erfasst das Speichern von und den Zugriff auf Informationen im Endgerät unabhängig von der Technik; der Aufruf des Verlängerungs-Endpunkts gehört deshalb hinter ein erteiltes analytics_storage.
Fragen und Antworten
Sollte der Worker das Cookie bei jeder Antwort schreiben oder nur dort, wo die Kennung fehlt, wenn Seiten am Edge gecacht werden?
Nur dort, wo sie fehlt oder bald abläuft. Der Ausschnitt im Artikel zeigt den Mechanismus, nicht die Platzierung, und die Platzierung entscheidet, ob die Website cachebar bleibt.
Eine Antwort mit Set-Cookie sollte nicht in einem gemeinsamen Cache landen, und viele gemeinsame Caches lehnen das Speichern einer solchen Antwort standardmäßig ab. Das ist eine Korrektheitsregel, keine Stellschraube, denn eine gecachte Kopie würde die Kennung eines Besuchers an den nächsten weitergeben. Je nachdem, an welcher Stelle der Kette der Header hinzukommt, kann er an jeder HTML-Antwort deshalb das Edge-Caching für die ganze Website abschalten, und diese Kosten übersteigen alles, was die Messung gewinnt.
Zwei Anpassungen erhalten beides. Der Header wird nur auf dem Pfad geschrieben, der ohnehin persönlich sein muss — dem Analytics-Endpunkt, den das Tag aufruft, nicht der Seite —, und nur dann, wenn das Cookie fehlt oder in seinem Erneuerungsfenster liegt. Was im Container ankommt, bleibt unverändert, weil die Kennung so oder so mit der Anfrage mitreist. Der Cache-Status-Header einer Seitenantwort zeigt den aktuellen Stand: Steht dort bei jeder Anfrage ein Miss, ist das bedingungslos geschriebene Cookie der erste Verdächtige.
Wie wird ein HttpOnly-Cookie wie fp_id mit einem Jahr Laufzeit wieder entfernt, wenn die Einwilligung widerrufen wird?
Über denselben Weg, auf dem es entstanden ist: Was der Server setzt, muss der Server auch zurücknehmen. Das ist die Pflicht, die diese Architektur mitbringt, und sie fehlt in vielen Beschreibungen.
Praktisch ist es ein zweiter Pfad am selben Worker, der das Cookie mit Max-Age=0 überschreibt, aufgerufen aus dem Widerrufspfad des Einwilligungswerkzeugs. Ohne diesen Pfad bleibt die Kennung ein Jahr bestehen, obwohl ihre Grundlage entfallen ist, und es gibt auch keinen Beleg dafür, dass sie entfernt wurde. Ebenso wichtig ist der Setzpfad: Der Worker im Artikel schreibt das Cookie, sobald es fehlt. Prüft er dort die Einwilligung nicht, legt schon der nächste Aufruf nach dem Löschen eine neue Kennung an.
Ein Detail entscheidet dabei über Erfolg oder Schein: Das Lösch-Cookie muss denselben Namen, dieselbe Domain und denselben Pfad tragen wie das ursprüngliche, im Beispiel also Domain=example.com und Path=/. Weichen Domain oder Pfad ab, läuft die Anweisung ins Leere, und das alte Cookie bleibt bestehen. Die Antwort des Workers sieht trotzdem korrekt aus, weil der Set-Cookie-Header vorhanden ist; erst der Blick auf die tatsächlich gespeicherten Cookies zeigt, dass fp_id noch da ist.
Macht ein Cookie auf der Hauptdomain, das mit jeder Anfrage mitgeschickt wird, auch für statische Ressourcen, das Caching im CDN kaputt?
Ja, wenn der Cache-Schlüssel Cookies berücksichtigt, und viele Konfigurationen tun das standardmäßig, um die Inhalte eines angemeldeten Nutzers nicht an jemand anderen auszuliefern.
Der Effekt ist still und teuer: Jeder Besucher hat einen anderen Wert der Kennung, also bekommt jeder eine eigene Kopie im Cache. Die Trefferquote fällt fast auf null, die Last auf dem Ursprungsserver steigt, und die Website wird langsamer, ohne eine einzige Fehlermeldung.
Die Lösung besteht darin, genau dieses Cookie aus dem Cache-Schlüssel auszunehmen; bei den meisten Anbietern ist das ein einzelnes Feld in der Konfiguration. Das geschieht am besten bewusst und schriftlich festgehalten, denn die Regel sieht gefährlich aus („Cookie ignorieren“), ist aber tatsächlich sicher: Eine Analytics-Kennung ändert den Seiteninhalt nicht, also gibt es keinen Grund, den Cache in so viele Teile zu zerlegen, wie es Besucher gibt.
Quellen
- Full Third-Party Cookie Blocking (WebKit)
- Tracking Prevention in WebKit: CNAME and third-party IP address cloaking defense
- Cloudflare Workers documentation
- Google Analytics: Cookie-Nutzung auf Websites
- Google tag: Customize cookies
- Chrome for Developers: Cookie Expires and Max-Age attributes now have upper limit
- MDN: Set-Cookie
- RFC 6265: HTTP State Management Mechanism, Section 5.3
- Richtlinie 2002/58/EG (Datenschutzrichtlinie für elektronische Kommunikation)