This is a guide to how sites can comply with Do Not Track (DNT). It is based on experience gained helping sites give users control over tracking, using the DNT Consent API, where it is supported, to communicate explicit consent to sites and their third-parties. It does not aim to be a complete guide to how all the DNT building blocks can be used, but tries to deal with those that can help meet the requirements of European Data Protection and ePrivacy law, namely the requirement for prior consent laid out in the ePrivacy Directive amended by 2009/136/EC, the right to object to processing of personal data, when the legal basis is public interest or legitimate interest, set out in Article 21 of the 2016 General Data Protection Regulation (GDPR), or when the legal basis is Consent as set out in Article 6.1(a) of the GDPR or Article 7(a) of the 1995 Data Protection Directive 95/46/EC This may hopefully be useful elsewhere, such as sites or third-party resources under compatible data protection frameworks such as the EU-US PrivacyShield. It may also help those who want to supply the control and transparency elements about tracking recently called for by the FTC.
The DNT
header differs from others in that it can be used to signal to other domains, i.e. it is cross-origin. Once a user has set their general preference not to be tracked,
the signal will be included in every HTTP request to websites, and to servers handling their embedded third-party elements.
In addition the Java-script Consent API (also known as the Tracking Exception API),
can register a user's consent to particular or all embedded third-parties on a particular website, or to a particular third-party resource anywhere on the web.
This allows ePrivacy compliant websites to communicate user consent, when it is given, to embedded third-parties using standard browser signals.
Not all browsers currently support the Consent API so this functionality has had to be developed in a proprietary way (generally known as out-of-band consent) for non-compliant browsers.
DNT is not only about user control - respecting a user's tracking preference, but also transparency - presenting information about tracking behaviour in a standardised way. If sites, or their embedded third-parties, do not communicate privacy practices that can be clearly understood and verified, users will increasingly lose trust in them. Browsers and browser extensions designed to enable tracking protection will also be able to use machine-readable tracking declarations to inform decisions on content blocking and other privacy protective measures.
DNT defines methods for declaring such things as the identity of the site's owner (in Europe the "Data Controller"), its tracking policy (listing why tracking occurs and the purposes for which the collected personal data is used), the compliance regime it operates under, the other host domains it controls, how consent can be given or revoked, and how its tracking behaviour has been modified in the light of a specific tracking preference. This is done in standardised machine-readable elements available to both first party and third-party servers.
Increasingly popular browser extensions, designed to give users control over non-consensual tracking or stop intrusive advertising, can use this information to recognise when a user has given consent, when their expressed preference is being ignored, or when embedded third-parties share the same data controller. This will allow extension developers to make intelligent decisions about sites, so that trustworthy sites and third-parties will not have to have their content or functionality arbitrarily blocked.
If a site does use tracking it must determine, for every incoming HTTP request, whether a user has opted-in to being tracked or has opted-out from it. For opted-out requests "tracking data" must not be stored, collected or retained unless certain exemptions or alleviations apply. "Tracking data" means anything that be used to single-out the user, i.e. unique identifiers in cookies, IP addresses, derived unique identifiers such as browser fingerprints, etc. The exemptions may differ depending on applicable local laws, and whether a particular request is being sent to a first-party or third-party server.
The default formal standard for sites that comply with Do Not Track is available from the W3C. The formal standard for the technical aspects of Do Not Track is Tracking Preference Expression. Other documents such as the EFF's Do Not Track Policy also exist, and it is expected that regulators in Europe and elsewhere will issue detailed guidance on the implications of DNT in their jurisdictions.
Implementation can be broken down to 5 main functional areas.
DNT
header and whether it denotes an opt-out request (DNT:1
)
or an opted-in request (DNT:0
). In certain jurisdictions, such as Europe,
if no DNT
header exists then the site must assume an opted-out user, in others the default may be an implied opted-in.
It is also possible that the user has opted-in to tracking using another mechanism for giving explicit consent not described in the DNT protocol,
referred to here and in other DNT documents as out-of-band consent.
Tracking
property of the TSR.
Tk
response header must be used. Either:
Tracking
property can be set to ?
(Dynamic
) and the TSV delivered in the value of the Tk
response header, or:
Tk
response header or in the tracking
property of a request specific TSR.
A site or web application can detect the DNT
header value by either examining incoming request headers, or by loading JavaScript into a page or iframe
to read the navigator.doNotTrack
property.
It is possible that further extension
characters are present after the leading 0
or 1
so care should be taken to mask them out when determining the value.
A Tracking Status Resource (TSR) must exist.
For example if a site's host domain is origin.com then the server should respond to an HTTP GET
to http://origin.com/.well-known/dnt/
with a properly formatted
JSON object. The response mime type should be application/tracking-status+json
. A DNT
header will also be delivered in the HTTP request for a TSR,
so it would be a simple matter to return a different version dependant on the DNT
value, i.e. DNT:1
could result in TSR with tracking
set to N
, while a request with DNT: 0
could return tracking
set to T
.
An origin server that receives a valid GET request targeting its site-wide tracking status resource must send either a successful response containing a machine-readable representation of the site-wide tracking status, as defined below, or a sequence of redirects that leads to such a representation. Failure to provide access to such a representation implies that the target origin server does not implement this protocol.
A valid TSR must have a tracking
property and a compliance
property.
It makes little sense for it not to also have policy
and controller
properties.
If out-of-band consent is indicated (with the Tk: C
response header) a config
property must also be present.
tracking
stringThis contains the single character Tracking Status Value or TSV.
A tracking status value (TSV) is a single character response to the user's tracking preference with regard to data collected via the designated resource. For a site-wide tracking status resource, the designated resource is any resource on the same origin server. For a Tk response header field, the target resource of the corresponding request is the designated resource, and remains so for any subsequent request-specific tracking status resource referred to by the Tk field value.
If the site does not ever track or single out users it should set this to N
.
If a site always tracks users, irrespective of the DNT
header value but for a "permitted purpose",
it should set the value to T
and set the qualifiers
property to one or more of the values
described for each purpose.
In Europe this may not be necessary if tracking, (or more accurately browser storage used to enable tracking i.e. a UID cookie),
is "strictly necessary to fulfil a purpose requested by the user" or "solely used for the purpose of carrying out the transmission of a communication".
It may still be a good idea to return a Tk: T
header with say an n
(for "strictly necessary"),
or a t
(for "solely used for the purpose of carrying out the transmission of a communication") in the TSR qualifier
property, because
browsers or extension may use an unqualified Tk: T
an indication of a non DNT compliant servers.
A tracking
property value of D
(or a value of T
without a valid qualifier
value
when the requesting headers contained DNT: 1
) signifies purposeful non-compliance with DNT.
This may be useful as a valid response to force browsers and/or extensions to block specific third-parties for debugging or security purposes.
If tracking behaviour varies according to the value of the DNT
header, then this status would be more easily returned in the Tk
response header.
Alternatively the request specific TSR mechanism can be used.
The clearest way to respond would be to include the header to Tk:T
in responses to opted-in requests and Tk:N
for opted-out requests.
Other values for the TSV may be possible, in more complex situations, and if local law allows them.
compliance
arrayThis is an array of strings representing URI references to documents describing the specific data protection or privacy regimes that the site complies with. It at least should contain a reference to the W3C's Tracking Compliance and Scope document http://www.w3.org/2011/tracking-protection/drafts/tracking-compliance.html Other possibilities are the 2002 ePrivacy Directive amended by 2009/136/EC, the 1995 Data Protection Directive 95/46/EC, the 2016 General Data Protection Regulation (GDPR), and the EFF's DNT Policy,
policy
URIThis should point to a document describing the purposes of tracking and the mechanisms used to implement it. In Europe this should also include what browser storage is used and the purposes for its use, and if storage is used for purposes for which consent is not needed, that should also be explained.
config
URIThis should point to a page or resource where the user can opt-in or opt-out of tracking. It may offer other services such as showing what personal data has already been collected for the user, and giving them the ability to amend or delete it.
If a request to a resource results in a change to the tracking state, i.e. an opt-in or an opt-out, then the response can include a Tk: U
header.
This is the only situation that the U
TSV can be returned, and is there to tell the browser to obtain an updated TSR.
This is only an option, and will probably be much easier to return a T
to an opt-in and a N
to an opt-out.
If out-of-band consent is used i.e. a TSV of C
, the config
property must exist.
controller
array
It is a requirement in Europe that every Data Controller identifies itself before personal data is collected,
and the Controller
property is designed for this.
Because there may be more than one company responsible for a particular resource, for example a hosting provider and their customer,
this is an array of string values representing URIs of resources describing the responsible data controller(s).
Each URI points to page where the data controller can be clearly identified by the user, for example a link to an "About" page may suffice.
same-party
array
A site can declare other host domains that it manages by adding them to the same-party
array.
This indicates to browsers etc. which external resource references are actually first-party rather than third-party.
Privacy protecting browsers, browser extensions and AdBlockers could use this as an indication
that they should not block the other first-party domains, even if behavour such as "cookie syncing" has been detected.
qualifiers
string
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 |
Possible codes for use in complying with the European ePrivacy directive could be:
qualifier | alleviation | 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 |
Here is an example of a TSR. The server for example1.com
is declaring that it honours DNT, does not track users, the responsible company is identified
as well as the their privacy policy and that they comply with the W3C Compliance and Scope document, as well as the EU's ePrivacy Directive.
{ "tracking": "N", "compliance": [ "https://www.w3.org/2011/tracking-protection/drafts/tracking-compliance.html", "http://eur-lex.europa.eu/legal-content/en/ALL/?uri=CELEX:32009L0136" ], "policy": "https://example1.com/privacy", "controller": [ "https://example1.com/about" ] }
This server for example2.com
is declaring (when the TSR request contains DNT: 1
) that it honours DNT, only identifies users to fulfil a user requested service and to implement load sharing,
also manages domains img.example2.com
and ourothersite.com
, and gives the page where consent can be given or revoked.
{ "tracking": "T", "same-party": [ "img.example2.com", "ourothesite.com" ], "compliance": [ "https://www.w3.org/2011/tracking-protection/drafts/tracking-compliance.html", "http://eur-lex.europa.eu/legal-content/en/ALL/?uri=CELEX:32009L0136" ], "qualifiers": "nt", "policy": "https://example2.com/privacy#purposes", "controller": [ "https://example1.com/about" ], "config": "https://example2.com/privacy/#give-or-revoke-consent" }If the request contains
DNT: 0
the TSR would not have a qualifiers property
,
signifying tracking for more than one or more of the permitted purposes i.e.
{ "tracking": "T", "same-party": [ "img.example2.com", "ourothesite.com" ], "compliance": [ "https://www.w3.org/2011/tracking-protection/drafts/tracking-compliance.html", "http://eur-lex.europa.eu/legal-content/en/ALL/?uri=CELEX:32009L0136" ], "policy": "https://example2.com/privacy#purposes", "controller": [ "https://example1.com/about" ], "config": "https://example2.com/privacy/#give-or-revoke-consent" }
Until the Consent API has wider support in browsers, the only compliant way for a site to indicate it has been given consent is to use the out-of-band consent (OOBC) mechanism.
It is important to do this because browser functionality designed to stop tracking may take tracking behaviour in the context of a DNT:1
request as refusal to respect the signal.
This could result in the site or third-party being blocked unnecessarily.
The TPE calls for the return of a TSV of C
to indicate OOBC but take care with how caching has been implemented.
If the existence of OOBC relies on a UID cookie, say for example if the user has given their consent for tracking when they logged in
which resulted in them receiving an persistent and unique authentication cookie, it would be impossible for the server to use the expiration caching model.
Caching would have to use the Vary
header to take cookie headers into account,
which would result in every request having to be responded to dynamically, there not being a way to use the Vary header for specific components
of the Cookie
request header.
It would still be possible to use the Validation caching model however, with the Tk: C
header indicating out-of-band consent
with a 304 "Not Modified" status code indicating a currently valid cache.
The expiration caching model can still be used with the Consent API because the DNT: 0
response can be cached (using Vary: DNT
)
Another way to deal with this issue is to use the Dynamic response Tk: ?status-id
The OOBC signal can then be coded as a C
value for the TSR tracking
property.
The W3C Tracking Compliance and Scope document
describes different tracking compliance processes for first-party resources, i.e. websites purposely visited by the user, from requests for resources meant only for embedded
third-party access. If a first-party website receives a DNT: 1
signal it can still collect and use tracking data but it must not share it with other parties
who have not been given user consent.
Even where EU law does not apply, the proscription of personal data sharing means that first-party sites must restrict their tracking activities
for DNT: 1
requests.
It is not possible to know if embedded third-parties have obtained user consent, unless that consent had been facilitated by the first-party.
For other situations, especially when the DNT compliance procedures of the third-party are unknown, it may incumbent on the first-party not to
insert third-parties who do not respect DNT.
This contingent insertion of third-parties can be achieved using a technique such as tag management, configured to load a restricted set of third-parties when DNT is set. Another recently standardised and open way is to insert a Content-Security-Policy response header. This header is supported by all the major browsers and can deliver policy directives such as lists of external origins allowed for particular mike types. If script attempts to lead resources not mentioned in the lists the browser will block them. As well as enabling sites to fully comply with DNT, this is also a great way to improve the security of first-party sites by restricting the parties that can be loaded onto users' browsers in the site's context. This technique could greatly diminish the possibility of malware delivery to browsers.
The Consent API, called the User-Granted Exception API in the other DNT documents, lets a site use JavaScript to register the user's consent to tracking in their browser, so that DNT: 0
will be sent in future requests to the site's resources.
The API is only available to script running in the top level browsing context, i.e. in the context of the first-party origin,
but consent can also be obtained for accesses to subdomains of its origin's main domain.
For example if a site is accessed via the URI https://www.example.com
, it can register consent for https://subdomain.example.com
As well as the top level domain, a site can register consent for its embedded third parties.
This "site specific" consent tells the browser to send
DNT: 0
headers when the third-parties are accessed as a result of loading the first-party site's content.
Some implementations of the API can specify a subset of the site's third-parties (known as "targets" of the API), while others may apply the consent to all of them,
called "site wide, site specific" consent.
A version of the API, called Web Wide consent, allows a site to specify that its origin, or a subdomain of its main origin, register consent
(i.e. DNT:0
is sent in requests to it) when it is accessed as a third-party on other sites.
A detailed description of the Consent API can be found in the Tracking Preference Expression document. The following shows the code for a simple situation where the user is presented with a form explaining the purposes of tracking, and asked to check a checkbox and click a Submit button if they agree.
Consent for tracking is registered if the checkbox is checked when the user clicks the submit button.
The consent applies to accesses to all the subdomains of the site's origin main domain,
applies when third-parties "socialwidgit.com" and "thirdparty-analytics.com" are accessed in the context of the site,
and will expire after 30 days. DNT: 0
will be sent in subsequent requests to the specified origins until the registered consent is revoked or expires.
If the checkbox is not checked when the user clicks the Submit button, the registered consent is revoked.
<form action="#" method="post" class="consentForm" id="consentForm"> <fieldset> <legend>Consent for Tracking</legend> <p> Information about the purposes of tracking. </p> <p> <label for="consent"> Please check the box to signify agreement.</label> </p> <input type="checkbox" name="consent" id="consent"> <p> <input type="submit" name="submit" value="Submit"> </p> </fieldset> </form> <script> var userForm = document.getElementById("consentForm"); var thirdParties = [ "socialwidget.com", "thirdParty-analytics.com" ]; userForm.addEventListener('submit',function(event) { var checkBox = this.elements['consent']; var dictionary = { siteName: "Example Site", explanationString: "tracking consent for the purpose of ... ", detailURI: "https://example.com/privacy-policy#tracking", maxAge: 60*60*24*30, // consent expires after 30 days domain: ".example.com", arrayOfDomainStrings: thirdParties }; if(checkBox.checked) { storeSiteSpecificTrackingException(dictionary); } else { removeSiteSpecificTrackingException(dictionary); document.cookie = "UID=opted-out"; // stop tracking e.g. set unique identifier // cookie to a low entropy value } }); </script>