This specification extends the [[TPE]] to achieve the following:
This document is an editors' straw man reflecting a snapshot of live discussions within the Tracking Protection Working Group . It does not necessarily constitute working group consensus. This draft has been prepared using the DNT Github repository and its associated issues list. However, see the previous issue tracking system for working group decisions prior to 2017. See for a summary of changes since the first Candidate Recommendation.
The GDPR requires that the identity of origin server is discoverable by web users, and the [[TPE]] supports this by enabling every origin server to identify itself by hosting a Tracking Status Resource (TSR) at the /.well-known/dnt/ location. This specification further requires that the information presented to a user before they agreed to a Tracking Exception, i.e. gave their informed consent for the collection and further processing of personal data derived from on-line activity, is permanently determinable from the TSR. As cookie headers SHOULD be present in the TSR request, servers can use them, or an identifier encoded in the DNT header as described in this specification, to determine what purposes the user has agreed to, and present them in a human-readable document pointed to by a new "purposes" TSR property. As cookies may not always be available to third-party requests the DNT encoded identifier could be a more reliable way to do it.
As well as introducing universal mechanisms for delivering machine-readable transparency information, and conveying a signal indicating individuals consent or otherwise for tracking in the DNT request header, the [[TPE]], via the Site-Specific Tracking Exception, introduced the ability to communicate this consent signal efficiently to embedded third-parties. Publishers can use this to signal immediately to third-parties when users have given consent, and the reverse when consent expires or is withdrawn. Under the GDPR consent must be "specific", meaning this signal must be capable of being selectively delivered to those parties to which the user has given their agreement, and this is supported by the API by allowing DNT:0 only to be sent to named embedded third-parties. Furthermore, when the user withdraws their consent, or has never given it, the opted-in/opted-out indication is restricted to a particular site - opting-out does not have to apply to the whole web, as it does when only standard third-party HTTP cookies are available.
Although a single boolean, indicating consent/no-consent, can be delivered this way, i.e. site-specifically via the DNT header, there is currently no way to do this similarly for data. HTTP cookies are intrinsically web-wide, once stored they will always be included in resource requests, whether to embedded third-parties or to first-party websites. The privacy concerns arising from this has led to cookies being increasingly blocked in third-party requests, either by the browser or by user action. Even when they are available users are much less likely to give their consent to tracking when there is no guarantee it will be constrained to one site, or a defined subset of sites. This means that if the user has agreed to site-specific tracking, say within a publishers first-party site, the persisted information has to recorded in a first-party cookie and communicated to embedded third-parties somehow. Even if this can be done in a scalable way, for example by editing the target URL with a mutually agreed encoding, the third-party could not persist it in one of its own cookies, because even if cookies were not blocked the tracking data would then be available web-wide, i.e on any site which embedded the same third-party.
This specification describes the ability for first-parties to efficiently communicate
site-specific values to embedded third-party servers,
but only after the user
has agreed to a site-specific Tracking Exception indicating consent.
This value is communicated to server in the DNT request header,
and to their associated browsing contexts in the
navigator.doNotTrack
property.The data would be immediately available to the third-party server within the request, so
there would be no need for additional round-trip delays. Like cookies, it would be available in all requests to the domain, i.e. not just to particular resources,
and it would not need to be separately persisted. The value could be encoded by first-party script at any time, for any purpose for which then user had agreed,
and there would be no need for the logistically complex and inefficient mechanisms needed for user-specific URL editing.
The value is only transmitted to, or available to, first-party or embedded third-party servers in the context of a single site, or defined subset of the web, and this could be readily and externally verified.
As further security measures this value would only be settable when the registering API call is made within a user gesture,
similar to the way the WebKit [[StorageAPI]] requestStorageAccess()
is constrained,
and only when the request is secure, i.e. delivered over https
.
Browsers SHOULD support an ability to indicate to the user when a DNT header is carrying a site-specific value, say in the browser chrome. How this information interacts with browser specific anti-tracking features is left to browser vendors.
The Tracking Exception API has been extended to support the ability of servers to register a site-specific Tracking Exception value of "1", useful in situations where a user has not configured their browser with a general Tracking Preference, and servers are legally required to support a signal to indicate the right-to-object, for example under the GDPR's Article 21.5.'
The key words must, must not, required, should, should not, recommended, may, and optional in this specification are to be interpreted as described in [[!RFC2119]].
This specification uses the Augmented Backus-Naur Form (ABNF) notation of [[!RFC5234]] to define network protocol syntax and WebIDL [[!WebIDL-20161215]] to define scripting APIs. Conformance criteria and considerations regarding error handling are defined in Section 2.5 of [RFC7230].
How to throw a DOMexception and the exceptions named "InvalidStateError", "SecurityError", and "SyntaxError" are defined in [[!WebIDL-20161215]].
Promise objects are defined in [[ECMASCRIPT]]; the phrases promise-call, resolve promise, reject promise, upon fulfillment, and upon rejection are used in accordance with [[PromiseGuide]].
When a user has enabled a tracking preference, that preference needs to be expressed to all mechanisms that might perform or initiate tracking.
When enabled, a tracking preference is expressed as either:
DNT | meaning |
---|---|
1 | This user prefers not to be tracked on this request. |
0 | This user prefers to allow tracking on this request. |
A user agent MUST NOT send a tracking preference expression if a tracking preference is not enabled. This means that no expression is sent for each of the following cases:
In the absence of regulatory, legal, or other requirements, servers MAY interpret the lack of an expressed tracking preference as they find most appropriate for the given user, particularly when considered in light of the user's privacy expectations and cultural circumstances. Likewise, servers might make use of other preference information outside the scope of this protocol, such as site-specific user preferences or third-party registration services, to inform or adjust their behavior when no explicit preference is expressed via this protocol.
The DNT
header field is a mechanism for expressing the
user's tracking preference in an HTTP request ([[!RFC7230]]).
At most one DNT
header field can be present in a valid request.
DNT-field-name = "DNT" DNT-field-value = ( "0" DNT-Consent / "1" ) DNT-Consent = %x21-7E ; excludes CTL, SP
A user agent MUST NOT generate a DNT
header field if the
user's tracking preference is not enabled.
A user agent MUST generate a DNT
header field with a
field-value that begins with the numeric character "1" if the user's
tracking preference is enabled, their preference is for
DNT:1, and no exception has been granted for the
target resource (see ).
A user agent MUST generate a DNT
header field with a
field-value that begins with the numeric character "0" if the user's
tracking preference is enabled and their preference is for
DNT:0, or if an exception has been granted for
the target resource.
A proxy MUST NOT generate a DNT
header field unless it has
been specifically installed or configured to do so by the user
making the request and adheres to the above requirements as if it
were a user agent.
GET /something/here HTTP/1.1 Host: example.com DNT: 1
When a domain origin implements tracking for multiple distinct purposes, and these are described to the user before they are given the option to agree to one or more of them, the subset of purposes the user has selected must be communicated back to the origin. While cookies may be used for this, they may not be always available, and in any case an embedding parent context, e.g. a first-party origin, would not be able to set them for origins it had embedded.
The DNT-Consent qualifier allows an arbitrarily encoded
string to be communicated to servers solely in
circumstances where the user has given their informed consent.
It is denoted by "0" followed by one or more alphanumeric characters.
The JavaScript Site-Specific storeTrackingException API,
with a site
dictionary property not set to "*", must be used to specify
a DNT field-value containing the DNT-Consent qualifier,
which can be encoded in any way that the relevent server that receives it can decode.
The browsing context executing it must be secure, i.e. the content has been delivered over https
.
If an origin server specifies a DNT-Consent qualifier it MUST implement a site-wide tracking status resource with a valid Purposes property. The Purposes property is a dynamically determined HTML resource containing a human-readable explanation of all the purposes for tracking that a domain origin implements, as well as the specific purposes a particular user has agreed to as communicated in the DNT header of the request to the site-wide tracking status resource.
Browsers MUST make it easy for users to see if a DNT-Consent qualifier has been specified for any page and/or any of the embedded third-parties on the page, and MUST offer the ability to immediately cancel the associated Tracking Exception should they want.
For example, a request containing
DNT:0 purpose=an,adwould indicate that the user had given consent for tracking, but solely for the purposes of analytics and advertising.
Similarly, a request to a particular third-party server containing
DNT:0 audience=male>65would indicate that the user had given consent for an audience indication to be sent from the publisher to that third-party.
The navigator.doNotTrack
property enables
a client-side script with read access to the
Navigator
object
[[!HTML51]] to determine what DNT header field value would be
sent to the effective script origin, taking into account the
user's general preference (if any) and user-granted exceptions
applicable to the target domain when referenced by the
active document's top-level browsing context.
partial interface Navigator { readonly attribute DOMString? doNotTrack; };
The value is null
if no DNT header field would be
sent (e.g., because a tracking preference is not enabled
and no user-granted exception is applicable);
otherwise, the value is a string beginning with "0" or "1",
possibly followed by DNT-extension characters.
Specifically, the value of Navigator.doNotTrack for a given
script is either null
or the string value that would be
sent in a DNT field-value
()
in a request to a target resource at the
effective script origin (the current document.domain
of
the script's responsible document) when that request is due to
an embedded reference from this site (the document.domain
of
the top-level browsing context's active document).
Ideally, the value of navigator.doNotTrack ought to reflect the current set of user-granted exceptions in effect when the attribute is read.
When a site has obtained consent for a
user-granted exception, or a user has indicated their
objection to lawfully exempted tracking when their tracking
preference is not enabled, a script running within an active
browsing context or nested browsing context of that
site can promise-call
Navigator.storeTrackingException
to store one or more tracking exceptions.
A TrackingExData
object is
supplied as a parameter to define the exception's scope (the set of
[site, target] duplets that encompass the granted exception)
and optional information to be stored for that exception.
The call returns a promise which either resolves to a
TrackingExResult
or is rejected with
a DOMException
identifying the reason for the failure.
partial interface Navigator { Promise<TrackingExResult> storeTrackingException ( TrackingExData properties ); }; dictionary TrackingExData { DOMString? site; sequence<DOMString>? targets; DOMString? name; DOMString? explanation; DOMString? details; long? maxAge; DOMString fieldValue; }; dictionary TrackingExResult { boolean isSiteWide; };
Navigator.storeTrackingException passes a TrackingExData object. A user agent MUST ignore unknown properties of the TrackingExData object (for future extensibility). The following OPTIONAL properties are defined:
site
*
", the exception is
intended to be web-wide< for the set of
targets.
A user agent MUST reject the promise with the
DOMException
named "SecurityError" if both
site and
any of the targets
are "*
".
*.
". The value
can be set to a fully-qualified right-hand segment of the
document host name, up to one level below TLD.
targets
[site, *]
, meaning
that the exception applies to all domains referenced by the
site.
[site, script domain]
, meaning that
the exception applies only to resources that share the same
domain as the effective script origin.
[site, domain]
.
name
explanation
details
maxAge
maxAge
is supplied and not null, empty, or
negative, the user agent MUST remove the stored exception
no later than the specified number of seconds after being
stored.
maxAge
is not supplied, the user agent
MAY retain the stored grant indefinitely.
fieldValue
DNT
header with the field-value set to "1" for all
requests to domains for which this exception applies; or
DNT
header with the field-value set to fieldValue for all requests
to domains for which this exception applies; or
DNT
header with the field-value set to "0" for all
requests to domains for which this exception applies; or
The properties name, explanation, and details are provided by the caller for the sake of potential user interfaces. If a user agent presents these properties to the user, it ought to be clear that they are provided for informational value and are less important than the exception's technical effect.
In addition to the data above, a user agent might also store ambient information about the call, such as the URI associated with the top-level browsing context, the effective script origin, a current timestamp, or other information potentially obtained from applicable tracking status resources.
The calling script domain MUST have a site-wide tracking status resource with a valid tracking status representation that includes a policy property. This allows a user agent to obtain and possibly store additional information about the caller’s controller and tracking policies at the time an exception is granted.
A user agent MAY reject the promise with a DOMException named "InvalidStateError" if it cannot determine the effective script origin or if the site corresponding to that origin does not have a site-wide tracking status resource with a valid tracking status representation.
For each site-specific exception being stored, a user agent MUST NOT store the duplets and MUST reject the promise with a DOMException named "SecurityError" if the script would not be able to set a cookie on that duplet's referring domain scope following the cookie domain rules [[!RFC6265]].
For example, a script on www.foo.bar.example.com can set
the site as
"bar.example.com"
or
"example.com"
, but not to
"something.else.example.com"
or "com"
.
For each web-wide exception being stored, a user agent MUST NOT store the duplets and MUST reject the promise with a DOMException named "SecurityError" if the script would not be able to set a cookie on that target domain following the cookie domain rules [[!RFC6265]]. This limits storing of a web-wide exception to scripts that share the same domain scope as the exception targets, but allows such scripts to be embedded within iframes of a common consent portal.
For any other failure, such as an incorrectly formatted parameter in the TrackingExData, the user agent MUST NOT store any of the target duplets in the database and MUST reject the promise with a DOMException named "SyntaxError".
Upon fulfillment, the user agent has added to its local database one or more site-pair duplets [site, target], each indicating that a request from that site domain to the target domain will include DNT:0 regardless of the user's general tracking preference. The fulfilled promise object contains the following TrackingExResult attribute:
isSiteWide
true
if the user agent stored a potentially
broader exception that applies to all domains (as opposed to just
the listed targets); otherwise, false
.
When a list of targets
is supplied for a site-specific exception,
the user agent MAY ignore that list, choosing instead to
store a site-specific exception for all domains
([site, *]
), if it also indicates that result by
setting the returned promise's
isSiteWide property
to true
.
User agents MAY instantiate Navigator.storeTrackingException even when Navigator.doNotTrack is null. Scripts SHOULD test for the existence of Navigator.storeTrackingException before calling the method.
There are some security concerns here regarding the ability of a
script with an effective script origin matching one site
being able to persist the DNT value received by resources on other
(target) sites. In particular, this feature could be abused to
set/unset an array of exceptions, similar to an array of bit values,
and be "read" as a persistent identifier by embedding requests to
those domains (which might all point to the same Internet host).
However, we expect that would leave an obvious trail on the
user agent, unlike other sources of fingerprinting.
Likewise, allowing an exception to be stored within an iframe of
another site's page could be ripe for abuse unless the calling
script ensures that it is being run within a page where it expects
to be collecting user consent and where the context of that consent
is consistent with the exceptions being stored.
This design is consistent with the fact that there is no technical
restraint from sites calling the API without having first obtained
an informed consent from the user. We are assuming that the social
and regulatory environment will be sufficient to punish
those who might misuse the API or abuse the scope of stored
exceptions. A user agent might further limit such risks by checking
for a site-wide tracking status resource when its presence is
required by the API.
For each tracking status resource, an origin server MUST provide a
valid representation using the
application/tracking-status+json
media type.
This media type consists of a status object
serialized as JSON [[!RFC7159]]. More information about the
application/tracking-status+json
media type can be
found in .
A tracking status representation consists of a single status object containing properties that describe the tracking status applicable to the designated resource. Most of the properties are optional and can be extended over time, as illustrated by the following Orderly schema [[Orderly]]:
object { string tracking; // TSV array { string; } compliance?; // hrefs string qualifiers?; // compliance flags array { string; } controller?; // hrefs array { string; } same-party?; // domains array { string; } audit?; // hrefs string policy?; // href string config?; // href string purposes?; // href }*;
The following example representation demonstrates a status object with all of the properties defined by this specification.
{ "tracking": "T", "compliance": ["https://acme.example.org/tracking101"], "qualifiers": "afc", "controller": ["https://www.example.com/privacy"], "same-party": [ "example.com", "example_vids.net", "example_stats.com" ], "audit": [ "http://auditor.example.org/727073" ], "policy": "/privacy.html#tracking", "config": "http://example.com/your/data" }
An origin server MAY send a property named
purposes
with a string
value containing a URI reference to a human-readable document that
describes each of the purposes for tracking implemented by this
origin server.
If the origin server supports the DNT-Consent qualifier then this property MUST be supported and be dynamically generated by decoding the field-value of the request's DNT header, to highlight or otherwise indicate the specific subset of purpose the user has agreed to.
Information communicated via the DNT header field is minimized to avoid abuse of the field for fingerprinting or as a side-channel. However, the DNT-Consent extension allows for the sending of additional information when signaling consent for tracking via DNT:0, and could be used to send persistent state information without the user's knowledge. For this reason browsers MUST NOT register a DNT-Consent value when the browsing context is insecure, the Navigator.storeTrackingException call is for a web-wide Tracking Exception, or was not processed in the context of a user gesture. Servers MUST ensure that a DNT-Consent value is only used when the user has given their consent.
Browsers SHOULD support an ability to indicate to the user in the browser chrome when a DNT header is carrying a DNT-Consent extension.