<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc [
  <!ENTITY nbsp "&#160;">
  <!ENTITY zwsp "&#8203;">
  <!ENTITY nbhy "&#8209;">
  <!ENTITY wj "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt"?>
<rfc
  xmlns:xi="http://www.w3.org/2001/XInclude"
  category="info"
  docName="draft-surampudi-wtx1-00"
  ipr="trust200902"
  submissionType="independent"
  xml:lang="en"
  version="3">

  <front>
    <title abbrev="WTX-1">WTX-1: Cross-Domain Context Preservation Protocol</title>

    <seriesInfo name="Internet-Draft" value="draft-surampudi-wtx1-00"/>

    <author fullname="Ravi Teja Surampudi" initials="R. T." surname="Surampudi">
      <organization>Nylo Project</organization>
      <address>
        <email>ravisurampudi@outlook.com</email>
        <uri>https://github.com/tejasgit/nylo</uri>
      </address>
    </author>

    <date year="2026" month="February" day="20"/>

    <area>Applications and Real-Time</area>
    <workgroup>Independent Submission</workgroup>

    <keyword>cross-domain</keyword>
    <keyword>analytics</keyword>
    <keyword>privacy</keyword>
    <keyword>pseudonymous</keyword>
    <keyword>cookies</keyword>

    <abstract>
      <t>
        This document defines the WTX-1 (WaiTag Transfer Protocol,
        version 1) for preserving pseudonymous user context across
        unrelated web domains without third-party cookies, browser
        fingerprinting, login requirements, or personal data collection.
        The protocol uses cryptographically generated pseudonymous
        identifiers (WaiTags), URL hash fragment transport, server-side
        verification, and DNS-based domain authorization to enable
        privacy-respecting cross-domain analytics.
      </t>
    </abstract>

  </front>

  <middle>

    <!-- Section 1: Introduction -->
    <section anchor="introduction">
      <name>Introduction</name>

      <t>
        Third-party cookies have been the primary mechanism for
        cross-domain user identification since the 1990s. With Safari's
        Intelligent Tracking Prevention
        (<xref target="ITP">ITP</xref>) deployed in 2017, Firefox
        Enhanced Tracking Protection (ETP) in 2019, and Chrome's Privacy
        Sandbox initiative beginning in 2024, this mechanism is being
        eliminated across all major browsers.
      </t>

      <t>
        When a user navigates from one domain to an unrelated domain
        (different effective top-level domain plus one label, or eTLD+1),
        analytics systems lose the ability to understand that the same
        visitor made both visits. This creates blind spots in patient
        journey analytics across healthcare providers, financial customer
        experience across banking portals, government service usage
        across agency domains, and multi-brand retail analytics.
      </t>

      <t>
        Existing solutions have significant limitations: browser
        fingerprinting is ethically problematic and legally risky;
        login-based identity excludes anonymous visitors; first-party
        data sharing requires business partnerships and PII exchange;
        Privacy Sandbox Topics API is coarse-grained, advertising-focused,
        and Chrome-only.
      </t>

      <t>
        WTX-1 addresses these limitations by defining a protocol that:
      </t>

      <ol>
        <li>Preserves visitor context across unrelated domains</li>
        <li>Never collects, transmits, or derives personal information</li>
        <li>Works without cookies, fingerprinting, or login</li>
        <li>Resists tracking by unauthorized third parties via DNS-based domain authorization</li>
        <li>Degrades gracefully when consent is denied</li>
        <li>Operates within GDPR, CCPA, and ePrivacy frameworks</li>
      </ol>

      <section anchor="requirements-language">
        <name>Requirements Language</name>
        <t>
          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
          <xref target="RFC2119"/> <xref target="RFC8174"/> when,
          and only when, they appear in all capitals, as shown here.
        </t>
      </section>
    </section>

    <!-- Section 2: Terminology -->
    <section anchor="terminology">
      <name>Terminology</name>

      <dl>
        <dt>WaiTag</dt>
        <dd>
          A pseudonymous identifier generated per-visitor using
          cryptographic randomness. Format:
          wai_&lt;timestamp_b36&gt;_&lt;random&gt;&lt;domain_hash&gt;.
          Contains no personally identifiable information (PII).
        </dd>

        <dt>Origin Domain</dt>
        <dd>
          The domain where the user's session begins and the WaiTag
          is generated.
        </dd>

        <dt>Destination Domain</dt>
        <dd>
          The domain the user navigates to, which receives and
          verifies the WaiTag via a cross-domain token.
        </dd>

        <dt>Cross-Domain Token</dt>
        <dd>
          A time-limited, server-signed token encoding the WaiTag
          for transfer between domains.
        </dd>

        <dt>DNS Authorization</dt>
        <dd>
          Domain ownership verification via DNS TXT records that
          authorizes a domain to participate in WTX-1 identity
          sharing.
        </dd>

        <dt>Verification Server</dt>
        <dd>
          The server-side component that issues, signs, and verifies
          cross-domain tokens.
        </dd>

        <dt>Anonymous Mode</dt>
        <dd>
          A degraded operating mode where no WaiTag is generated,
          no identity is preserved, and identity-related API calls
          are no-ops.
        </dd>
      </dl>
    </section>

    <!-- Section 3: Protocol Overview -->
    <section anchor="protocol-overview">
      <name>Protocol Overview</name>

      <t>
        The WTX-1 protocol operates in seven steps across three
        participants: the origin domain, the destination domain, and
        the verification server.
      </t>

      <figure anchor="protocol-flow">
        <name>WTX-1 Protocol Flow</name>
        <artwork type="ascii-art"><![CDATA[
  Domain A            Verification           Domain B
  (Origin)              Server             (Destination)
     |                    |                      |
  1. User visits          |                      |
  2. Generate WaiTag      |                      |
  3. Register WaiTag ---->|                      |
     |              4. Store WaiTag              |
     |                    |                      |
  5. User clicks link     |                      |
     to Domain B          |                      |
  6. Request token ------>|                      |
     |              7. Verify DNS                |
     |                 authorization             |
     |<--------- 8. Return signed token          |
     |                    |                      |
  9. Append token to      |                      |
     URL hash fragment    |                      |
     |                    |                      |
     |--- User navigates to Domain B ----------->|
     |                    |                      |
     |                    |    10. Read token     |
     |                    |        from hash      |
     |                    |<---- 11. Verify token |
     |                    |                      |
     |              12. Check signature,         |
     |                  expiry, domain           |
     |                    |                      |
     |                    |----> 13. Return       |
     |                    |      identity         |
     |                    |                      |
     |                    |  14. Restore WaiTag   |
     |                    |      Clean URL        |
        ]]></artwork>
      </figure>

      <section anchor="step-by-step">
        <name>Step-by-Step</name>

        <ol>
          <li>
            <strong>WaiTag Generation:</strong> When a user first visits
            a participating domain, the client generates a WaiTag using
            the Web Crypto API (crypto.getRandomValues). The WaiTag
            format is wai_&lt;timestamp_base36&gt;_&lt;random_id&gt;&lt;domain_hash&gt;.
          </li>
          <li>
            <strong>Identity Registration:</strong> The client registers
            the WaiTag with the verification server. The server stores
            the WaiTag, session ID, originating domain, and timestamp.
          </li>
          <li>
            <strong>Cross-Domain Navigation:</strong> When the user
            navigates to another participating domain, a cross-domain
            token is appended to the destination URL. The mechanism for
            link decoration is implementation-defined (e.g., server-side
            link rewriting, client-side click handlers, or manual URL
            construction).
          </li>
          <li>
            <strong>Token Generation:</strong> The verification server
            generates a signed, time-limited token encoding the user's
            WaiTag and session context. The server SHOULD verify that the
            destination domain is DNS-authorized before issuing the token.
          </li>
          <li>
            <strong>Hash Fragment Transport:</strong> The token is
            appended to the destination URL as a hash fragment
            (#nylo_token=&lt;token&gt;). Hash fragments are never sent
            to the server in HTTP requests, providing an additional
            privacy layer.
          </li>
          <li>
            <strong>Token Verification:</strong> On the destination
            domain, the client reads the token from the hash fragment
            and sends it to the verification server for validation.
          </li>
          <li>
            <strong>Identity Restoration:</strong> If verification
            succeeds, the server returns the original WaiTag and session
            context. The client restores the user's pseudonymous identity
            on the new domain and removes the token from the URL.
          </li>
        </ol>
      </section>
    </section>

    <!-- Section 4: WaiTag Format -->
    <section anchor="waitag-format">
      <name>WaiTag Format</name>

      <section anchor="waitag-structure">
        <name>Structure</name>
        <t>A WaiTag has the following structure:</t>
        <artwork><![CDATA[
wai_<timestamp>_<random><domain_hash>
        ]]></artwork>

        <table anchor="waitag-components">
          <name>WaiTag Components</name>
          <thead>
            <tr><th>Component</th><th>Encoding</th><th>Length</th><th>Source</th></tr>
          </thead>
          <tbody>
            <tr><td>Prefix</td><td>ASCII</td><td>4 chars</td><td>Literal "wai_"</td></tr>
            <tr><td>Timestamp</td><td>Base-36</td><td>~8 chars</td><td>Current time in milliseconds</td></tr>
            <tr><td>Separator</td><td>ASCII</td><td>1 char</td><td>Literal "_"</td></tr>
            <tr><td>Random ID</td><td>Base-36</td><td>11 chars</td><td>crypto.getRandomValues (8 bytes)</td></tr>
            <tr><td>Domain Hash</td><td>Hex</td><td>8 chars</td><td>One-way hash of hostname</td></tr>
          </tbody>
        </table>
      </section>

      <section anchor="waitag-properties">
        <name>Properties</name>
        <t>A WaiTag has the following properties:</t>
        <ul>
          <li>Not reversible: No component can be reversed to identify a natural person.</li>
          <li>Not derived from PII: No personal information is used as input.</li>
          <li>Domain-scoped: The domain hash binds the WaiTag to its origin, but the hash is one-way and cannot reveal the domain to a third party.</li>
          <li>Collision-resistant: 64 bits of cryptographic randomness provides sufficient uniqueness for analytics use cases.</li>
          <li>Not a fingerprint: No hardware, software, or behavioral signals are used.</li>
          <li>Not deterministic: The same user on the same device will receive different WaiTags across sessions unless identity is explicitly restored via cross-domain token.</li>
        </ul>
      </section>

      <section anchor="waitag-generation">
        <name>Generation Requirements</name>
        <t>
          Implementations MUST generate WaiTags using
          crypto.getRandomValues <xref target="W3C-WebCryptoAPI"/> or
          an equivalent cryptographically secure pseudorandom number
          generator (CSPRNG). If the Web Crypto API is not available,
          implementations MAY fall back to Math.random, but SHOULD log
          a warning indicating reduced randomness quality.
        </t>
      </section>
    </section>

    <!-- Section 5: Token Transport -->
    <section anchor="token-transport">
      <name>Token Transport</name>

      <section anchor="hash-fragment-transport">
        <name>Primary: URL Hash Fragment</name>
        <t>
          The cross-domain token MUST be transported via URL hash
          fragment as the primary mechanism:
        </t>
        <artwork><![CDATA[
https://destination.example.com/page#nylo_token=<signed_token>
        ]]></artwork>
        <t>
          Hash fragments (the portion of a URL after "#") are processed
          entirely client-side per <xref target="RFC3986"/>
          Section 3.5. They are:
        </t>
        <ul>
          <li>Never included in HTTP requests to the server</li>
          <li>Never logged in server access logs</li>
          <li>Never sent in the Referer header</li>
          <li>Not visible to network intermediaries (proxies, CDNs, WAFs)</li>
        </ul>
        <t>
          This provides a stronger privacy guarantee than URL query
          parameters, which are transmitted to the server and commonly
          logged.
        </t>
      </section>

      <section anchor="search-param-fallback">
        <name>Fallback: URL Query Parameters</name>
        <t>
          If hash fragment transport is not feasible (e.g., the
          destination URL uses hash-based client-side routing), the
          token MAY be transported as a query parameter:
        </t>
        <artwork><![CDATA[
https://destination.example.com/page?nylo_token=<signed_token>
        ]]></artwork>
        <t>
          Implementations using query parameter transport SHOULD remove
          the token from the URL immediately after reading it, using the
          History API (history.replaceState) to clean the URL without
          triggering a page reload.
        </t>
      </section>

      <section anchor="parameter-names">
        <name>Parameter Names</name>
        <t>
          Implementations MUST accept both of the following parameter
          names for cross-domain tokens:
        </t>
        <ul>
          <li>"nylo_token" (primary)</li>
          <li>"wai_token" (alternative)</li>
        </ul>
      </section>

      <section anchor="token-cleanup">
        <name>Token Cleanup</name>
        <t>
          After reading a cross-domain token from the URL, the client
          MUST remove it from the URL to prevent:
        </t>
        <ul>
          <li>Accidental sharing of token-bearing URLs</li>
          <li>Token replay from browser history</li>
          <li>Token exposure in analytics tools that capture full URLs</li>
        </ul>
        <t>
          The client SHOULD use history.replaceState to remove the token
          without causing a navigation event or page reload.
        </t>
      </section>
    </section>

    <!-- Section 6: Token Format and Verification -->
    <section anchor="token-format">
      <name>Token Format and Verification</name>

      <section anchor="token-contents">
        <name>Token Contents</name>
        <t>A cross-domain token encodes the following fields:</t>
        <table anchor="token-fields">
          <name>Cross-Domain Token Fields</name>
          <thead>
            <tr><th>Field</th><th>Description</th></tr>
          </thead>
          <tbody>
            <tr><td>waiTag</td><td>The pseudonymous identifier to transfer</td></tr>
            <tr><td>sessionId</td><td>The session identifier from the origin domain</td></tr>
            <tr><td>originDomain</td><td>The domain that issued the token</td></tr>
            <tr><td>destinationDomain</td><td>The intended recipient domain</td></tr>
            <tr><td>issuedAt</td><td>UTC timestamp of token creation</td></tr>
            <tr><td>expiresAt</td><td>UTC timestamp of token expiry</td></tr>
            <tr><td>signature</td><td>Server-generated signature (HMAC or implementation-defined)</td></tr>
          </tbody>
        </table>
        <t>
          The token encoding format is implementation-defined. Common
          choices include JSON Web Tokens (JWT) <xref target="RFC7519"/>
          and opaque server-side tokens with a lookup key.
        </t>
      </section>

      <section anchor="verification-requirements">
        <name>Verification Requirements</name>
        <t>The verification server MUST check:</t>
        <ol>
          <li>Signature validity: The token has not been tampered with.</li>
          <li>Expiry: The token has not expired. The expiry window is configurable; the recommended default is 5 minutes.</li>
        </ol>
        <t>The verification server SHOULD also check:</t>
        <ol>
          <li>Domain authorization: The destination domain is DNS-authorized to receive identities.</li>
          <li>Origin matching: The token was issued for the domain making the verification request.</li>
        </ol>
      </section>

      <section anchor="verification-endpoint">
        <name>Verification Endpoint</name>
        <t>
          The verification endpoint accepts a POST request with
          Content-Type application/json containing the token, the
          requesting domain, a customer identifier, and the HTTP
          Referer value.
        </t>

        <t>Request body:</t>
        <sourcecode type="json"><![CDATA[
{
  "token": "<signed_token>",
  "domain": "destination.example.com",
  "customerId": "<customer_id>",
  "referrer": "https://origin.example.com/page"
}
        ]]></sourcecode>

        <t>Success response:</t>
        <sourcecode type="json"><![CDATA[
{
  "success": true,
  "identity": {
    "sessionId": "<session_id>",
    "waiTag": "<wai_tag>",
    "userId": null
  }
}
        ]]></sourcecode>

        <t>Failure response:</t>
        <sourcecode type="json"><![CDATA[
{
  "success": false,
  "error": "TOKEN_EXPIRED"
}
        ]]></sourcecode>
      </section>
    </section>

    <!-- Section 7: DNS Domain Authorization -->
    <section anchor="dns-authorization">
      <name>DNS Domain Authorization</name>

      <section anchor="dns-purpose">
        <name>Purpose</name>
        <t>
          Before a domain can receive cross-domain identities, it SHOULD
          prove ownership via a DNS TXT record. This prevents unauthorized
          domains from requesting or receiving WaiTags and ensures that
          only domains controlled by the same organization (or
          participating partners) can share visitor context.
        </t>
      </section>

      <section anchor="dns-txt-format">
        <name>TXT Record Format</name>
        <t>The DNS TXT record uses the following format:</t>
        <artwork><![CDATA[
_nylo-verify.example.com. IN TXT
    "nylo-domain-verify=<verification_code>"
        ]]></artwork>
        <t>
          The verification code is a unique value generated by the
          verification server for each domain registration.
        </t>
      </section>

      <section anchor="dns-verification-flow">
        <name>Verification Flow</name>
        <ol>
          <li>The domain owner registers the domain with the verification server and receives a verification code.</li>
          <li>The domain owner adds the TXT record to their DNS configuration.</li>
          <li>The domain owner calls the verification endpoint.</li>
          <li>The server performs a DNS lookup for _nylo-verify.&lt;domain&gt;.</li>
          <li>If the TXT record matches the expected verification code, the domain is authorized.</li>
          <li>Authorization is cached server-side and periodically re-verified.</li>
        </ol>
      </section>

      <section anchor="subdomain-inheritance">
        <name>Subdomain Inheritance</name>
        <t>
          If a parent domain (e.g., example.com) is DNS-verified,
          subdomains (e.g., blog.example.com, shop.example.com) inherit
          authorization automatically. Implementations MAY provide
          configuration to exclude specific subdomains from inheritance.
        </t>
      </section>
    </section>

    <!-- Section 8: Client-Side Storage -->
    <section anchor="client-storage">
      <name>Client-Side Storage</name>

      <section anchor="storage-strategy">
        <name>Three-Layer Strategy</name>
        <t>
          The client SHOULD store identity data using multiple
          mechanisms for resilience against browser storage restrictions:
        </t>
        <table anchor="storage-layers">
          <name>Storage Layers</name>
          <thead>
            <tr><th>Layer</th><th>Mechanism</th><th>Persistence</th><th>ITP Impact</th></tr>
          </thead>
          <tbody>
            <tr><td>1</td><td>First-party cookie</td><td>24h (JS-set under ITP)</td><td>Capped at 7 days</td></tr>
            <tr><td>2</td><td>localStorage</td><td>Until cleared</td><td>Partitioned by eTLD+1</td></tr>
            <tr><td>3</td><td>sessionStorage</td><td>Tab lifetime</td><td>Unaffected</td></tr>
          </tbody>
        </table>
      </section>

      <section anchor="storage-priority">
        <name>Storage Read Priority</name>
        <t>
          When restoring identity, the client reads in order: cookie,
          localStorage, sessionStorage. The first valid result is used.
        </t>
      </section>

      <section anchor="stored-data">
        <name>Data Stored</name>
        <t>The stored identity record contains:</t>
        <sourcecode type="json"><![CDATA[
{
  "sessionId": "<secure_id>",
  "waiTag": "<wai_tag>",
  "userId": null,
  "domain": "example.com",
  "createdAt": "2026-02-20T12:00:00.000Z",
  "integrity": "<hash>"
}
        ]]></sourcecode>
        <t>
          The "integrity" field is a one-way hash of the session ID,
          domain, WaiTag, and customer ID, used to detect tampering.
        </t>
      </section>

      <section anchor="storage-obfuscation">
        <name>Data Obfuscation</name>
        <t>
          Data stored in localStorage SHOULD be encoded with a
          customer-specific salt and timestamp to prevent casual
          inspection. This is obfuscation, not cryptographic security.
          The stored data contains no PII regardless of encoding.
        </t>
      </section>
    </section>

    <!-- Section 9: Consent and Anonymous Mode -->
    <section anchor="consent">
      <name>Consent and Anonymous Mode</name>

      <section anchor="consent-api">
        <name>Consent API</name>
        <t>
          Implementations MUST provide a consent API that integrates
          with Consent Management Platforms (CMPs). The API MUST
          support the following operations:
        </t>
        <ul>
          <li>setConsent({analytics: false}) - Deny consent, switch to anonymous mode</li>
          <li>setConsent({analytics: true}) - Grant consent, restore identity tracking</li>
          <li>getConsent() - Query current consent state, returns {analytics: boolean}</li>
        </ul>
      </section>

      <section anchor="anonymous-mode">
        <name>Anonymous Mode Behavior</name>
        <t>
          When consent is denied, the client MUST operate in anonymous
          mode with the following behavior:
        </t>
        <ul>
          <li>Event tracking remains active but with no identity attached.</li>
          <li>WaiTag generation is disabled; waiTag is null.</li>
          <li>The identify() API call is a no-op and is silently ignored.</li>
          <li>getSession() returns null for waiTag and userId fields.</li>
          <li>Cross-domain identity is disabled; no tokens are generated or accepted.</li>
          <li>Only a session-scoped anonymous identifier is used (format: anon_&lt;timestamp&gt;_&lt;random&gt;).</li>
          <li>No persistent identity data is written to cookies, localStorage, or sessionStorage.</li>
        </ul>
      </section>

      <section anchor="consent-restoration">
        <name>Consent Restoration</name>
        <t>
          When consent is granted after starting in anonymous mode:
        </t>
        <ol>
          <li>The client checks for previously stored identity data.</li>
          <li>If found, the existing WaiTag and session are restored.</li>
          <li>If not found, a new WaiTag is generated.</li>
          <li>Cross-domain token checking is activated.</li>
          <li>Full identity tracking resumes.</li>
        </ol>
      </section>

      <section anchor="regulatory-position">
        <name>Regulatory Considerations</name>
        <t>
          WaiTags are designed to fall outside the
          <xref target="GDPR">GDPR</xref> definition of
          "personal data" as defined in Article 4(1) of Regulation (EU)
          2016/679 because they contain no information derived from a
          natural person, cannot be reversed or cross-referenced to
          identify someone, and are not deterministic across sessions.
        </t>
        <t>
          However, the classification of pseudonymous identifiers under
          data protection law varies by jurisdiction and is subject to
          evolving regulatory interpretation. Implementers SHOULD consult
          local legal counsel. The anonymous mode provides a conservative
          fallback for jurisdictions where pseudonymous identifiers may
          be considered personal data.
        </t>
      </section>
    </section>

    <!-- Section 10: Security Considerations -->
    <section anchor="security">
      <name>Security Considerations</name>

      <section anchor="token-security">
        <name>Token Security</name>
        <ul>
          <li>Tokens MUST be signed server-side using HMAC
          <xref target="RFC2104"/> or an equivalent mechanism.</li>
          <li>Tokens MUST have a configurable expiry window. The recommended default is 5 minutes.</li>
          <li>Tokens SHOULD be single-use where feasible to prevent replay attacks.</li>
          <li>Token verification MUST validate the signature and expiry.</li>
        </ul>
      </section>

      <section anchor="transport-security">
        <name>Transport Security</name>
        <ul>
          <li>All API communication between the client and the
          verification server MUST use HTTPS
          <xref target="RFC2818"/>.</li>
          <li>Hash fragment transport prevents server-side token logging by design, as fragments are not included in HTTP requests per <xref target="RFC3986"/>.</li>
          <li>When query parameter fallback is used, the client MUST clean the token from the URL after reading.</li>
        </ul>
      </section>

      <section anchor="input-validation">
        <name>Input Validation</name>
        <ul>
          <li>All client-supplied strings MUST be sanitized to prevent cross-site scripting (XSS) attacks. HTML entity encoding is RECOMMENDED.</li>
          <li>String fields MUST be length-limited. The recommended maximum is 1,000 characters.</li>
          <li>Domain values MUST be validated before use in DNS lookups or token generation.</li>
        </ul>
      </section>

      <section anchor="rate-limiting">
        <name>Rate Limiting</name>
        <ul>
          <li>API endpoints MUST implement rate limiting. The recommended default is 100 requests per IP address per minute.</li>
          <li>Rate limit status MUST be communicated via X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset response headers.</li>
          <li>Exceeded limits MUST return HTTP 429 (Too Many Requests).</li>
        </ul>
      </section>

      <section anchor="response-headers">
        <name>Response Headers</name>
        <t>
          Servers implementing WTX-1 SHOULD set the following
          security-related response headers:
        </t>
        <ul>
          <li>X-Content-Type-Options: nosniff</li>
          <li>X-Frame-Options: SAMEORIGIN</li>
          <li>Referrer-Policy: strict-origin-when-cross-origin</li>
          <li>Permissions-Policy: camera=(), microphone=(), geolocation=()</li>
          <li>Content-Security-Policy: Appropriate policy for the deployment</li>
          <li>Strict-Transport-Security: max-age=31536000; includeSubDomains (when serving over HTTPS)</li>
        </ul>
      </section>
    </section>

    <!-- Section 11: IANA Considerations -->
    <section anchor="iana">
      <name>IANA Considerations</name>
      <t>
        This document has no IANA actions.
      </t>
      <t>
        If this protocol achieves broader adoption, the following
        registrations may be requested in future revisions:
      </t>
      <ul>
        <li>
          Registration of the "_nylo-verify" DNS underscore name
          prefix in the "Underscored and Globally Scoped DNS Node
          Names" registry per RFC 8552.
        </li>
        <li>
          Registration of the "nylo_token" and "wai_token" URI
          fragment parameter names if a suitable registry is
          established.
        </li>
      </ul>
    </section>

    <!-- Section 12: Privacy Considerations -->
    <section anchor="privacy">
      <name>Privacy Considerations</name>

      <t>
        WTX-1 is designed from the ground up to preserve user privacy while
        enabling cross-domain analytics. This section details the privacy
        properties, guarantees, and limitations of the protocol.
      </t>

      <section>
        <name>Core Privacy Commitments</name>
        <ol>
          <li>No PII collection: The protocol never collects, transmits, or derives personal information such as names, email addresses, phone numbers, or physical addresses.</li>
          <li>No fingerprinting: No hardware, software, or behavioral signals (screen resolution, installed fonts, GPU rendering, etc.) are used to generate or correlate identifiers.</li>
          <li>No third-party cookies: Cross-domain identity does not use the Set-Cookie/Cookie HTTP mechanism for cross-domain transfer.</li>
          <li>No login required: Identity preservation works for anonymous visitors without requiring authentication or account creation.</li>
          <li>Consent-respecting: The protocol degrades to fully anonymous tracking when consent is denied, ensuring compliance with opt-out requirements.</li>
          <li>Domain-authorized: Only DNS-verified domains can participate in identity sharing, preventing unauthorized cross-domain tracking.</li>
          <li>Time-limited tokens: Cross-domain tokens expire (default 5 minutes), preventing indefinite tracking or token reuse.</li>
          <li>Client-side token reading: Hash fragment transport ensures tokens are never sent to destination servers in HTTP requests. The token is subsequently sent to the verification server via a dedicated API call for validation.</li>
        </ol>
      </section>

      <section>
        <name>Pseudonymous Identifiers</name>
        <t>
          WaiTags are pseudonymous identifiers generated using cryptographically
          secure random number generators (window.crypto.getRandomValues). They
          contain no embedded personal information, device characteristics, or
          derivable real-world identity. A WaiTag cannot be reversed to identify
          a natural person without access to a separate mapping table, which the
          protocol does not define or require.
        </t>
        <t>
          Under GDPR, pseudonymous identifiers are still considered personal data
          when they can be attributed to a natural person by using additional
          information. Implementors MUST ensure that any additional information
          that could link a WaiTag to a natural person is kept separately and
          subject to appropriate technical and organizational measures.
        </t>
      </section>

      <section>
        <name>User Control and Consent</name>
        <t>
          Implementations SHOULD provide users with clear mechanisms to:
        </t>
        <ol>
          <li>Opt out of cross-domain identity sharing while retaining single-domain analytics.</li>
          <li>Clear their WaiTag and session data at any time.</li>
          <li>View what data has been collected about their pseudonymous identity.</li>
          <li>Request deletion of all data associated with their WaiTag.</li>
        </ol>
        <t>
          When a user denies consent, the protocol MUST degrade gracefully to
          anonymous mode where no cross-domain tokens are generated or accepted,
          and only aggregate, non-identifiable analytics are collected.
        </t>
      </section>

      <section>
        <name>Data Minimization</name>
        <t>
          The protocol follows the principle of data minimization as required by
          GDPR Article 5(1)(c). Cross-domain tokens contain only the minimum
          fields necessary for identity verification: a WaiTag, session
          identifier, optional user identifier, source domain, expiration
          timestamp, and cryptographic signature. No behavioral data, page
          content, or interaction history is included in the token.
        </t>
      </section>

      <section>
        <name>Cross-Domain Tracking Scope</name>
        <t>
          Cross-domain identity sharing is limited to domains that have been
          explicitly authorized via DNS TXT records. This prevents a domain
          from being included in a tracking network without the domain owner's
          explicit consent. The DNS verification mechanism ensures that only
          organizations with administrative control over a domain can authorize
          it for cross-domain identity sharing.
        </t>
        <t>
          Implementations MUST NOT allow wildcard domain authorization or
          open enrollment of domains into a tracking network.
        </t>
      </section>

      <section>
        <name>Regulatory Compliance</name>
        <t>
          WTX-1 is designed to operate within the following regulatory frameworks:
        </t>
        <ul>
          <li>GDPR (EU): Pseudonymous processing with data minimization, purpose limitation, and right to erasure support.</li>
          <li>CCPA/CPRA (California): No sale of personal information; supports opt-out mechanisms.</li>
          <li>ePrivacy Directive (EU): No use of cookies or similar technologies for cross-domain transfer; hash fragment transport does not trigger cookie consent requirements.</li>
          <li>HIPAA (US Healthcare): No collection or transmission of Protected Health Information (PHI).</li>
          <li>COPPA (US Children): Protocol does not collect age information; implementors in child-directed services MUST implement additional safeguards.</li>
        </ul>
        <t>
          Implementors are responsible for ensuring their specific deployment
          complies with applicable local regulations, as the protocol alone
          does not guarantee regulatory compliance.
        </t>
      </section>

      <section>
        <name>Limitations and Residual Risks</name>
        <t>
          While WTX-1 provides strong privacy guarantees, the following
          residual risks should be acknowledged:
        </t>
        <ul>
          <li>Server-side correlation: Organizations operating multiple domains may correlate WaiTags server-side. The protocol limits this to DNS-authorized domains but cannot prevent the authorizing organization from performing correlation.</li>
          <li>Token interception: Although hash fragment transport prevents tokens from being sent in HTTP requests, tokens may be visible to browser extensions or client-side JavaScript on the destination page before cleanup occurs.</li>
          <li>Referrer leakage: Some browsers may include hash fragments in Referer headers under certain conditions. Implementations SHOULD set Referrer-Policy headers to mitigate this risk.</li>
          <li>Long-lived sessions: If WaiTags are stored in localStorage without expiration, they persist indefinitely. Implementations SHOULD implement WaiTag rotation or expiration policies.</li>
        </ul>
      </section>
    </section>

  </middle>

  <back>

    <!-- References -->
    <references>
      <name>References</name>

      <references>
        <name>Normative References</name>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2104.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2818.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3986.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
      </references>

      <references>
        <name>Informative References</name>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7519.xml"/>

        <reference anchor="W3C-WebCryptoAPI">
          <front>
            <title>Web Cryptography API</title>
            <author>
              <organization>W3C</organization>
            </author>
            <date year="2017" month="January"/>
          </front>
          <seriesInfo name="W3C Recommendation" value=""/>
          <refcontent>https://www.w3.org/TR/WebCryptoAPI/</refcontent>
        </reference>

        <reference anchor="GDPR">
          <front>
            <title>Regulation (EU) 2016/679 (General Data Protection Regulation)</title>
            <author>
              <organization>European Parliament and Council</organization>
            </author>
            <date year="2016" month="April"/>
          </front>
          <refcontent>https://eur-lex.europa.eu/eli/reg/2016/679/oj</refcontent>
        </reference>

        <reference anchor="ITP">
          <front>
            <title>Intelligent Tracking Prevention</title>
            <author>
              <organization>Apple WebKit</organization>
            </author>
            <date year="2017" month="June"/>
          </front>
          <refcontent>https://webkit.org/blog/7675/intelligent-tracking-prevention/</refcontent>
        </reference>
      </references>
    </references>

    <!-- Appendix A: Comparison -->
    <section anchor="comparison" numbered="false">
      <name>Comparison with Existing Approaches</name>
      <table>
        <name>Cross-Domain Identity Approaches</name>
        <thead>
          <tr>
            <th>Property</th>
            <th>3P Cookies</th>
            <th>Fingerprinting</th>
            <th>Login-Based</th>
            <th>WTX-1</th>
          </tr>
        </thead>
        <tbody>
          <tr><td>Cross eTLD+1</td><td>Yes (deprecated)</td><td>Yes</td><td>Yes</td><td>Yes</td></tr>
          <tr><td>Requires login</td><td>No</td><td>No</td><td>Yes</td><td>No</td></tr>
          <tr><td>Collects PII</td><td>Varies</td><td>Yes</td><td>Yes</td><td>No</td></tr>
          <tr><td>Browser support</td><td>Declining</td><td>Declining</td><td>Universal</td><td>Universal</td></tr>
          <tr><td>Consent required</td><td>Yes</td><td>Yes</td><td>Varies</td><td>Recommended</td></tr>
          <tr><td>Works on Safari</td><td>No (ITP)</td><td>Partially</td><td>Yes</td><td>Yes (degraded)</td></tr>
        </tbody>
      </table>
    </section>

    <!-- Acknowledgments -->
    <section anchor="acknowledgments" numbered="false">
      <name>Acknowledgments</name>
      <t>
        WTX-1 was developed as part of the Nylo project to address the
        analytics gap created by the deprecation of third-party cookies,
        with a focus on privacy-respecting solutions for regulated
        industries including healthcare, finance, and government.
      </t>
    </section>

  </back>

</rfc>
