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.

Introduction

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.

Implementing Do Not Track

Implementation can be broken down to 5 main functional areas.

  1. The site must contain a reference to a Tracking Status Resource (TSR) that can give user agents information about the site's tracking behaviour, if any.
  2. Unless the site does not ever track users, each incoming request should be checked to see if it contains a 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.
  3. Action taken depending on the deemed tracking preference.
    • If the request signifies an opted-in user, tracking data can be used without restriction, although there may be implicit restrictions due to local law, or dependent on the information given to the user when they opted-in.
    • If the request is an opted-out one and no exemption or alleviation applies, then the tracking data must not be retained. This normally means that UID cookies should not be placed (and, at least in Europe, should be deleted if they are already there), JavaScript used for fingerprinting should not be loaded, and any user identifying data in logs (such as IP addresses) deleted or otherwise permanently de-identified. If personal data must be collected for one of the permitted uses allowed by local laws, or in Europe is "strictly necessary to fulfil a service requested by the user" or for "the sole purpose of carrying out the transmission of a communication", then the data can be retained, but only for the particular claimed purpose.
  4. A site's tracking behaviour in the context of a particular request should be indicated in the Tracking Status Value (TSV). The TSV can be communicated in various ways.
    • If its value never changes, i.e. does not depend on individual HTTP requests, it can be recorded in the Tracking property of the TSR.
    • If the value can change for individual requests then the Tk response header must be used. Either:
      • The Tracking property can be set to ? (Dynamic) and the TSV delivered in the value of the Tk response header, or:
      • A sub-tree of Tracking Status Resources can be maintained and the particular one that applies in the current request indicated using the status-id mechanism.
  5. If the site uses the user's consent to enable tracking then this can best be achieved by informing the user of the purpose and retention limits etc., then, when they have given their consent by checking a box or clicking a button, using the DNT Consent API to register the fact in the browser. As the script API is not currently supported by some browsers an out-of-band technique, probably using cookies, can be used instead. In this case a Tracking Status Value of C must be communicated in the Tk response header or in the tracking property of a request specific TSR.

DNT detection via header detection or script

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.

Tracking Status Resource

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.

The tracking string

This 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.

The compliance array

This 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,

The policy URI

This 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.

The config URI

This 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.

The 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.

The 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.

The 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

TSR Examples

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"
    }
    

Out-of-band consent and caching

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.

Permitted uses, exemptions and derogations.

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.

Using the Consent API

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>