---
title: "Build first‑party durability with Cloudflare Workers"
id: "95747"
type: "solution"
slug: "build-first-party-durability-with-cloudflare-workers"
published_at: "2026-08-10T19:50:04+00:00"
modified_at: "2026-08-10T19:50:05+00:00"
url: "https://tealium.com/developer-center/build-first-party-durability-with-cloudflare-workers/"
markdown_url: "https://tealium.com/developer-center/build-first-party-durability-with-cloudflare-workers.md"
taxonomy_solutions_department:
  - "Data &amp; Analytics"
  - "IT"
taxonomy_solutions_usecase:
  - "Data Collection"
---

Data & Analytics

# Build first‑party durability with Cloudflare Workers

Caleb Jaquith

This post builds on [Part 1](https://tealium.com/developer-center/reduce-consent-fatigue-and-improve-compliance/)
, where we covered the design and reasoning behind a first-party reverse proxy for durable consent and identity. This post gets into implementation, with code to help you set up your own.

A fully functional POC is up on **calebjaquith.com** — the code in this post is from that implementation.

- Make Tealium traffic first-party **without needing changes to Tealium origins or CDN settings**.
- **Preserve consented state** by storing server-side copies of specific first-party cookies and restoring them only when appropriate — mitigating Safari’s first-party cookie limits and letting us reliably respect consent.
- **Centralize governance at the edge.** Decide which cookies persist, their attributes and lifetimes, and which vendor cookies to write, since the headers are now in your control.

## Review: architecture at a glance

As covered in Part 1, inside a reverse proxy on our main CDN (we used a Cloudflare Worker), we expose a small set of first-party paths that forward to Tealium services. The browser only sees the first-party domain, while the proxy dispatches to Tealium iQ, Tealium Collect, and Data Layer Enrichment (DLE) behind the scenes.

This creates one place to manage cookie persistence and similar edits — without needing to host new files — all while keeping a first-party footprint in the browser.

## What we did in this POC

### 1Made all Tealium calls first-party using a Cloudflare Worker

This solution results in first-party, working path support for:

- The full `tags.tiqcdn.com` Tealium CDN
- `collect.tealiumiq.com` Tealium Collection endpoints
- Tealium’s Data Layer Enrichment (DLE) feature (used by Collect)
- A simple cookie sync endpoint to enable step 2 to restore cookies in time
- And more

This helps with cosmetic concerns and CSP complexity, and thwarts some adblockers that look for our CDN (more on that in step 3). It’s easy to add additional paths as we add new services, and the origin doesn’t need to change anything at all — no certs to exchange, no First-Party Domains (FPD) to activate, no ops tickets to log.

As a bonus, avoiding a subdomain with this path-based system also ensures Safari (or any other browser) recognizes the domain as first-party and owned by the site owner. And the whole CDN is accessible — unlike with a typical FPD product — so files used by Adobe Launch and Google Tag Manager are available too, for example:

```
Example first-party pathshttps://calebjaquith.com/fwd-tealcdn/libs/tealiumjs/latest/tealium_collect.min.js
https://calebjaquith.com/fwd-tealcdn/shared/tms/t.tealium_collect.1_0_3.js
```

### 2Persist specific cookies longer than Safari ITP would generally allow

We added functionality to copy specific cookies into a server-side version — continually restored to the client — which isn’t impacted by ITP. The demo uses:

- `utag_main_v_id`
- `cc_cookie` (only visible if you make a decision on `calebjaquith.com?use_cmp=true`)

Each is persisted using the same name with `_copy` appended, to keep the connection clear — we have nothing to hide, since we’re circumventing ITP for the right reasons. That means we can persist opt-outs for Californians, a critical capability that Safari’s ITP otherwise takes away without this kind of server-side-cookie workaround.

We also added an endpoint to delete those cookies and their copies, since server-side cookies can otherwise only be removed by the user in Developer Tools.

Try it yourself

1. Visit [calebjaquith.com/?use_cmp=true](https://calebjaquith.com/?use_cmp=true) and make a consent decision when prompted.
2. Check **Application → Cookies** in DevTools. You’ll see `utag_main*` cookies including `utag_main_v_id` and a server-side-only `utag_main_v_id_copy`, plus `cc_cookie` and `cc_cookie_copy`.
3. Visit the deletion endpoint to remove specific cookies with a URL-encoded list: `/fwd-delete-cookies/?cookies=%5B%22utag_main_v_id%22%5D`. After this, `utag_main_v_id` and its copy are gone, but `cc_cookie` stays intact.
4. Call `/fwd-delete-cookies/` with no list to delete both cookies and their copies (an empty list is treated as no list).
5. Revisit the first page at any point to restore cookies and test other variants.

### 3Removed all instances of “utag” from file paths to thwart adblockers

Only make this change if you’re also rewriting the string back to `utag` in your reverse proxy. Tealium’s CDN only serves `utag.js` and `utag.N.js` files — this relies on the customer’s proxy renaming those strings in the path before forwarding to the CDN, or you’ll get page errors.

We wanted to thwart string matching for “utag” on the path, a method some adblockers use. It took a small utag config update to rewrite path strings, with the reverse rename happening on the CDN side:

```
utag_cfg_ovrdwindow.utag_cfg_ovrd = window.utag_cfg_ovrd || {};
window.utag_cfg_ovrd.utag_cdn_rewrite = 'lkjdf';
```

That override, with an updated utag template, means even extreme adblock lists that look for “tealium” or “utag” in paths won’t recognize and block our requests. It turns the utag.js request on calebjaquith.com from:

Before  
`https://calebjaquith.com/fwd-tealcdn/utag/services-caleb/personal-website/prod/utag.js`

After  
`https://calebjaquith.com/fwd-tealcdn/lkjdf/services-caleb/personal-website/prod/lkjdf.js`

…which is then transformed back by the Cloudflare Worker before it’s sent to the Tealium CDN. The browser never sees that the file is called `utag.js`, and the CDN only ever sees `utag` files, so it serves them as usual.

Two changes are needed. First, in the `utag.loader.AS` method, replace:

```
a.src = utag.cfg.path + ((typeof a.name != 'undefined') ? a.name : 'ut' + 'ag.' + a.id + '.js')
```

with:

```
a.src = utag.cfg.path.replaceAll('utag', (utag.cfg.utag_cdn_rewrite||'utag')) + ((typeof a.name != 'undefined') ? a.name : (utag.cfg.utag_cdn_rewrite || 'utag') + '.' + a.id + '.js')
```

to accommodate a different string in place of “utag” for subloaded tag files, set via `utag_cfg_ovrd` as described above.

Second, update the billing request. Replace:

```
v = utag.cfg.path;
 
if (b["cp.utag_main__ss"] == 1 && !utag.cfg.no_session_count) utag.ut.loader({ src: v + "ut" + "ag" + ".v.js?a=" + utag.cfg.utid + (utag.cfg.nocookie ? "&nocookie=1" : "&cb=" + (new Date).getTime()), id: "tiqapp" })
```

with:

```
Rewrite the billing call// CUSTOM - add support for rewriting the billing call
v = utag.cfg.path + "utag";
v = v.replaceAll('utag', (utag.cfg.utag_cdn_rewrite || 'utag'));
 
if (b["cp.utag_main__ss"] == 1 && !utag.cfg.no_session_count) utag.ut.loader({ src: v + ".v.js?a=" + utag.cfg.utid + (utag.cfg.nocookie ? "&nocookie=1" : "&cb=" + (new Date).getTime()), id: "tiqapp" })
```

### 4Removed the TAPID cookie

TAPID is used for cross-domain tracking, which isn’t useful in a first-party context, so we removed it. There’s a client-side flag we could have used instead, but doing it in the Worker was simpler — no other changes required.

## Putting it all together

Together, these choices give you a durable, first-party surface: consented state survives Safari inactivity windows via server-side copies, Tealium traffic stays reliably first-party through path-based forwarding, and cookie policy moves into one place you control at the edge.

You can roll this out incrementally — route iQ and Collect through your domain first, persist consent and a small set of IDs, then expand as your legal team allows.

No changes to Tealium origins, no certificate exchanges, and no ops tickets were required in our POC, because the Cloudflare Worker performs the forwarding and header work at the edge. The live demo on calebjaquith.com lets you dig into and test the approach end to end, including optional path rewriting to avoid list-based blocking, removal of TAPID where cross-domain linking isn’t needed, and a preview of CSP reporting — covered next in Part 3.

Caleb Jaquith

**Senior Product Manager**  
*Data Privacy Products / Visitor & Identity Platform*  
  
 I'm a Berlin-based American who joined Tealium in the summer of 2016, originally working on enterprise Tealium deployments as a (Lead) Implementation Engineer.   
  
 Since the fall of 2021, I've been the (Senior) Product Manager for Data Privacy Products at Tealium, working with the team to help our customers ensure data only flows where it's allowed to flow. In late 2024, I started working with the Visitor & Identity Platform team as well.   
  
 Say it "KAY-leb JAKE-with".

### Use Case

Data Collection

### Products
