Skip to content

Edge Cookies (EC)

Trusted Server persists a stable per-device identifier in a first-party cookie on the publisher's domain. The cookie name is ts-ec. Trusted Server also surfaces the current EC ID on the x-ts-ec response header, and strips that header when the consent evaluation does not permit EC use.

Policy Posture

Trusted Server is technology. It is neutral on policy. The Edge Cookie gives the deployer a cookie slot and configuration over the surrounding attributes. The deployer determines the policy posture based on the laws and contractual arrangements that apply to their deployment. Privacy outcomes follow from that configuration, not from the cookie mechanism itself.

For full operational onboarding (partner configuration, batch sync, identify, and auction verification), use the EC Setup Guide.

How They Work

EC IDs are generated on first request using HMAC-SHA256 over the normalized client IP and a configured secret, with a short random suffix appended. On subsequent requests the value is read from the ts-ec cookie and reused.

Format: 64-hex-hmac.6-alphanumeric-suffix

IP normalization: IPv4 addresses pass through unchanged. IPv6 addresses are masked to the /64 prefix before hashing, so a device that rotates its interface identifier under Privacy Extensions still maps to a stable base.

Determinism and Stability

ScenarioResult
Same client IP, same secret, no cookieSame 64-hex base; fresh suffix each mint.
Same client IP, same secret, existing cookieExisting cookie value reused; no fresh mint.
Same client IP, different secretDifferent 64-hex base. Useful for rotating identity.
Multiple clients behind shared NAT, same secret, no cookiesSame 64-hex base; the suffix distinguishes them.

Request Lifecycle

Every request passes through four phases. EC generation only happens on organic routes (publisher proxy, integration proxy, auction) — read-only endpoints like /identify and /batch-sync skip generation entirely. During pre-routing, Trusted Server builds consent from request-local cookies, headers, geolocation, and policy defaults; it does not load consent from a separate KV store.

Response Finalization

After routing completes, the server evaluates consent state and cookie presence to decide what to do with the EC cookie on the response.

When consent cannot be verified for the current request — for example, unknown jurisdiction or missing/undecodable consent signals in a regulated region — Trusted Server fails closed for EC use by stripping EC headers, but it does not treat that as authoritative revocation of an already-issued EC.

EC creation is gated by jurisdiction. The server detects jurisdiction from geolocation data attached to the request and applies the corresponding consent rules. Live consent comes from request-local signals (euconsent-v2, __gpp, __gpp_sid, us_privacy, Sec-GPC) plus geolocation and policy defaults; there is no separate consent KV fallback.

  • GDPR: Opt-in required. TCF Purpose 1 (store/access device) must be explicitly consented.
  • US State: Opt-out model with three-tier fallback — GPC always blocks, then TCF if a CMP uses it, then US Privacy string, then fail-closed.
  • Non-regulated: EC always allowed.
  • Unknown: Fail-closed when jurisdiction cannot be determined.

The ec_identity_store KV store is the only EC lifecycle store. It holds identity graph state, source-domain keyed partner UIDs, a minimal consent snapshot used for EC entry metadata, and withdrawal tombstones. Consent interpretation for each request remains based on the live request signals listed above.

Partner Sync Channels

Partner identities flow into the KV identity graph through three channels. Each writes to the same ids map in the KV entry via idempotent upsert logic: unchanged UIDs are accepted without a KV write, while different UIDs replace the stored value.

The ts-eids cookie bridges client-side Prebid user ID modules with the server-side identity graph.

Current TSJS writers preserve the full OpenRTB-style {source, uids:[...]} shape in ts-eids. The server remains backward-compatible with earlier flattened {source, id, atype} cookies during rollout, but new cookies use the structured uids[] form.

The sharedId cookie follows a similar path but is written directly by Prebid's SharedID module rather than by TSJS. The server reads it separately and maps it via the sharedid.org source domain.

EID Seeding and Prebid Bidstream Forwarding

EIDs can reach the EC identity graph from either server-side pull sync or browser-side Prebid sync. During a Prebid-routed auction, Trusted Server combines those stored IDs with any same-request EIDs from Prebid.js, applies consent gating, and forwards the merged set to Prebid Server as OpenRTB user.ext.eids. Prebid Server then passes those EIDs downstream to demand partners in its OpenRTB requests.

The relevant OpenRTB structure forwarded to Prebid Server and downstream partners is:

json
{
  "user": {
    "id": "<ec-id-when-forwarding-is-allowed>",
    "ext": {
      "eids": [
        {
          "source": "id5-sync.com",
          "uids": [
            {
              "id": "ID5-abc123",
              "atype": 1
            }
          ]
        },
        {
          "source": "liveramp.com",
          "uids": [
            {
              "id": "LR-xyz789",
              "atype": 3,
              "ext": {
                "rtiPartner": "idl"
              }
            }
          ]
        }
      ]
    }
  }
}

Server-resolved EIDs and current-request Prebid EIDs are deduplicated by source + uid.id. When a partner UID already exists in KV, pull sync does not periodically refresh it; browser-side Prebid sync can still replace the stored UID if a later ts-eids cookie carries a different value for the same configured partner source.

Configuration

Configure EC settings in the [ec] section of trusted-server.toml. See the Configuration Reference for the full surface and environment variable overrides.

The shipped configuration carries a local-development passphrase, and known placeholder values are rejected at startup with a settings load error, because an HMAC computed with a known secret can be forged by anyone who knows it. Replace the development passphrase before running outside local development.

The EC value is the deterministic HMAC base plus a random suffix. It contains no name, email, account identifier, or other field supplied by the user. The value is written back as Set-Cookie only when the consent evaluation permits EC creation for the detected jurisdiction. See GDPR Compliance for how signals are interpreted.

The value passes a base64url-compatible allowlist. The cookie envelope sets Path=/, Secure, HttpOnly, SameSite=Lax, and a Max-Age. Domain is computed as .{publisher.domain}. The separate cookie_domain setting applies only to non-EC cookies.

Operational Notes

  • Rotate the secret periodically. Rotation produces a new 64-hex base for subsequent mints.
  • Watch the logs for cookie value rejections, which happen when a ts-ec cookie value carries characters outside the allowlist.

Runtime Behavior Notes

  • Returning requests with consent and an existing ts-ec do not refresh the EC cookie or KV TTL.
  • Newly generated ECs receive Set-Cookie: ts-ec=....
  • When consent is blocked but not explicitly withdrawn, Trusted Server strips EC response headers for that request but leaves any existing ts-ec cookie intact; cookie expiry and tombstones happen only on explicit withdrawal.
  • /_ts/api/v1/identify is read-oriented and returns identity enrichment for the authenticated partner. It computes cluster_size only when the EC entry does not already store one.
  • /_ts/api/v1/batch-sync writes mappings into the EC identity graph. Mapping timestamps are retained for API compatibility but no longer order writes; valid mappings use idempotent last-write-wins semantics.
  • Pull sync fills missing partner UIDs only. Existing partner UIDs are not periodically refreshed because EC entries no longer store per-partner sync timestamps.

Next Steps

Released under the Apache License 2.0.