Some suggestions for improvements to the TPE, to help increase transparency and make implementation easier. This is based on building the Chrome and Firefox browser extension Bouncer, which implements the full Javascript API, together with experience creating user consent systems based on the API on European ePrivacy compliant websites.

Scope

Introduction

Sites and third-party servers are not likely to implement DNT (either the W3C TCS or the EFF flavour) unless there is a scalable way to override the DNT general preference on particular domains i.e. to whitelist them. Moreover, the TCS scope section specifically requires browser support for the JavaScript Exceptions or Consent API. The API has proven to be implementable in browsers and browser extensions, but there has been no use of it by a high profile site such as a publisher or third-party advertiser. Until the API is more widely supported the out-of-band mechanism is the only way for domains to be white-listed, but it suffers from a lack of verifiability and transparency.

There have been a few implementations of the Tracking Status Resource or the Tk response. Moreover there also been very few declarations by sites of one of the valid EFF DNT policies at /.well-known/dnt-policy.txt

Some sites such as www.w3.org, pixel.piwik.org and gchq.gov.uk have the Tk response header, but with an incorrect value. This could partly to do with lack of clarity, but also hints at the problems for server side code detecting (in a scalable way) out-of-band consent using cookies. Server side code capable of changing HTTP headers is often maintained by a different team, even a different company, than the team responsible for the logic of a web application. A way for the application team to declare the header using a "meta tag" approach could help here, as it has for other recommendations such as the Content-Security-Policy header.

The GDPR and the principles laid out in the EU-US Privacy Shield arrangements both call for increased transparency. Embedded third-parties now have to be identified and declare their legal basis and purpose for personal data processing. This requirement is a good fit with facilities in browsers, or browser extensions, to present information clearly, which in turn relies on it being available in a standardised machine readable way. The Tracking Status Resource is perfect mechanism for that, but it would help if this could be deployed more flexibly. Giving sites the option to vary the location of the TSR, and to declare it within an HTML document using meta tags would make it easier for sites to deploy it.

This suggested changes are an attempt to address these issues:

Tracking Status Resource in the Tk Response Header field

Organisations sometimes have to manage several, perhaps thousands, of websites, often developed and maintained by marketing agencies and other contracted parties. Logistically it can be difficult to manage the multiple servers run by these disparate parties in a coordinated way.

An example of where this is required is delivering a Tk response header, especially when the out-of-band consent (OOBC) mechanism must be used. If a user's browser does not support the DNT Exception (Consent) API then the server must determine from the request if tracking consent has been given by that user, before inserting the correct Tk response header. This will in most cases involve looking up the value of an authentication cookie in an external database, and the code to do this would have to reside in the server, and it, or its underlying logic, would have to be shared among the different parties.

Another example is the delivery and maintenance of the Tracking Status Resource at the "well known" location. Every origin would have to contain a reference (at /.well-known/dnt) to the current resource, which may have to be maintained by the company's legal or data protection function.

While it is possible in the current TPE to target any URI as the declared Tracking Status Resource using a chain of HTTP Redirects, getting all a company's servers to initiate the correct server-side redirection code can be difficult.

Both of these issues could be addressed by explicitly allowing the delivery of Tk responses within the returned HTML content, and communicating an alternative TSR URI within the response. It is relatively easy to supply a JavaScript library reference to be inserted in every HTML head-section, and this is a well understood industry practice.

This mechanism would only take effect in situations where an origin server did not return a Tk header, and where it did not already return a well formed JSON resource to a GET to /.well-known/dnt.

This proposal calls for the ability to specify the Tracking Status Resource within the value of the Tk response header, and be able to declare any Tk response header in an HTML head section using a meta tag with the standard http-equiv attribute.

In future there is likely to be a standardised policy resource for an entire origin (e.g web site) where security and policy oriented headers can be declared. The motivation for this is managing the "header bloat" issue arising from new recommendations such as Content-Security-Policy. It would make sense to append the Tracking Status Resource to this, and incorporating a reference inside a header is a natural way to do it. If every site must have a set of cached origin-wide resources it would be best to combine their functionality so only one extra round-trip was needed, and to minimise the size of the cache.

A valid URI after a "%" character in the Tk header will be construed as a valid Tracking Status Resource, unless a valid resource is also located at {origin server domain}/.well-known/dnt, in whch case that resource is taken as the only valid one.

If a Tk response header exists the meta tag is ignored. If a Tracking Status Resource exists at {origin server domain}/.well-known/dnt then any "%" component of any Tk response , in a header or in the HTML, is ignored.

The new Tk response header is defined formally by the following ABNF

            Tk-field-name  = "TK"
            Tk-field-value = TSV [ ";" status-id] [ "%" URI-reference]
            status-id =  1*id-char
            id-char =  ALPHA / DIGIT / "_" / "-" / "+" / "=" / "/"
            URI-reference is defined as per [[RFC3986]]
         

Tk response header via meta tag

The server MAY supply a Tk response via an HTML meta elements with http-equiv attributes that are an ASCII case-insensitive match for the string "Tk". For example:

<meta http-equiv="Tk" content="N">
<meta http-equiv="Tk" content="C%https://corporate-site.com/.well-known/dnt">

Add the following entry to the pragma directives for the meta element:

Tracking response (http-equiv="Tk")
  1. If a Tk response header exists abort these steps.
  2. If the Document’s head element is not an ancestor of the meta element, abort these steps.
  3. If the meta element lacks a content attribute, abort these steps.
  4. Let trackingResponse be the value of the content attribute of the meta element.

Authors are strongly encouraged to place meta elements as early in the document as possible, because policies in meta elements are not applied to content which precedes them.

Note: Modifications to the content attribute of a meta element after the element has been parsed will be ignored.

well-known named cookie to indicate consent

If a user agent does not support the JavaScript API i.e. if navigator.confirmWebWideTrackingException is undefined, and so cannot indicate a DNT exception by sending DNT: 0 to the appropriate origin server, then there should be an alternative method to indicate user consent, i.e. that DNT: 1 has been overridden, by arranging for the user agent to send a cookie with a "well known" name. It is envisioned that a JavaScript library could be installed on a page to be activated if the required functionality is not implemented by a particular user agent.

For transparency and verifiability the cookie should have a standard name __DNT0, MUST have the Secure flag, and must only be placed if the user has given their affirmative consent for web-wide tracking by the origin server, i.e. as the result of the appropriate call to the JavaScript DNT Exception API.

If the server recognises the consent indication it MUST respond with a Tk: C header, or an HTML response containing a in the head section.

The recognition of web-wide consent for origin server is straight forward using this method, as the cookie would be present in every request. For site-specific consent the data needed could be encoded in the cookie's value, perhaps to be matched against the domain specified in a Referer header. If the recognition requires servers held in the server linked by singling-out via a UID this should be encoded here, and in that case the qualifier TSR property MUST include the i code.

Cookie:__DNT0=1a5b43ea7

Tracking Status Representation - Additional Properties

Status Object

The tracking status representation can have the following additional or amendedproperties, as illustrated by the following Orderly schema [Orderly]:

object {
    string tracking;                 // as per the Orderly schema in the TPE
    array { string; } compliance?;   //                 ''                   
    string qualifiers?;              // amended below 
    array { string; } controller?;   // as per the Orderly schema in the TPE
    array { string; } same-party?;   //                 '' 
    array { string; } audit?;        //                 '' 
    string policy?;                  //                 '' 
    string config?;                  //                 '' 
    array { object { string name; string uri} } controllerDescription; // Legal name of the data controller and a URI of a page providing the user with information about it;
    
    object { long overall_retention?; // A positive number of seconds indicating the overall maximum lifetime of the client storage.
             array object { string type ["C","L","I"]; // storage type C = a cookie, L = localStorage item, I = indexdedDB table, "E" = cache item e.g. ETag 
                            string match; // a regular expression used to match an item of storage when applied to the item name or cookie name and value pair
                            array { string ["n","t","i","f","a","u","O","!f","!l","!s","!d"]* purpose;};
                            array { string sharedWith; }; // the main domains names managed by the entities the data may be shared with.
                            long retention?; // A positive number of seconds indicating the maximum lifetime of the storage item.
                          } 
           } storageUse; // matches any client data item e.g. a cookie, item in localStorage etc., used by the origin server
    string deleteDataUri?; // URI of resource that causes all tracking data on this origin to be deleted
    string optInUri?; // URI of resource that causes the origin server or its JavaScript browsing context to register tracking consent
    string optOutUri?; // URI of resource that causes the origin server or its JavaScript browsing context to revoke any tracking consent
    string dataHeldUri; // URI of resource that will return HTML content identifying tracking data held by the origin server,  
                        // giving the user the ability to access, amend or delete it.
    object {integer {,48} bitLength?; integer maxAge}} trackingIdConstraint?; // declared tracking identifier entropy and expiry
    array { string; } currentAudienceSelector?; // array of audience categories derived from the current DNT-identifier
}*;

controllerDescription

An origin server MAY send a property named controllerDescription containing an array of objects representing one or more Data Controllers responsible for an origin. Each object contains a string name indicating the unique name of the Data Controller entity along with a string url containing the URI of a human readable web page describing the entity. If the controller TSR property is present the url property need not be. If the url property is present it overrides the value of any TSR controller property.

qualifiers

This contains a set of characters corresponding to explanations or limitations on tracking. The meaning of each character is explained by one or more of the regimes listed in the compliance property. For example the codes referred to in the default W3C compliance document are:

qualifier permitted use
c frequency capping
f financial logging
s security
d debugging
t transferred

Additional codes for use in implementing site-specific consent in the absence of support for the JavaScript Consent API (and to help comply with Recital 66 of the European ePrivacy directive) could be:

qualifier purpose description
n strictly necessary strictly necessary to fulfil a service requested by the user, e.g. authentication
T transmission solely used for the purpose of carrying out the transmission of a communication
L first-party login solely used for registering an authenticated user. If the cookie accessible to an embedded third-party then the duration MUST be limited to no more than 24 hours
i site-specific consent tracking solely for the purpose of detecting whether site-specific consent had been given
o other tracking for any other purpose for which informed consent has been given

storageUse

This is an object representing user agent storage employed by the origin server for tracking or other purposes. This gives the origin server the ability to transparently describe in a standardised way the overall retention time for client storage and the purpose and retention period for each storage item. User agents MAY present this information to the user, and privacy regulators, audit services etc. will be able use website scanning tools to verify it. In addition Privacy Enhancing Technology components, such as TrackingBlocker or AdBlocker extensions, can make intelligent decisions regarding content blocking or storage removal when enforcing a user's privacy preferences. The object contains a long integer overall_retention a positive number of seconds indicating the maximum lifetime of all the declared data. and an array of objects describing individual storage items controlled by the origin server. Each of these contains a selector string used to match the name or name-value pair of a particular item , a string type representing the class of storage used where "C" is an HTTP cookie, "L" is local HTML5 storage and "I" is indexedDB. The selector string MAY contains a = character to demarcate between Regex match strings for the name and value of a name-value pair. The purposes for each item is encoded in the purpose array of strings. If this is present it MUST contain one or more of the following purpose identifiers. N.B. Need to specify Qualifiers.

Code Purpose Definition
n Necessary Strictly necessary to fulfil a service requested by the user.
t Transmission Solely used for the purpose of carrying out the transmission of a communication.
i Site-Specific Consent Solely for the purpose of detecting whether site-specific consent had been given when the user agent does not support JavaScript Exception API.
f Functional Retains information in the user agent solely used to retain state between HTTP transactions without a unique user identifier. Any data retained is generic in nature and will not be used to profile the user.
a Analytics Used to collect anonymous statistical information about visitors to a web site. No attempt will be made to single-out the user for profiling purposes. Any unique identifier used will not be shared with any other party.
u Tracking Used to single-out or track a user, i.e. a unique user identifier. If this is shared with another party their domain MUST be indicated in the sharedWith attribute below.
O Opt-out This identifies an HTTP cookie used by some non-standard systems to indicate that a user has opted-out from tracking. If the same cookie name is also used as a UID tracking identifier then the selector must uniquely identify the opt-out case e.g. UID=opted-out. A properly identified opt-out cookie MUST not be deleted by a user agent when other storage is deleted, for example when the overall_retention period expires.
!f Permitted capping Used for frequency capping, i.e.to limit the number of times that a user sees a particular advertisement, often called frequency capping, as long as the data retained do not reveal the user’s browsing history.
!l Permitted logging Used for financial logging, i.e. for billing and auditing related to the current network interaction and concurrent transactions. This may include counting ad impressions to unique visitors, verifying positioning and quality of ad impressions and auditing compliance with this specification and other standards.
!s Permitted security Used for security, i.e. to the extent reasonably necessary to detect security incidents, protect the service against malicious, deceptive, fraudulent, or illegal activity, and prosecute those responsible for such activity, provided that such data is not used for operational behaviour beyond what is reasonably necessary to protect the service or institute a graduated response.
!d Permitted debugging Used for debugging, i.e. solely collected, retained or used for debugging purposes to identify and repair errors that impair existing intended functionality.
The long integer retention contains a positive number of seconds indicating the maximum lifetime of the storage item. The optional array of strings sharedWith represents the main domains of any entities that any data is shared with.

deleteDataUri

An origin server MAY send a property named deleteDataUri indicating the URI (relative to the origin domain) of a resource that will delete any personal data held in the user agent such as identifiers used for non-permitted tracking.

optInUri

The URI of a resource to communicate a user opt-in (explicit consent) to an origin server. When a user opts-in using a user agent based UI, an HTTP GET MAY be sent to this URI to communicate the change in consent

optOutUri

The URI of a resource to communicate a user opt-out (revoked consent) to a server. When a user opts-out using a user agent based UI, or the user agent detects that the Consent Grant has expired, an HTTP GET MAY be sent to this URI to communicate the change in consent.

dataHeldUri

The URI of resource that will return HTML content identifying tracking data held by the origin server, giving the user the ability to access, amend or delete it.

User-Agent header dntapi client property information

Many browsers have yet to support the JavaScript API and this makes it difficult for servers who want to register user consent to decide on whether to support the API or fall back to the out-of-band mechanism. It is for server side code to insert the Tk header and this is a necessity if OOBC must b used. JavaScript can be used to detect the shortfall, but this creates the necessity for another round-trip to communicate the result. At this time even this is problematic in the case of the Microsoft Edge browser because navigator.confirmSiteSpecificTrackingException exists, and it is not until a call to storeSiteSpecificTrackingException is made, which throws an Access is denied exception, that the client code can detect that the API is not supported.

We propose that Browsers or browser extensions that support the API should indicate this to servers by including the string dntapi in the User-Agent request header. Servers or client code can easily detect this string and immediately implement the appropriate procedures.

API

The [[tracking-dnt]]] JavaScript API is enhanced in the following ways:

            partial interface Navigator {
                Promise<TrackingStatusObject> 
                    storeSiteSpecificTrackingException (TrackingPermission properties);
                Promise<TrackingStatusObject> 
                    confirmTrackingException(TrackingPermission properties);
            };
            dictionary TrackingStatusObject {
                DomString Status; // string value indicating "OK" for success or any other value for failure
                DOMString GrantId; // a unique value registered for this granted exception, 
                                   // or consent receipt. 
                                   // This can be communicated to a server so the grant  can be matched to one stored 
                                   // within the user agent for proof-of-consent purposes.
            };
            dictionary StoreExceptionPropertyBag {
            DOMString? domain;
            DOMString? siteName;
            DOMString? explanationString;
            DOMString? detailURI;
            DOMString? expires;
            long? maxAge;
            };
            dictionary TrackingPermission : StoreExceptionPropertyBag {
                boolean? useSameParty; // true to specify UGE is also for same-parties
                boolean? resetTargets; // clears any pre-existing arrayOfDomainNames property from a previous granted exception
                DOMString? DNTVal; // the DNT field-name to be sent in future requests to this origin server, optionally its same-parties, and any targets. 
                                   // if the property is present the first character must be either "0" or "1"
                                   // The user agent will strip any characters after the field value which defaults to "0".
                DOMString? optIn; // the URI of a resource to communicate a user opt-in (explicit consent) to a server. When a user opts-in using a user agent
                                  // based UI, an HTTP GET MAY be sent to this URI.
                DOMString? optOut; // the URI of a resource to communicate a user opt-out (revoked consent) to a server. When a user opts-out using a user agent
                                  // based UI, or the user agent detects that the Consent Grant has expired, an HTTP GET MAY be sent to this URI.
            };