Intelligent Tracking Prevention 2.0

Today we’re happy to bring you Intelligent Tracking Prevention 2.0, or ITP 2.0. It builds upon ITP 1.0, which we released last year, and ITP 1.1, which was released in March, adding the Storage Access API.

Removal of the 24 Hour Cookie Access Window

ITP 2.0, as opposed to earlier versions, immediately partitions cookies for domains determined to have tracking abilities. The previous general cookie access window of 24 hours after user interaction has been removed. Instead, authenticated embeds can get access to their first-party cookies through the Storage Access API. The API requires that the user interacts with the embedded content.

0 days: Cookies are partitioned and not persisted in 3rd-part contexts. | 30 days: Existing cookies are purged. New cookies are blocked. | Days of use after the most recent interaction with the website or successful use of the Store Access API.

video.example offers an ad-free subscription service and has many of its videos embedded on other websites. ITP classifies video.example as having tracking abilities and therefore partitions its cookies. This is a timeline of how ITP might work for video.example:

  1. Day 1: The user logs in to video.example which updates video.example’s user interaction timestamp.
  2. Day 22: The user clicks to watch a video.example clip on news.example and the embedded video calls the Storage Access API. ITP notes that the user has not previously granted video.example access to its first-party cookies on news.example and thus prompts the user. The user grants storage access and video.example’s user interaction timestamp is updated.
  3. Day 26: The user clicks to watch another video.example clip on news.example and the video.example embed calls the Storage Access API. ITP notes that the user has previously granted video.example access to its first-party cookies on news.example and thus provides access without a prompt and updates video.example’s user interaction timestamp.
  4. Day 55: The user interacts with video.example as first party website which updates video.example’s user interaction timestamp.
  5. Day 76: The user clicks to watch a video.example clip on blog.example and the video.example embed calls the Storage Access API. ITP notes that the user has not previously granted video.example access to its first-party cookies on blog.example and thus prompts the user. The user grants storage access and video.example’s user interaction timestamp is updated.
  6. Day 80-82: The user doesn’t use Safari which means that these three days do not count towards the 30 days before website data purge.
  7. Day 109: video.example’s cookies, website data, and granted storage access entries are purged as a result of 30 days of Safari usage without an update to video.example’s user interaction timestamp.
Developer Advice

If you are a provider of authenticated third-party content, you should adopt the Storage Access API. If your website relies on a third party domain for user authentication, your authentication provider should adopt the Storage Access API or transfer authentication tokens to you in URLs.

User Prompt For the Storage Access API

ITP 2.0 adds a prompt to WebKit’s implementation of the Storage Access API. If the user allows access, their choice is persisted. If the user declines, their choice is not persisted which allows them to change their mind if they at a later point tap a similar embedded widget that calls the Storage Access API.

As an example, video.example may have an ad-free subscription service and have many of its videos embedded on other websites. ITP will thus classify video.example as having tracking abilities and partition its cookies. When the user taps or clicks to play a clip embedded on news.example, video.example can call the Storage Access API to check whether the user is a subscriber. The user will be prompted if they have not explicitly allowed access under news.example previously.

Storage Access API prompt
Storage Access API Prompt

This prompt provides users with a way to show intent (the tap/click enabling the API call) and provide consent (“Allow” in the prompt). If the user chooses “Allow,” their choice is persisted and subsequent calls to the Storage Access API by video.example embeds on news.example do not trigger a prompt. Instead a tap or click on the embed is enough for a successful API call. As always, ITP considers the eTLD+1 to be the “party,” so a user “Allow” for under will be valid for video.example and any of its subdomains under news.example or any of its subdomains.

Successful use of the Storage Access API now counts as user interaction with the third-party and refreshes the 30 days of use before ITP purges the third-party’s website data. By successful use we mean the user was either prompted right now and chose “Allow,” or had previously chosen “Allow.” The fact that successful Storage Access API calls now count as user interaction allows users to stay logged into services they rarely use as first party but keep using as embedded third parties.

Finally, we received developer feedback (thank you), saying it should be possible to do a popup should storage access be granted but it turns out the user is not logged in. Our original version of the Storage Access API would consume the user gesture and thus require another tap or click to do a login popup. Now, the third-party embed is allowed to do a popup in the resolve scope of the returned promise, like so:

function makeRequestWithUserGesture() {
  var promise = document.requestStorageAccess();
    function () {
      // Storage access was granted.
      // Check whether the user is logged in.
      // If not, do a popup to log the user in.
    function () {
      // Storage access was denied.
<button onclick="makeRequestWithUserGesture()">Play video</button>
Developer Advice

We encourage you to adopt the Storage Access API if you provide authenticated embeds. The API’s prompt provides you with a way to extend your users’ authenticated sessions if ITP has classified your domain as having the ability to track the user. If ITP classifies your domain and you don’t adopt the API, your domain will be permanently blocked from accessing its first-party cookies in a third-party context.

Temporary Compatibility Fix: Automatic Storage Access for Popups

Many federated logins send authentication tokens in URLs or through the postMessage API, both of which work fine under ITP 2.0. However, some federated logins use popups and then rely on third-party cookie access once the user is back on the opener page. Some instances of this latter category stopped working under ITP 2.0 since domains with tracking abilities are permanently partitioned.

Our temporary compatibility fix is to detect such popup scenarios and automatically forward storage access for the third party under the opener page. Since popups require user interaction, the third party could just as well had called the Storage Access API instead.

Developer Advice

If you provide federated login services, we encourage you to first call the Storage Access API to get cookie access and only do a popup to log the user in or acquire specific consent. The Storage Access API provides a better user experience without new windows and navigations. We’d also like to stress that the compatibility fix for popups is a temporary one. Longterm, your only option will be to call the Storage Access API.

Protection Against First Party Bounce Trackers

ITP 2.0 has the ability to detect when a domain is solely used as a “first party bounce tracker,” meaning that it is never used as a third party content provider but tracks the user purely through navigational redirects.

Say the user clicks on a news.example link on the social.example website. Instead of navigating them straight to their destination news.example, they are rapidly navigated through trackerOne.example and trackerTwo.example before reaching news.example. Those two tracker domains can store information about the user’s browsing history in first party storage and cookies. ITP 2.0 detects such tracking behavior and treats those domains just like any other tracker, i.e. purges their website data.

First-party cookie bounce diagram

Protection Against Tracker Collusion

Through our research, we found that cross-site trackers help each other identify the user. This is basically one tracker telling another tracker that “I think it’s user ABC,” at which point the second tracker tells a third tracker “Hey, Tracker One thinks it’s user ABC and I think it’s user XYZ.” We call this tracker collusion, and ITP 2.0 detects this behavior through a collusion graph and classifies all involved parties as trackers.

Cross-site tracker collusion diagram

In the graph above, as soon as trackerSix.example is classified by ITP, all the domains that have redirected to trackerSix.example get classified too. That’s trackerTwo.example, trackerThree.example, and trackerFive.example. Then domains that have redirected to those get classified too, which covers the last two—trackerOne.example and trackerFour.example.

Developer Advice

Avoid making unnecessary redirects to domains that are likely to be classified as having tracking ability.

Origin-Only Referrer for Domains Without User Interaction

ITP’s purging of website data does not prevent trackers from receiving the so called referrer header which reveals the webpage the user is currently on. In ITP 2.0, the referrer, if there is one, is downgraded to just the page’s origin for third party requests to domains that have been classified as possible trackers by ITP and have not received user interaction.

Here’s an example of what we mean by this: Say the user visits https://store.example/baby-products/strollers/deluxe-navy-blue.html, and that page loads a resource from trackerOne.example. Before ITP 2.0, the request to trackerOne.example would contain the full referrer “https://store.example/baby/strollers/deluxe-stroller-navy-blue.html” which reveals a lot about the user to the third-party. With ITP 2.0, the referrer will be reduced to just “https://store.example/”.

For further reading on this subject, see Mozilla’s research on origin-only referrers.


Does ITP differentiate between my subdomains?
No. ITP captures statistics and applies its rules for the effective top-level domain plus one, or eTLD+1. An eTLD is .com or so an example of an eTLD+1 would be but not (eTLD+2) or just (eTLD).

Does eTLD mean public suffix?
Yes. See the Public Suffix List.

Is there a way for users to whitelist my domain to be excepted from ITP’s rules?
No, there is no such whitelisting feature.

How does ITP classify a domain’s tracking abilities?
See the original ITP 1.0 blog post for details on the machine learning model.

My domain is not a tracker, but it gets classified by ITP. Is that a bug?
ITP does not rely on a centralized blacklist of known trackers. Instead, it captures per-domain (eTLD+1) statistics on-device and classifies each domain’s ability to track cross-site. If a domain has the ability to track the user cross-site, it’s subject to ITP’s cookie and website data rules.

Is it enough for users to visit my website to keep its cookies from being purged if my domain gets classified by ITP?
No, a mere visit does not suffice. The user has to interact with your website, meaning a tap, click, or form entry. In ITP 2.0, user granted access through the Storage Access API also counts as such user interaction.

How do I reset ITP or the domains I’ve allowed storage access for?
Clear your Safari history. Note that this gets rid of data that may be needed to reproduce an ITP issue. If you’re investigating a bug related to ITP, don’t clear your history before you’re done with that work.

I need to debug my website in regards to ITP. Are there specific developer tools?
We’re working on an ITP Debug Mode which will help you debug websites and capture data that’s useful when filing bugs on ITP. It will be announced on this blog.

What is an authenticated widget, an authenticated embed, or authenticated third-party content?
The web platform allows for powerful integration across websites. This enables services such as social media to create widgets that are to be embedded as third-party content on news sites and blogs, but it also enables cross-site tracking. Some widgets have to see the user as logged in to work. For example, if the user wants to comment on blog.example with their social.example account, the social.example commenting widget needs to see the user as logged in to their service. We refer to these widgets as authenticated and to enable them while disabling cross-site tracking, the widgets now have to ask for permission to see the user’s identity, per-site.

How does the removal of the 24 hour cookie access window prevent cross-site tracking from social media etc?
ITP 1.0 had a 24 hour window in which websites the user interacted with could use their cookies as in previous versions of Safari. This was a compatibility measure we took to enable federated logins (e.g. use social.example to login to news.example) and authenticated third-party content (e.g. use social.example to make a comment on blog.example). However, this also allowed social media and search engines that the user interacted with as first parties to track the user across websites while inside that 24 hour window. The mere existence of third-party content from these services was enough for them to see which webpages the user visited. For example, if a user used social.example and then, several hours later, visited news.example which had a social.example Like button or comment widget embedded on the site, social.example could track their browsing on news.example. In ITP 2.0 we restrict such third-party content to only be able to identify the user when they actually use the content, such as write a comment or play a video. This is also the point at which Safari will ask for the user’s permission (if the widget is asking for permission to see its cookies).

Feedback and Bug Reports

Please report bugs through and send feedback to our evangelist Jon Davis. If you have technical questions on how the feature works you can find me on Twitter @johnwilander.