Introduction
Edition 3.1.1
This is edition 3.1.1 of the User Identity & Attribution Framework (UIAF), licensed under Apache-2.0. v3 is a breaking change from the published 2.0.0 edition; do not mix v2 and v3 payloads or registries.
Why Native Identity Management
Section titled “Why Native Identity Management”Most websites add tracking through external scripts, loaded from a tag manager or a third-party host. Those scripts load late, run where ad blockers and privacy extensions can intercept them, and cannot directly emit an HTTP Set-Cookie response header without server participation. That approach has three structural problems.
-
Timing. External scripts load after the main page. A visitor can leave, submit a form, or fire the event you needed before the script even runs. When the identity code lives in your own server, the identity cookie can be set with the very first response, before the browser draws the page. (Native client code does not have to execute in the first response; the advantage is the server boundary being first-party, not a fixed execution point.)
-
Blocking. Ad blockers keep filter lists of known third-party tag and tracking hosts, and a
gtag.jsloaded from such a host is trivially blocked. Code that is part of your own application, setting a first-party cookie from your own server, is not on those lists by default. This reduces blocking; it does not eliminate it. -
Cookie lifetime. Browsers restrict storage that JavaScript can write more aggressively than a cookie your own server sets with a
Set-Cookieresponse header. The exact limits differ per browser and change over time, so verify against current behavior rather than treating any number as permanent (Browser Landscape).
The User Identity & Attribution Framework (UIAF) takes the native route: the identity system is part of your first-party application, deployment, and origin, not a third-party tag. The identity-resolution logic lives in your codebase, not in a tag template.
Only your server can create a lasting user ID (UID). If your site has no server or serverless function, UIAF can still run in a temporary mode where no identity is stored. That mode cannot recognize returning visitors and cannot claim the persistent-identity profile.
UIAF’s job is narrow. It manages identity (who is this user?), captures attribution (how did they get here?), and prepares, freezes, and attempts delivery of a structured payload. Freezing means the payload’s bytes are produced once and never edited afterward; delivery uses honest-loss / bounded-retry contracts, so arrival is not guaranteed. UIAF does not decide what to measure, does not define behavioral events, and does not render analytics dashboards. Those decisions belong to your analytics platform (GA4, Adobe, and so on).
What This Spec Is and Isn’t
Section titled “What This Spec Is and Isn’t”This specification IS:
- An implementation specification with concepts (why), requirements (what), illustrative pseudocode (how it might look), diagrams, edge cases, and FAQ sections.
- Platform-agnostic: the same spec applies whether you build on WordPress/PHP, Next.js, Django, Rails, or a static site backed by serverless functions.
- A reference for developers, technical stakeholders, and privacy reviewers.
This specification IS NOT:
- A library, SDK, or installable package. There is no
npm install uiaf. - Framework-specific. The mock code is pseudocode that resembles JavaScript but is explicitly not runnable, and no framework-specific code or complete reference implementation is provided.
- A consent management platform. It reads the authoritative consent state (the selected source, its lifecycle/status, and the effective permission vector) at collection time; it does not collect consent.
- A behavioral tracking system. It emits exactly three protocol event classes (
session,conversion,identify), not an arbitrary taxonomy of pageviews, clicks, or interactions.
In scope: the three protocol event classes (session, conversion, identify) and the normative endpoint ingress contract (raw-body validation, trust classes, idempotency/deduplication, ordering, and the control-plane contracts). On conversion, conversion_name is a required field whose deployment vocabulary is open, and the optional event_data.extensions is the sole generic extension point. This is not an arbitrary behavioral event taxonomy. Out of scope: the endpoint’s internal processing and its mappings to downstream platforms.
The developer’s job is to translate this spec into their platform. The pseudocode illustrates intent; the diagrams show data flow; the test scenarios define expected outcomes. The implementation is yours.
Pseudocode and template-injection contract
Section titled “Pseudocode and template-injection contract”All mock code in this specification is written in a block-structured pseudocode dialect that is explicitly not runnable. It resembles JavaScript for readability but omits imports, error plumbing, and framework glue, and it must be translated, not copied. The dialect’s convention is that a line naming a real browser API (for example navigator.locks, document.cookie, sendBeacon) carries a // REAL API marker. That way implementers can distinguish a real platform surface from illustrative shorthand.
Server-rendered patterns inject server-side context into the page template. This page writes that as the {{ uiaf_context_json }} placeholder; the Implementation Guide uses the equivalent server-side injection helpers (for example an inject-context helper). Wherever a server injects such context, the injected value must be escaped for the exact output context (HTML and, inside a <script> block, JavaScript-string/JSON context) before rendering. An unescaped injection is an XSS sink. This injection-safety contract governs those equivalent 09 server-rendered patterns and is defined here (normative as UIAF-01-CODE-001 below).
UIAF-01-CODE-001 — The specification’s mock code MUST be treated as a block-structured, explicitly non-runnable pseudocode dialect; by that dialect’s convention a line naming a genuine browser API MUST carry a
// REAL APImarker; and any server-side injection of{{ uiaf_context_json }}(or an equivalent inject-context helper) into a page template MUST be escaped for its exact output context (HTML, and JavaScript-string/JSON context inside a<script>block) before rendering.
Integration note (non-blocking). The frozen Implementation Guide (Spec 09) does not yet annotate every real browser API with // REAL API and realizes template injection through inject-context helpers rather than the literal {{ uiaf_context_json }} placeholder. That marker/placeholder retrofit is to be reconciled in a later Spec 09 pass; it is not changed here, and this contract governs those equivalent patterns as written.
How to Read This Spec
Section titled “How to Read This Spec”The spec is structured in two phases: full technical capability first, then the consent overlay that degrades it.
Sections 02–06, Full Technical Capability. These describe the system operating at maximum capability: full persistence, full attribution capture, complete identity resolution. Read them first to understand everything the system can do.
- 02 — Identity Management: how user identifiers are minted, persisted, and recovered.
- 03 — Attribution Capture: which marketing parameters are captured and how the touch model works.
- 04 — Endpoint Schema: the structured payload format and the normative endpoint ingress, trust-class, and control-plane contracts.
- 05 — Browser Landscape: how different browsers restrict storage (dated, with primary sources) and what the system does about it.
- 06 — Identity Resolution: cross-device linking, cross-domain handoff, and authenticated-identity binding.
Section 07, Consent Overlay. 07 — Consent Integration takes the full capability from 02–06 and degrades it by the authoritative consent lifecycle/status together with the effective permission vector. While pending there is no data-plane send; not_applicable runs under an established site policy; and resolved acts on the selected source and its effective permissions. Behavior keys off status and the effective vector; tiers are display-only shorthand, never a behavioral switch. This is not a separate system. It is the same system with constraints applied.
Sections 08–09, Data Handling and Implementation.
- 08 — Data Handling: data minimization, PII hashing, cookie-security attributes, and the rationale for endpoint authentication and trust classes.
- 09 — Implementation Guide: concrete integration patterns for each platform type.
Where authentication and endpoint trust are concerned, Endpoint Schema is normative (the endpoint ingress, trust-class, and control-plane contracts), while Data Handling provides the rationale.
Conformance
Section titled “Conformance”The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in BCP 14 (RFC 2119 and RFC 8174) when, and only when, they appear in all capitals, as shown here — and only inside the identified requirement blocks. Requirement identifiers use the form UIAF-<section>-<area>-<number> (for example UIAF-04-EP-001) and are stable after publication. As a release gate, every testable MUST/MUST NOT is required to map to at least one test scenario (security/rejection requirements to a negative scenario), and non-automatable requirements are required to carry a reviewed waiver; this is a release-gate obligation, not an assertion that the mapping is already complete.
A conforming implementation belongs to one or more of three classes (the shared reference validator is not a class; it is tooling those classes use):
- Client: the browser-side runtime. It resolves identity, captures attribution under the consent rules, freezes the immutable payload, and attempts delivery.
- Server Integration: the same-origin server or serverless participation. Minting and setting the identity cookie, request-context derivation, and the same-origin relay that applies validation, origin policy, and rate limits and holds downstream authentication.
- Endpoint: the receiving service. It validates raw bodies against the shared reference validator, deduplicates and orders events, and enforces the trust classes.
UIAF-01-CONF-001 — A conforming implementation MUST identify itself as one or more of the Client, Server Integration, or Endpoint classes and MUST satisfy every requirement block applicable to the class(es) it claims.
UIAF-01-CONF-002 — A deployment claiming the persistent-identity profile MUST have same-origin server or serverless participation to mint and set the identity cookie. When such participation is unavailable, a deployment MAY operate in explicitly nonpersistent ephemeral mode (no persistent UID) and MUST NOT claim conformance to the persistent-identity profile; it is not otherwise compelled into any identity mode.
Core Architecture
Section titled “Core Architecture”The division of responsibility:
- The website (Client + Server Integration) resolves identity, captures attribution, and freezes and attempts payload delivery. The primary path is a same-origin relay: your own server receives the payload first, checks it, and forwards it with server-held credentials. The relay applies validation, origin policy, and rate limits, forces
_meta.emittertoclientfor browser submissions, and holds the downstream authentication. Only an authenticated server-to-server channel may assertemitter: "server". - Direct browser-to-public-endpoint delivery is an explicit untrusted alternative: the endpoint enforces strict validation, origin policy, quotas, and abuse monitoring with zero privileged or control-plane effect. It does not attempt “forgery rejection.”
- The endpoint (typically server-side GTM) validates the raw body against the shared reference validator and forwards to downstream platforms. The exact ingress, trust-class, and relay contracts are normative in Endpoint Schema and applied in Implementation Guide; this section does not restate the algorithms.
The website prepares data. The relay validates and forwards it with server-held downstream authentication. The endpoint routes it. The platforms consume it.