### Tracking Status Resource ### {#status-resource} #### Summary #### {#status-resource-summary}
This summary is not normative.
This section explains how to discover a server's tracking practices. It defines the , a cacheable document that expresses a sever's tracking practices, and explains its syntax, function, and meaning. This section includes a technical description of the tracking status reasource, instructions for its use, a discussion caching practices, and a protocol for notifying users of real-time changes to it. #### Resource Definition #### {#status-resource-defn} An origin server MUST provide a tracking status resource at the well-known identifier [[RFC5785]] ~~~ /.well-known/dnt ~~~ (relative to the URI of that origin server) for obtaining information about the potential tracking behavior of services provided by that origin server. A tracking status resource MAY be used for verification of DNT support, as described in . A valid retrieval request (e.g., a `GET` in [[!HTTP11]]) on the well-known URI MUST result in 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. A user agent MAY consider failure to provide access to such a representation equivalent to the origin server not implementing this protocol. The representation might be cached, as described in . If an origin server contains multiple services that are controlled by distinct parties or that might have differing behavior or policies regarding tracking, then it MAY also provide a space of well-known resources for obtaining information about the potential tracking behavior of each specific service. This parallel tree of resources is called the tracking status resource space. The tracking status resource space is defined by the following URI Template [[URI-TEMPLATE]]: ~~~ /.well-known/dnt{+pathinfo} ~~~ where the value of `pathinfo` is equal to the path component [[RFC3986]] of a given reference to that origin server, excluding those references already within the above resource space. For example, a reference to ~~~ http://example.com/over/here?q=hello#top ~~~ MAY have a corresponding tracking status resource identified by ~~~ http://example.com/.well-known/dnt/over/here ~~~ Resources within the tracking status resource space are represented using the same format as a site-wide tracking status resource. All requests for well-known URIs defined here MUST NOT be tracked, irrespective of the presence, value, or absence of a DNT header, cookies, or any other information in the request. In addition, all responses to requests on a tracking status resource, including redirected requests, MUST NOT include `Set-Cookie` or `Set-Cookie2` header fields [[COOKIES]] and MUST NOT include content that would have the effect of initiating tracking beyond what is already present for the request. A user agent SHOULD ignore or treat as an error any `Set-Cookie` or `Set-Cookie2` header field received in such a response. #### Tracking Status Representation #### {#status-representation} The representation of a tracking status resource SHALL be provided in the "application/json" format [[!RFC4627]] and MUST conform to the ABNF in . The following is an example tracking status representation that illustrates all of the fields defined by this specification, most of which are optional.
{
 "path": "/",
 "tracking": true,
 "received": "1",
 "response": "t1",
 "same-site": [
 "example.com",
 "example_vids.net",
 "example_stats.com"
 ],
 "partners": [
 "api.example-third-party.com"
 ],
 "policy": "/tracking.html",
 "edit": "http://example-third-party.com/your/data",
 "options": "http://example-third-party.com/your/consent"
}
A tracking status representation consists of a single status-object containing members that describe the tracking status applicable to this user agent's request. If the status-object has an OPTIONAL path member, then this object describes the tracking status for the entire space of resources that share the same path prefix as the value of path. The user agent MUST interpret the path value relative to the originally referenced resource, not the resource where it obtained the tracking status representation. For the site-wide tracking status resource, the presence of a path member with a value of "/" indicates that this status-object applies for the entire origin server of the originally referenced resource. If the originally referenced resource's path component does not share the same prefix as the value of path, or if the path member is absent, then the tracking status for the referenced resource MAY be obtained via a request on the corresponding tracking status resource space. A status-object MUST have a member named tracking with a boolean value. A value of false indicates that the corresponding resources do not perform tracking as it is defined by [[!TRACKING-COMPLIANCE]]. A value of true indicates that the corresponding resource performs tracking and claims to conform to all tracking compliance requirements applicable to this site. For example, the following demonstrates a minimal tracking status representation that is applicable to any resource that does not perform tracking.
{"tracking": false}
The following status-object would indicate that the entire site does not perform tracking.
{"path": "/", "tracking": false}
If tracking is true, the status-object MUST include two additional members, named received and response, and MAY include other members as described below. The received member MUST have either a string value equal to the DNT-field-value received in that request or the value null if no DNT-field-value was received. Any invalid characters received in the DNT-field-value MUST be elided from the string value to ensure that invalid data is not injected into the JSON result. The response member MUST have a string value that indicates the status of tracking applicable specifically to this user in light of the received DNT-field-value. The string value begins with "t" (tracking) or "n" (not tracking) and MAY be followed by any number of alphanumeric characters that indicate reasons for that status. The valid characters and their meanings are described in . An OPTIONAL member named same-site MAY be provided with an array value containing a list of domain names that the origin server claims are the same site, to the extent they are referenced on this site, since all data collected via those references share the same data controller. An OPTIONAL member named partners MAY be provided with an array value containing a list of domain names for third-party services that might track the user as a result of using this site and which do not have the same data controller as this site. An OPTIONAL member named policy MAY be provided with a string value containing a URI-reference to a human-readable document that describes the tracking policy for this site. The content of such a policy document is beyond the scope of this protocol and only supplemental to what is described by this machine-readable tracking status representation. An OPTIONAL member named edit MAY be provided with a string value containing a URI-reference to a resource intended to allow a tracked user agent to review or delete data collected by this site, if any such data remains associated with this user agent. The design of such a resource and the extent to which it can provide access to that data is beyond the scope of this protocol. An OPTIONAL member named options MAY be provided with a string value containing a URI-reference to a resource intended to allow a user agent to opt-in, opt-out, or otherwise modify their consent status regarding data collection by this site. The design of such a resource and how it might implement an out-of-band consent mechanism is beyond the scope of this protocol. Additional extension members MAY be provided in the status-object to support future enhancements to this protocol. A user agent SHOULD ignore extension members that it does not recognize. Note that the tracking status resource space applies equally to both first-party and third-party services. An example of a third-party tracking status is
{
 "tracking": true,
 "received": "1",
 "response": "n",
 "policy": "/privacy.html",
 "edit": "/your/data",
 "options": "/your/consent"
}

ISSUE-47: Should the response from the server indicate a policy that describes the DNT practices of the server?
[PENDING REVIEW] The tracking status resource is a machine-readable policy and provides a mechanism for supplying a link to a human-readable policy.

ISSUE-61: A site could publish a list of the other domains that are associated with them
[PENDING REVIEW] The same-site and partners members provide a means to list first-party and third-party domains, respectively.

ISSUE-124: Alternative DNT implementations that replace HTTP headers with something else
[PENDING REVIEW] The tracking status resource minimizes bandwidth usage because only a small proportion of user agents are expected to perform active verification, status would only be requested once per site per day, and the response can be extensively cached.

#### Using the Tracking Status #### {#using-tracking-status} A key advantage of providing the tracking status at a resource separate from the site's normal services is that the status can be accessed and reviewed prior to making use of those services and prior to making requests on third-party resources referenced by those services. In addition, the presence (or absence) of a site-wide tracking status representation is a means for testing deployment of this standard and verifying that a site's claims regarding tracking are consistent with the site's observed behavior over time. A user agent MAY check the tracking status for a given resource URI by making a retrieval request for the well-known address `/.well-known/dnt` relative to that URI. If the response is an error, then the service does not implement this standard. If the response is a redirect, then follow the redirect to obtain the tracking status (up to some reasonable maximum of redirects to avoid misconfigured infinite request loops). If the response is successful, obtain the tracking status representation from the message payload, if possible, or consider it an error. Once the tracking status representation is obtained, parse the representation as JSON to extract the Javascript status-object. If parsing results in a syntax error, the user agent SHOULD consider the site to be non-conformant with this protocol. If the status-object does not have a member named path or if the value of path is not "/" and not a prefix of the path component for the URI being checked, then find the service-specific tracking status resource by taking the template `/.well-known/dnt{+pathinfo}` and replacing `{+pathinfo}` with the path component of the URI being checked. Perform a retrieval request on the service-specific tracking status resource and process the result as described above to obtain the specific tracking status. The status-object is supposed to have a member named tracking with a boolean value. If the value is false, then no tracking is performed for the URI being checked. If the value is true, then examine the member named received to verify that the DNT header field sent by the user agent has been correctly received by the server. If the received value is incorrect, there may be an intermediary interfering with transmission of the DNT request header field. If the received value is correct, then examine the member named response to see what the origin server has claimed regarding the tracking status for this user agent in light of the received DNT-field-value. If the first character of the response value is "n", then the origin server claims that it will not track the user agent for requests on the URI being checked, and for any URIs with a path prefix matching the path member's value, for at least the next 24 hours or until the Cache-Control information indicates that this response expires, as described below. If the first character of the response value is "t", then the origin server claims that it might track the user agent for requests on the URI being checked, and for any URIs with a path prefix matching the path member's value, for at least the next 24 hours or until the Cache-Control information indicates that this response expires. The remaining characters of the response value might indicate reasons for the above choices or limitations that the origin server will place on its tracking. The others members of the status-object MAY be used to help the user agent differentiate between a site's first-party and third-party services, to provide links to additional human-readable information related to the tracking policy, and to provide links for control over past data collected or over some consent mechanism outside the scope of this protocol. #### Tracking Status Caching #### {#status-caching} If the tracking status is applicable to all users, regardless of the received DNT-field-value or other data received via the request, then the response SHOULD be marked as cacheable and assigned a time-to-live (expiration or max-use) that is sufficient to enable shared caching but not greater than the earliest point at which the service's tracking behavior might increase. For example, if the tracking status response is set to expire in seven days, then the earliest point in time that the service's tracking behavior can be increased is seven days after the policy has been updated to reflect the new behavior, since old copies might persist in caches until the expiration is triggered. A service's tracking behavior can be reduced at any time, with or without a corresponding change to the tracking status resource. If the tracking status is only applicable to all users that have the same DNT-field-value, then either the response MUST include a Cache-Control header field with one of the directives "no-cache", "no-store", "must-revalidate", or "max-age=0", or the response MUST include a Vary header field that includes "DNT" in its field-value. If the tracking status is only applicable to the specific user that requested it, then the response MUST include a Cache-Control header field with one of the directives "no-cache", "no-store", "must-revalidate", or "max-age=0". Regardless of the cache-control settings, it is expected that user agents will check the tracking status of a service only once per session (at most). A public Internet site that intends to change its tracking status to increase tracking behavior MUST update the tracking status resource in accordance with that planned behavior at least twenty-four hours prior to activating that new behavior on the service. #### Interactive Status Changes #### {#status-interaction} It is anticipated that there may exist interactive mechanisms for expressing, configuring, or otherwise changing privacy preferences, such as at the URIs expressed in the `edit` or `options` fields. In the event that a user makes an interactive preference change -- such as opting into or out of some form of data collection -- the tracking status resource that their user-agent has cached may become obsolete. In order to ensure that user-agents always have a valid tracking status resource, we provide an HTTP response header which servers can use to signal such interactive changes to the user-agent.

ISSUE-107: Exact format of the response header?
[PENDING REVIEW] See the proposal in this section.

ISSUE-120: Should the response header be mandatory (MUST) or recommended (SHOULD)
[PENDING REVIEW] See the proposal in this section.

If a request causes the most recent tracking status resource served to that user to become invalid, the response to that request MUST include a `Tk` response header with the `update-needed` flag. A server MAY send a `Tk` header in response to other requests, but MUST NOT include the `update-needed` flag. The header is defined as follows:
Tk-Response = "Tk: [CFWS] tracking [CFWS] [update-needed]
tracking = "0" / "1"
update-needed = "u"
tracking has the same meaning in the `Tk` header as in the tracking status resource. A `Tk` header tracking value of `1` corresponds to a tracking status resource tracking value of `true`, and vice versa. If the update-needed flag is included, this indicates that the tracking status resource has changed. If the user agent has a cached tracking status resource for this domain, it MUST be updated. #### Tracking Status Response Values #### {#status-reponse-values} | reasons | meaning |:-------:|---------------------------------------| | 1 | Intended for use as a first-party | | 3 | Compliant with third-party definition | | s | Service provider | | c | Prior consent received | | a | Advertising audits | | q | Advertising frequency capping | | f | Fraud prevention | | g | Regional/geographic constraints | | r | Referral information | There are two classes of response values: party signifiers (`1`, `3`, & `s`), and use tokens (all the others). Tracking status resources MUST NOT contain more than one one party signifier, but MAY contain any number of use tokens. If the **first party** signifier (`1`) is present, this tracking status resource asserts that: - all the resources to which it refers are intended only to be used in a first party context, and - this party will process this request according to the specifications for 1st parties in [TRACKING-COMPLIANCE]. If the **service provider** signifier (`s`) is present, this tracking status resource asserts that: - this resource is intended to be used in the context of third party acting as an outsourced service provider for a first party, and - this party will process this request according to the exemption for a third party acting as an outsourced service provider for a first party, as described in [TRACKING-COMPLIANCE]. If the first party or service provider signifier is present, any use tokens are only informational: the party does not assert that it is only doing the things. If the **third party** signifier (`3`) is present, this tracking status resource asserts that: - this party will process this request according to the specification for 3rd parties in [TRACKING-COMPLIANCE], and - all the purposes for which data is collected or used are specified in the following use tokens. #### Tracking Status ABNF #### {#status-abnf} The representation of a site's machine-readable tracking status MUST conform to the following ABNF for status-object, except that the members within each member-list MAY be provided in any order.
status-object = begin-object member-list end-object
member-list = [ path ns path-v vs ]
 tracking ns tracking-v
 [ vs received ns received-v ]
 [ vs response ns response-v ]
 [ vs same-site ns same-site-v ]
 [ vs partners ns partners-v ]
 [ vs policy ns policy-v ]
 [ vs edit ns edit-v ]
 [ vs options ns options-v ]
 *( vs extension ) 
path = %x22 "path" %x22
path-v = string ; URI absolute-path 
tracking = %x22 "tracking" %x22
tracking-v = true / false 
received = %x22 "received" %x22
received-v = null / string 
response = %x22 "response" %x22
response-v = %x22 r-codes %x22 
r-codes = ("t" / "n") *reasons 
reasons = "1" ; first-party
 / "3" ; third-party
 / "s" ; service provider
 / "c" ; prior consent
 / "a" ; advertising audits
 / "q" ; frequency capping
 / "f" ; fraud prevention
 / "g" ; geographic/regional compliance
 / "r" ; referrals
 / ALPHA / DIGIT ; TBD 
same-site = %x22 "same-site" %x22
same-site-v = array-of-strings 
partners = %x22 "partners" %x22
partners-v = array-of-strings 
policy = %x22 "policy" %x22
policy-v = string ; URI-reference 
edit = %x22 "edit" %x22
edit-v = string ; URI-reference 
options = %x22 "options" %x22
options-v = string ; URI-reference 
extension = object 
array-of-strings = begin-array
 [ string *( vs string ) ]
 end-array 
ns = <name-separator (:), as defined in [[!RFC4627]]>
vs = <value-separator (,), as defined in [[!RFC4627]]> 
begin-array = <begin-array ([), as defined in [[!RFC4627]]>
end-array = <end-array (]), as defined in [[!RFC4627]]>
begin-object = <begin-object ({), as defined in [[!RFC4627]]>
end-object = <end-object (}), as defined in [[!RFC4627]]>
object = <object, as defined in [[!RFC4627]]>
string = <string, as defined in [[!RFC4627]]>
true = <true, as defined in [[!RFC4627]]>
false = <false, as defined in [[!RFC4627]]>
null = <null, as defined in [[!RFC4627]]>