In Europe individuals visiting website are protected by law from being profiled without their consent. This legislation has been reinforced by the the Data Privacy Directive which requires that websites only store data in user-agents if the user has given their consent or the data is strictly necessary for the delivery of a requested service.

Web technology already exists so that website publishers can obtain consent for their own website and retain it for future visits. A visitor can give their informed consent through interaction with a suitable UI and an HTTP cookie encoded so on subsequent visits their agreement can be signaled back to the server. The mechanism is robust because if a user deletes their cookies the no-track default  means the server must request consent again before tracking. Consent can be automatically revoked after a sunset period using the standard cookie expiry feature and signaled to other domains controlled by the same party using established cross-domain signaling techniques.

Unfortunately this cannot be used to ensure consent is honoured by servers of embedded third-party content. HTTP cookies cannot be accessed in other domains, so another form of consent signaling is needed, and even then there is often no contractual agreement that a signal will be adequately honoured by the other parties. A publisher may wish to embed content from parties under a different jurisdiction which does not require tracking consent or with which they have not agreed suitable contractual terms. The extensive re-engineering of the site needed to contingently add third-party elements only when user consent has been given is impractical in many situations.

The DNT header signal is sent to all parties so it can be used to signal third-party servers. The negative form of it, or the DNT User Granted Exception, can be used as a cross-domain consent signal, while the positive form could signal either that the user has enabled the DNT general preference or  the first-party site is in a jurisdiction that requires consent and it has not been given. Publishers of first-party sites need a mechanism to control the DNT signal irrespective of whether the general exception has been set.

In addition to the ability to control the DNT signal there needs to be a way to ensure it will be honoured by the targeted third-party servers. In many cases there will be no commitment given by third-party content servers that they will honour it in a way that lets the first-party comply with its own legal requirements. The first-party may wish to keep these elements for its users that have given consent and not have to limit their use of third-party elements to those entities that have given contractual commitments.

The following is a draft of an extensible API that can give first-party sites the level of  control needed over the DNT signal sent to its own and its embedded third-party servers. First-party sites can use this API to differentially signal user consent for different pages on the site, for example profiling could be enabled on a store checkout page but not on others. It can make the user-agent signal DNT to the site's embedded third-party servers when the user has not set the general preference and can cause the DNT exception signal to be sent, with an automatic revocation period,  to signal user consent for tracking.

Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

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

Introduction

Web technology already exists so that website publishers can obtain consent for their own website and retain it for future visits. A visitor can give their informed consent through interaction with a suitable UI and an HTTP cookie can be encoded so on subsequent visits their agreement can be signaled back to the server. The mechanism is robust because if a user deletes their cookies the no-track default means the server must request consent again. Consent can be automatically revoked after a sunset period using the standard cookie expiry feature and can be signaled to other domains controlled by the same party using established cross-domain signaling techniques.

Unfortunately this technique will not work for embedded third-parties because cookies in the scope of other domains cannot be accessed. If the DNT header can be edited then the user granted exception (DNT:0) can be used to signal a user’s tracking consent and DNT:1 can indicate that consent is required but has not been given.

First-party publishers are not always sure that servers targeted by their third-party content will honour the signal preference. Publishers often embed third-party content without the appropriate contractual agreement to ensure the preference will be honoured. The third-party could be in a jurisdiction where they can ignore the absence of a signal, for example the DNT general preference being unset, whereas the first-party may be required to assume this means the user must not be tracked.

It should be possible for the server to enlist the user-agent in order to ensure the preference is honoured by getting it to block HTTP requests to less trusted third-party resources.

First-party sites communicate their requirements to a user-agent by loading JavaScript which on execution calls the setTrackingPolicyActions function. Invoking setTrackingPolicyActions allows sites to register a set of Rules, matching specific URIs accessed during or after the site's pages have been rendered, and a list of Commands indicating Tracking Policy Actions which are all executed just before a matched HTTP request is sent. Actions and Rules are stored in a site-specific repository keyed to the top-level origin. The first call to setTrackingPolicyActions after a document is rendered replaces any Tracking Policy Actions previously stored with new ones and each subsequent call adds to them.

Before a user-agent sends an HTTP request the URI is checked against any Rules stored in the repository pointed to by the current top-level origin. Because they are accessed in the reverse order to how they were added the last added match takes precedence, and all the Tracking Action Commands associated with that match are invoked. Unless a block  command is present the HTTP request is then sent with the appropriate DNT header value. If a block command is present and the URI represents a third-party resource the request is not sent and a 409 Status Code is assumed to have been returned.

Tracking Policy Actions can:

Action Commands can have an optional additional string that can qualify the action. The API can be extended in the future by defining new commands.

Repositories are persisted in a user-agent object stored in a database keyed to the site or its top-level origin. To simplify language used in this API specification, we define four terms:

For instance, if the document at http://web.exnews.com/news/story/2098373.html references the resources http://exnews.analytico.net/1x1.gif and http://widgets.exsocial.org/good-job-button.js, the top-level origin is web.exnews.com; exnews.analytico.net and widgets.exsocial.org are both targets.

Third-Party URIs

A third-party URI [[!URI]] is a URI with a (second-level) domain name that differs from that of the top-level containing document. When a user agent is sending an HTTP request to a URI, the server sends back a response possibly containing further URIs. Among these URIs, those with a different second-level domain name are considered, in that document, third-party URIs.

Similarly if executing JavaScript causes a HTTP request with a different second-level domain name to be sent, this is also a third-party request.

A user agent must evaluate any URIs that indicate a sub-document—such as an frame or any URIs defined in any sub-documents—as third-party with respect to the topmost document.

A third-party download is any potential HTTP download request to a third-party URI.

Unconditional Third-Party URIs

This is a Third-Party URI that is accessed without explicit user action. For example if an image tag is referenced during the rendering of an HTML page then the URI referenced in the src attribute is an unconditional third-party. In contrast, a Third-Party URI referenced by the href attribute of an anchor tag, or by JavaScript in the context of an onclick event handler, would not classed as conditional (on user interaction).

Site-specific Repositories

Site-specific Repositories are user-agent based objects that store data that is local to a particular domain origin. For example privacy related preferences, to be acted upon by user-agents when users visit particular websites, would be stored here. Although some privacy data related to tracking may be held globally within the user-agent, for instance the Do-Not-Track general preference, other data is specific to particular websites and the set of third-party resources embedded within them. An example of this is the Do-Not-Track User Granted Exception which registers a user's agreement to send a Consent signal (or DNT:0 header) in HTTP requests in the context of a particular website. A user may agree to have unique identifying data gathered by some third-parties referenced by a site and not others, and this can be recorded in the Repository.

Repositories contain a set of matching Rules which are used to select URIs referencing third-party content. Each Rule is linked to a set of Action Commands that are executed just before the HTTP request to a matched URI is sent. Each Command initiates an action such as changing the preference value in a DNT header to 0 or 1, or perhaps to skip sending the request at all.

Repositories are edited by a JavaScript API executed by script executed in the context of the associated top-level document. Each call to the API supplies a JavaScript Array of strings representing Rules, and a string containing a comma-separated list of Action Commands. Each Rule is a string that can select URIs using a matching technique similar to that that used for web-wide Tracking Selection Lists.

Each invocation of the JavaScript API will result in a single current state of the Site-specific Repository, with a single list of distinct Rules and associated Action Commands.

Processing Repositories when Tracking Selection Lists are enabled

Site-specific Repositories are processed in the context of their associated top-level document origin and are processed before any web-wide Tracking Selection Lists. If a third-party URI is referenced by a rule with an allow command then the HTTP request is transmitted and any web-wide Tracking Selection Lists are ignored. If the URI is referenced by a rule associated with a block command then an HTTP request for the resource is not sent. If the URI is not referenced in the site-specific list then it is checked against the web-wide selection lists, if any exist.

JavaScript API

sequence<DOMString>? setTrackingPolicyActions()

This function is used to set up Tracking Policy Commands for the implicit top-level document origin host.

At the first invocation of this method in a document any existing Tracking Policy Commands  in the Repository of the referenced domain are deleted.

If the actions parameter is not present, null or empty then no Tracking Policy Commands are stored but the returned JavaScript Array of strings will indicate the DNT header that will be sent for matched URIs.

Rules will be immediately used to apply Tracking Policy Commands to URIs subsequently referenced in the document.

If the call fails the NavigatorDoNotTrackException exception is thrown with the code attribute giving the error code.

If the call succeeds it returns an Array of strings representing the DNT preference and qualifiers that will be set in subsequent HTTP requests to each matching URI.

sequence<DOMString> arrayOfRules
An array of rules, each of which can contain one or more wildcard characters "*" which must match 0 or more of any character, and are "greedy" meaning they will match as much text as possible. The rules are matched against any requests to URIs sent in the context of the implicit top-level document origin. Matched URIs can reference third-party or first-party resources. For the first matched URIs, the specified action commands are executed before the request is sent. If a rule string starts with a "/" character it is assumed to refer to a first-party page and the top-level document origin host will be prepended to it. Characters in a URI up to and including any "://" string are ignored when matching so that the scheme name does not have to be included in a rule.
optional DOMString? actions
A string containing a comma separated list of zero or more tracking action commands. Each command is composed of a command string optionally followed by '=' and a qualifier string. User-agents MUST implement the following commands:
command qualifier description
set-dnt string prefixed by 0 or 1 set the DNT header value for matched third-party requests to be equal to the qualifier value.
reset-dnt reset the DNT header value for matched third-party requests to be the same as the DNT general preference.
sunset expires-datetime If the current date and time is after expires-datetime the DNT header is reset to the general preference. expires-datetime is formatted according to [RFC2616, Section 3.3.1]. This action command is executed after all others irrespective of their order in the string.

User-agents MAY implement the following commands:

block blocktype If blocktype is absent or "0" this is the block action defined for site-specific Tracking Selection Lists i.e. third-party requests are skipped for matching URIs. Other values of blocktype are reserved for additional blocking algorithms that could be implemented by user-agents in the future. If a user-agent implements the block command it MUST support the default blocking action.
unblock Cancel any previous block command for matched URIs.
allow Cancel any previous block command for matched URIs and override any matched Rules in Tracking Protection Lists.
const unsigned short ERRORBP = 1
bad parameter
unsigned short code

Examples

Example 1

Here script checks for a DNT=1 signal. If it is set a block rule is set for non-trusted third parties that may not honour the DNT signal. This is done here by setting block for all third parties and setting an allow rule for particular trusted third-parties.

The RegisterConsent function could for example be attached to a "Consent" button in a form with the onsubmit attribute. When triggered it removes blocking rules for all third-parties and its own pages, and sets the DNT UGE.

The RevokeConsent function, perhaps triggered by a "Revoke" link with an onclick handler, restores the DNT signal to the general preference, revokes the Consent signal and restores the blocking rule for the untrusted third-parties.

<script type="text/JavaScript">

if( NavigatorDoNotTrack.requestDNTStatus()!=null && NavigatorDoNotTrack.requestDNTStatus().indexOf("1")==0 )
{ 
   NavigatorDoNotTrack.setTrackingPolicyActions(["*"], "block");
   NavigatorDoNotTrack.setTrackingPolicyActions(["trustedthirdparty.com*","another.ttp.com/*.js"], "allow");
}

function RegisterConsent()
{
   NavigatorDoNotTrack.setTrackingPolicyActions( ["*"],"allow, set-dnt=0");
} function RevokeConsent() {    NavigatorDoNotTrack.setTrackingPolicyActions(["*"], "reset-dnt, block");    NavigatorDoNotTrack.setTrackingPolicyActions(["trusted.tp.com*","another.ttp.com/*.js"], "unblock"); } </script>

Example 2

Here the API is used to register a Consent signal (a DNT UGE) for a first-party checkout page. The site targets European citizens so consent must be indicated explicitly, meaning the absence of a DNT header is equivalent to DNT being set. The checkout page is only accessible by a POST request, as a result of the user clicking a form "Submit" button and, because the identifiers the checkout page uses supports a service specifically requested by the user, explicit consent for this action does not need to be obtained. If the user indicates consent for tracking the RegisterConsent event is executed causing the DNT:0 signal to be sent for all requests for first-party and embedded third-party resources, with an expiry date set so consent will be automatically revoked after a sunset period.

<script type="text/JavaScript">

if( NavigatorDoNotTrack.requestDNTStatus()==null || NavigatorDoNotTrack.requestDNTStatus().indexOf("1")==0  )
{
   NavigatorDoNotTrack.setTrackingPolicyActions(["*"], "block");
   NavigatorDoNotTrack.setTrackingPolicyActions(["trusted.tp.com*","another.ttp.com/*.js"], "allow");
   NavigatorDoNotTrack.setTrackingPolicyActions(["/checkout.htm"], "set-dnt=0");
}

function RegisterConsent()
{
   NavigatorDoNotTrack.setTrackingPolicyActions( ["*"],"unblock, set-dnt=0, sunset=Tue,01-Jan-2013 00:00:00 GMT");
} function RevokeConsent() {    NavigatorDoNotTrack.setTrackingPolicyActions(["*"], "reset-dnt, block"); } </script>

Augmented Backus-Naur Form of protocol elements

The following is the Augmented Backus-Naur Form [[!ABNF]] of a Rule.

rule            =     1*WSP wcstring [substring-exp]
substring-exp   =     1*WSP wcstring
wcstring        =     1*(ALPHA/DIGIT/"."/"*")

The following is the Augmented Backus-Naur Form [[!ABNF]] of a Tracking Action Command Set.

commandset      =     command 0*("," command)
command         =     action ["=" qualifier ]
action          =     1*WSP string
qualifier       =     1*WSP wcstring
string          =     1*(ALPHA/DIGIT/".")

The following is the Augmented Backus-Naur Form [[!ABNF]] of the DNT header field.

Glossary

Issues

Acknowledgements