New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Storage Access API #3338

Open
johnwilander opened this Issue Jan 10, 2018 · 89 comments

Comments

@johnwilander

johnwilander commented Jan 10, 2018

Hi! John Wilander from WebKit here. We hope this can extend existing specifications rather than create some whole new spec. It was originally filed under whatwg/dom but I was advised to move it here.

Storage Access API

Problem

Tl;dr: Browsers that block access to third-party cookies break authenticated embeds such as commenting widgets and subscribed video services.

In the context of cross-origin resource loads, cookies are popularly referred to as third-party cookies. In reality, these cookies are often the same as the first-party cookies so what we really mean with third-party cookies is access to first-party cookies in a third-party context.

A browser may have rules for third-party cookies that go beyond cookie policy rules such as scheme, host, path, secure attribute etc. These additional rules may be:

  • Third-parties aren't allowed to set cookies,
  • Third-parties have their cookies partitioned or double-keyed, or
  • Third-parties have no cookie access.

However, certain services are intended to be embedded as third-party content and need access to first-party cookies for authentication. Examples are commenting widgets, video embeds, payment provider integration, document embeds, and social media action widgets. These break if the third-party content has no access to its first-party cookies.

The same problem exists for other kinds of storage such as IndexedDB and LocalStorage, except they are not tied to the HTTP protocol and are typically not used for authentication purposes. From here on we will refer to cookies except when the distinction between cookies and other storage makes sense.

Proposed Solution

Tl;dr: A new API with which cross-origin iframes can request access to their first-party cookies when processing a user gesture such as a tap or a click. This allows third-party embeds to authenticate on user interaction.

We propose two new functions on the document:

partial interface Document {
    Promise<bool> hasStorageAccess();
    Promise<void> requestStorageAccess();
};

The reasons these are on the document is that 1) storage access is granted to the particular document (see Access Removal) and 2) it changes document.cookie.

hasStorageAccess() can be called at any time to check whether access is already granted and it doesn't require user interaction.

requestStorageAccess() should only be called on user interaction such as a tap or a click. It will check a set of rules and grant access if the rules are fulfilled. Access to first-party cookies in the given iframe can be assumed if the returned promise resolves. From that point, any sub resource load in the iframe will have first-party cookies sent and incoming cookies will be set in the first-party cookie jar.

Note that no other third-party resources on that webpage are affected by the storage access status of an individual iframe.

Algorithm for requestStorageAccess()

  1. If the document already has been granted access, resolve.
  2. If the document has a null origin, reject.
  3. If the document's frame is the main frame, resolve.
  4. If the sub frame's origin is equal to the main frame's, resolve.
  5. If the sub frame is not sandboxed, skip to step 7.
  6. If the sub frame doesn't have the token "allow-storage-access-by-user-activation", reject.
  7. If the sub frame's parent frame is not the top frame, reject.
  8. If the browser is not processing a user gesture, reject.
  9. Check any additional rules that the browser has. Examples: Whitelists, blacklists, on-device classification, user settings, anti-clickjacking heuristics, or prompting the user for explicit permission. Reject if some rule is not fulfilled.
  10. Grant the document access to cookies and store that fact for the purposes of future calls to hasStorageAccess() and requestStorageAccess().

Access Removal

Storage access is granted for the life of the document and as long as the document's frame is attached to the DOM. This means:

  • Access is removed when the sub frame navigates.
  • Access is removed when the sub frame is detached from the DOM.
  • Access is removed when the top frame navigates.
  • Access is removed when the webpage goes away, such as a tab close.

In addition, the browser may decide to remove access on a timeout basis or on some dedicated user action such as switching cookie policy.

WebKit Specifics

WebKit's implementation of Storage Access API will be available in Safari Technology Preview soon and on by default. It only covers cookie access, i.e. no other storage mechanisms and the partitioning of them is affected by a call to requestStorageAccess() at this point.

@ppeg34

This comment has been minimized.

Show comment
Hide comment
@ppeg34

ppeg34 Jan 10, 2018

Can you please elaborate on what is meant by...

the partitioning of them is affected by a call to requestStorageAccess() at this point.

How is the partitioning of the cookies affected by calling requestStorageAccess()? Thanks in advance.

ppeg34 commented Jan 10, 2018

Can you please elaborate on what is meant by...

the partitioning of them is affected by a call to requestStorageAccess() at this point.

How is the partitioning of the cookies affected by calling requestStorageAccess()? Thanks in advance.

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Jan 10, 2018

Can you please elaborate on what is meant by...

the partitioning of them is affected by a call to requestStorageAccess() at this point.

How is the partitioning of the cookies affected by calling requestStorageAccess()? Thanks in advance.

That is, as you can see, a WebKit-specific detail and not really part of what we propose. But sure.

Let's say example.com has an iframe from social.org and social.org's cookies are partitioned under example.com. If the social.org iframe calls document.requestStorageAccess() upon a user gesture, and the rules say that access should be granted, the returned promise will resolve.

From that point, social.org's cookies are no longer partitioned under example.com in that iframe. Instead it has access to whatever cookies it would have if the user went directly to social.org as a first-party website.

Access goes back to its partitioned state when social.org's document in that iframe goes away or its frame is detached from the DOM.

The same would apply to any other partitioned storage that the browser supports in Storage Access API.

johnwilander commented Jan 10, 2018

Can you please elaborate on what is meant by...

the partitioning of them is affected by a call to requestStorageAccess() at this point.

How is the partitioning of the cookies affected by calling requestStorageAccess()? Thanks in advance.

That is, as you can see, a WebKit-specific detail and not really part of what we propose. But sure.

Let's say example.com has an iframe from social.org and social.org's cookies are partitioned under example.com. If the social.org iframe calls document.requestStorageAccess() upon a user gesture, and the rules say that access should be granted, the returned promise will resolve.

From that point, social.org's cookies are no longer partitioned under example.com in that iframe. Instead it has access to whatever cookies it would have if the user went directly to social.org as a first-party website.

Access goes back to its partitioned state when social.org's document in that iframe goes away or its frame is detached from the DOM.

The same would apply to any other partitioned storage that the browser supports in Storage Access API.

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Jan 10, 2018

Small note on "access to whatever cookies it would have if the user went directly to social.org as a first-party website": That obviously wouldn't apply to SameSite cookies. WebKit don't support those yet, but I wanted to mention that exception.

johnwilander commented Jan 10, 2018

Small note on "access to whatever cookies it would have if the user went directly to social.org as a first-party website": That obviously wouldn't apply to SameSite cookies. WebKit don't support those yet, but I wanted to mention that exception.

@dlongley

This comment has been minimized.

Show comment
Hide comment
@dlongley

dlongley Jan 11, 2018

We ran into the partitioned storage problem when writing polyfills for the Payment Handler API and Credential Handler APIs and running them on Safari. These needed to load content via a third-party iframe that maintained previously registered payment and credential handlers that were kept track of via localStorage/IndexedDB.

When the relying party website (that loaded the polyfill iframe) attempted to request payment or credentials on Safari, the iframe would fail to see what the user previously registered -- and there was no way to fulfill the request. It sounds like this API would address the problem, which would be fantastic.

dlongley commented Jan 11, 2018

We ran into the partitioned storage problem when writing polyfills for the Payment Handler API and Credential Handler APIs and running them on Safari. These needed to load content via a third-party iframe that maintained previously registered payment and credential handlers that were kept track of via localStorage/IndexedDB.

When the relying party website (that loaded the polyfill iframe) attempted to request payment or credentials on Safari, the iframe would fail to see what the user previously registered -- and there was no way to fulfill the request. It sounds like this API would address the problem, which would be fantastic.

@jeisinger

This comment has been minimized.

Show comment
Hide comment
@jeisinger

jeisinger Jan 15, 2018

Member

As I mentioned at TPAC, Chrome offers granular cookie & site data controls and UI that allow for users configuring this without any special APIs, so I'm a bit surprised that we'd need to change the spec for something that other browsers already can offer.

I'm also not sure why we'd need a separate API for this as opposed to using the permissions API.

Member

jeisinger commented Jan 15, 2018

As I mentioned at TPAC, Chrome offers granular cookie & site data controls and UI that allow for users configuring this without any special APIs, so I'm a bit surprised that we'd need to change the spec for something that other browsers already can offer.

I'm also not sure why we'd need a separate API for this as opposed to using the permissions API.

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Jan 15, 2018

Are you saying Chrome has cookie controls that allow the user to block or partition all or some cross-origin resources’ cookies, and then allow those subresources cookie access on a per-iframe or per page basis?

johnwilander commented Jan 15, 2018

Are you saying Chrome has cookie controls that allow the user to block or partition all or some cross-origin resources’ cookies, and then allow those subresources cookie access on a per-iframe or per page basis?

@mikewest

This comment has been minimized.

Show comment
Hide comment
@mikewest

mikewest Jan 15, 2018

Member

As I mentioned at TPAC, Chrome offers granular cookie & site data controls and UI that allow for users configuring this without any special APIs, so I'm a bit surprised that we'd need to change the spec for something that other browsers already can offer.

Browsers can offer the functionality natively, but it might be reasonable to give sites the ability to ask for more permission than they're granted as-configured. In the same way that the permission API gives sites the ability to ask for geolocation, even when the browser is configured to deny-by-default, the problem statement above posits that it might be reasonable to allow sites to ask for permission to access locally stored data, even if the existing configuration would deny that to them.

If we model storage as a permission, as @jyasskin suggested elsewhere, it doesn't seem out of the question to me that developers could call something like navigator.permissions.query({name:'first-party-storage'})) to determine whether their first-party storage is available (perhaps behind a prompt), and call something like navigator.storage.requestFirstParty() (or something similar, but navigator.storage feels like a better spot than Document if we mean for this to cover more than cookies) to cause the prompt.

Also, as @annevk noted in the DOM bug, and @raymeskhoury has noted in a Permission Delegation proposal prompting from a third-party context is hard. It's interesting to think about some of the secondary consequences of modeling this as a permission, if some browsers are shifting to a world where we deny third-party permissions by default and allow/require the parent to delegate. Requiring allow on a frame seems pretty reasonable when we're talking about additional privileges beyond what developers have traditionally expected by default (geolocation, etc). I imagine the breakage (and other side-effects, like the tacit encouragement for third-party scripts to execute in their parents' contexts) would be greater if we shifted things like storage into a deny-by-default mode.

Member

mikewest commented Jan 15, 2018

As I mentioned at TPAC, Chrome offers granular cookie & site data controls and UI that allow for users configuring this without any special APIs, so I'm a bit surprised that we'd need to change the spec for something that other browsers already can offer.

Browsers can offer the functionality natively, but it might be reasonable to give sites the ability to ask for more permission than they're granted as-configured. In the same way that the permission API gives sites the ability to ask for geolocation, even when the browser is configured to deny-by-default, the problem statement above posits that it might be reasonable to allow sites to ask for permission to access locally stored data, even if the existing configuration would deny that to them.

If we model storage as a permission, as @jyasskin suggested elsewhere, it doesn't seem out of the question to me that developers could call something like navigator.permissions.query({name:'first-party-storage'})) to determine whether their first-party storage is available (perhaps behind a prompt), and call something like navigator.storage.requestFirstParty() (or something similar, but navigator.storage feels like a better spot than Document if we mean for this to cover more than cookies) to cause the prompt.

Also, as @annevk noted in the DOM bug, and @raymeskhoury has noted in a Permission Delegation proposal prompting from a third-party context is hard. It's interesting to think about some of the secondary consequences of modeling this as a permission, if some browsers are shifting to a world where we deny third-party permissions by default and allow/require the parent to delegate. Requiring allow on a frame seems pretty reasonable when we're talking about additional privileges beyond what developers have traditionally expected by default (geolocation, etc). I imagine the breakage (and other side-effects, like the tacit encouragement for third-party scripts to execute in their parents' contexts) would be greater if we shifted things like storage into a deny-by-default mode.

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Jan 15, 2018

Mike, do you still think the API should be on navigator given that any access is scoped to the document?

johnwilander commented Jan 15, 2018

Mike, do you still think the API should be on navigator given that any access is scoped to the document?

@othermaciej

This comment has been minimized.

Show comment
Hide comment
@othermaciej

othermaciej Jan 15, 2018

To explain the context for this a bit more, I'd like to explain some things about Safari's current storage policy for third-party contexts, and also some model use cases for this proposed storage access API. I think some of the suggestions here may be due to lack of clarity about these things.

Safari's third-party storage policy

Safari has long partitioned or denied all types of storage except cookies, including even incidental storage like the cache, to prevent tracking via so-called super cookies like evercookie. Partitioning means keying based on both the origin of the resource and the top-level document's origin, effectively making third-party contexts see completely different storage universes on each site they were embedded into.

Cookies were an exception, for web compatibility reasons. Cookies were partially blocked via our long-standing policy that prevents setting new third-party cookies. But if a third-party cookie already existed, third-party origins could read and set it.

In 2017, we extended this to also partition cookies in third-party contexts (with a few limited exceptions). As a result, most content has access to only a partitioned view of its storage including cookies.

The reason for all this is privacy. We don't want embedded content to be able to passively track users across the web. We're most interested in preventing passive tracking, not necessarily incidental tracking when a user chooses to engage with a cross-site embed.

Use cases

  1. YouTube videos are commonly embedded in third-party sites. When the user plays a YouTube video embedded in another site, it would be good to respect their global YouTube preferences, for example caption settings. It would also be good if YouTube Red subscribers were not shown ads, as per the terms of their subscription. But if YouTube's cookies are partitioned, the video player frame cannot see the user's first party

  2. A number of sites have Facebook "like" buttons. These buttons register that a user has "liked" the article with their Facebook account but without leaving the page. If Facebook's cookies are partitioned, then FB doesn't know who the user is and has to navigate or pop up a window to ask. (Facebook "share" buttons and Twitter "tweet this" buttons are unaffected, because they always open a new first-party page on the relevant site to complete the action).

How the Storage Access API helps with cases like this

When the user clicks on a YouTube video to play it, or a Facebook like button to like an article, the embedded content may requestStorageAccess(). The API can only be called within the scope of a user action. Although prompting is allowed by our proposal, we expect in most cases we will just grant the permission without prompting, as the user action is sufficient. We will prompt only if we suspect some funny business is going on, and even then we may just choose to always deny. The API is asynchronous just to enable the possibility of prompting. First-party storage access is allowed only in that frame, and only until it is navigated or removed from the document.

In the examples above, this would allow YouTube to respect the user's settings, and Facebook to know who they are to register the "like". However, it would not enable passive tracking. The user has to click every time to expose first-party state.

Why some other ideas in this issue would not work

  1. Manual fine-grained cookie settings do not solve this problem. They do not enable the user to make Facebook "like" buttons and YouTube video preferences work, but without enabling these sites to passively track them even on pages where they don't engage with these features. IF the user allowed third-party cookies for youtube.com or facebook.com on all domains, this would enable passive tracking. If the user allowed third-party cookies for these domains when embedded in particular other domains, they'd have to predict exactly the sites where they will watch youtube videos or click like buttons, which is not reasonable.

  2. Treating this as a generic permission that is delegated via Feature Policy. We don't want sites to be able to grant their iframes first-party storage access by adding markup to the iframe. This would enable passive tracking even when the user does not engage. And embed providers would be incentivized to add this permission to their standard embed markup. The idea is that embeds only get to identify the user when the user engages with them.

How this might apply to other browsers

Other browsers, including Mozilla and Brave, have expressed interest in denying storage to third-party origins either by default or in optional modes. We believe this API could allow embedded gadgets to function correctly under these types of policies.

othermaciej commented Jan 15, 2018

To explain the context for this a bit more, I'd like to explain some things about Safari's current storage policy for third-party contexts, and also some model use cases for this proposed storage access API. I think some of the suggestions here may be due to lack of clarity about these things.

Safari's third-party storage policy

Safari has long partitioned or denied all types of storage except cookies, including even incidental storage like the cache, to prevent tracking via so-called super cookies like evercookie. Partitioning means keying based on both the origin of the resource and the top-level document's origin, effectively making third-party contexts see completely different storage universes on each site they were embedded into.

Cookies were an exception, for web compatibility reasons. Cookies were partially blocked via our long-standing policy that prevents setting new third-party cookies. But if a third-party cookie already existed, third-party origins could read and set it.

In 2017, we extended this to also partition cookies in third-party contexts (with a few limited exceptions). As a result, most content has access to only a partitioned view of its storage including cookies.

The reason for all this is privacy. We don't want embedded content to be able to passively track users across the web. We're most interested in preventing passive tracking, not necessarily incidental tracking when a user chooses to engage with a cross-site embed.

Use cases

  1. YouTube videos are commonly embedded in third-party sites. When the user plays a YouTube video embedded in another site, it would be good to respect their global YouTube preferences, for example caption settings. It would also be good if YouTube Red subscribers were not shown ads, as per the terms of their subscription. But if YouTube's cookies are partitioned, the video player frame cannot see the user's first party

  2. A number of sites have Facebook "like" buttons. These buttons register that a user has "liked" the article with their Facebook account but without leaving the page. If Facebook's cookies are partitioned, then FB doesn't know who the user is and has to navigate or pop up a window to ask. (Facebook "share" buttons and Twitter "tweet this" buttons are unaffected, because they always open a new first-party page on the relevant site to complete the action).

How the Storage Access API helps with cases like this

When the user clicks on a YouTube video to play it, or a Facebook like button to like an article, the embedded content may requestStorageAccess(). The API can only be called within the scope of a user action. Although prompting is allowed by our proposal, we expect in most cases we will just grant the permission without prompting, as the user action is sufficient. We will prompt only if we suspect some funny business is going on, and even then we may just choose to always deny. The API is asynchronous just to enable the possibility of prompting. First-party storage access is allowed only in that frame, and only until it is navigated or removed from the document.

In the examples above, this would allow YouTube to respect the user's settings, and Facebook to know who they are to register the "like". However, it would not enable passive tracking. The user has to click every time to expose first-party state.

Why some other ideas in this issue would not work

  1. Manual fine-grained cookie settings do not solve this problem. They do not enable the user to make Facebook "like" buttons and YouTube video preferences work, but without enabling these sites to passively track them even on pages where they don't engage with these features. IF the user allowed third-party cookies for youtube.com or facebook.com on all domains, this would enable passive tracking. If the user allowed third-party cookies for these domains when embedded in particular other domains, they'd have to predict exactly the sites where they will watch youtube videos or click like buttons, which is not reasonable.

  2. Treating this as a generic permission that is delegated via Feature Policy. We don't want sites to be able to grant their iframes first-party storage access by adding markup to the iframe. This would enable passive tracking even when the user does not engage. And embed providers would be incentivized to add this permission to their standard embed markup. The idea is that embeds only get to identify the user when the user engages with them.

How this might apply to other browsers

Other browsers, including Mozilla and Brave, have expressed interest in denying storage to third-party origins either by default or in optional modes. We believe this API could allow embedded gadgets to function correctly under these types of policies.

@dlongley

This comment has been minimized.

Show comment
Hide comment
@dlongley

dlongley Jan 15, 2018

@othermaciej,

First-party storage access is allowed only in that frame, and only until it is navigated or removed from the document.

Would the choice be remembered on the same site in the future without user interaction? I imagine not -- which has me wondering how this would impact embedded content that only loads after the user has engaged in some activity on the top-level domain.

For example, consider a payment handler polyfill that shows the user their registered payment handlers for selection after they've hit a pay button on the top level domain.

With storage partitioning enabled and this new API, the registered payment handlers would be inaccessible (being stored in localStorage/IndexedDB by a third-party polyfill domain) until the user clicks on the embedded content. This may be acceptable the first time it happens, by adding a one-time prompt requesting that the user enable payment on the site. But introducing an extra click to the payment process every time they buy something from the same site would be unfortunate.

It would also be unfortunate to force the top-level domain to use a specialized payment button that is served from the third-party polyfill domain as a mitigation to this problem. One of the advantages of standardizing payment on the Web is to avoid the Nascar problem and forcing top-level domains to use specialized buttons.

I wonder if some kind of one-time use "delegated user interaction object" could be passed to the iframe via postMessage if specifying delegated permissions in the iframe markup is considered unacceptable. That sort of primitive may also be helpful/reusable in other situations on the Web platform, particularly those where a Promise must resolve prior to "consuming" a user interaction to call some guarded API.

dlongley commented Jan 15, 2018

@othermaciej,

First-party storage access is allowed only in that frame, and only until it is navigated or removed from the document.

Would the choice be remembered on the same site in the future without user interaction? I imagine not -- which has me wondering how this would impact embedded content that only loads after the user has engaged in some activity on the top-level domain.

For example, consider a payment handler polyfill that shows the user their registered payment handlers for selection after they've hit a pay button on the top level domain.

With storage partitioning enabled and this new API, the registered payment handlers would be inaccessible (being stored in localStorage/IndexedDB by a third-party polyfill domain) until the user clicks on the embedded content. This may be acceptable the first time it happens, by adding a one-time prompt requesting that the user enable payment on the site. But introducing an extra click to the payment process every time they buy something from the same site would be unfortunate.

It would also be unfortunate to force the top-level domain to use a specialized payment button that is served from the third-party polyfill domain as a mitigation to this problem. One of the advantages of standardizing payment on the Web is to avoid the Nascar problem and forcing top-level domains to use specialized buttons.

I wonder if some kind of one-time use "delegated user interaction object" could be passed to the iframe via postMessage if specifying delegated permissions in the iframe markup is considered unacceptable. That sort of primitive may also be helpful/reusable in other situations on the Web platform, particularly those where a Promise must resolve prior to "consuming" a user interaction to call some guarded API.

@othermaciej

This comment has been minimized.

Show comment
Hide comment
@othermaciej

othermaciej Jan 15, 2018

Would the choice be remembered on the same site in the future without user interaction?

No.

I imagine not -- which has me wondering how this would impact embedded content that only loads after the user has engaged in some activity on the top-level domain.

I don't think it would help in such cases (unless the user clicks again on the embedded content).

For example, consider a payment handler polyfill that shows the user their registered payment handlers for selection after they've hit a pay button on the top level domain. With storage partitioning enabled and this new API, the registered payment handlers would be inaccessible (being stored in localStorage/IndexedDB by a third-party polyfill domain) until the user clicks on the embedded content.

Do you know a real site or embedded gadget that actually works this way? It would specifically need to:

  • Load an iframe after the user initially clicks.
  • Show a set of payment providers based on info specific to the user, with that set being accessed from the iframe.
  • Not involve any clicks prior to selecting a payment provider in its normal flow.
  • Not make the initial payment button itself an iframe.

I don't know of any setups like this, but if there are, we can certainly think about opportunities to help them in the face of limitations on third-party storage.

othermaciej commented Jan 15, 2018

Would the choice be remembered on the same site in the future without user interaction?

No.

I imagine not -- which has me wondering how this would impact embedded content that only loads after the user has engaged in some activity on the top-level domain.

I don't think it would help in such cases (unless the user clicks again on the embedded content).

For example, consider a payment handler polyfill that shows the user their registered payment handlers for selection after they've hit a pay button on the top level domain. With storage partitioning enabled and this new API, the registered payment handlers would be inaccessible (being stored in localStorage/IndexedDB by a third-party polyfill domain) until the user clicks on the embedded content.

Do you know a real site or embedded gadget that actually works this way? It would specifically need to:

  • Load an iframe after the user initially clicks.
  • Show a set of payment providers based on info specific to the user, with that set being accessed from the iframe.
  • Not involve any clicks prior to selecting a payment provider in its normal flow.
  • Not make the initial payment button itself an iframe.

I don't know of any setups like this, but if there are, we can certainly think about opportunities to help them in the face of limitations on third-party storage.

@dlongley

This comment has been minimized.

Show comment
Hide comment
@dlongley

dlongley Jan 16, 2018

@othermaciej,

Other than the payment handler and credential handler polyfills -- I don't know of any at the moment. There may be some some third-party payment providers that provide this kind of flow, but I'm unaware of them.

This is the payment handler polyfill demo that was presented at TPAC that I'm talking about (note that this won't run in Safari because of this very issue, but will run in Chrome, Firefox, and Edge):

You install a payment handler and add payment instruments (credit cards) here at a "wallet" website:

https://payment-handler.demo.digitalbazaar.com/

And then you use the registered handler here via a payment instrument of your choice here at a "merchant" website:

https://payment-merchant.demo.digitalbazaar.com/

This follows the flow you described above.

dlongley commented Jan 16, 2018

@othermaciej,

Other than the payment handler and credential handler polyfills -- I don't know of any at the moment. There may be some some third-party payment providers that provide this kind of flow, but I'm unaware of them.

This is the payment handler polyfill demo that was presented at TPAC that I'm talking about (note that this won't run in Safari because of this very issue, but will run in Chrome, Firefox, and Edge):

You install a payment handler and add payment instruments (credit cards) here at a "wallet" website:

https://payment-handler.demo.digitalbazaar.com/

And then you use the registered handler here via a payment instrument of your choice here at a "merchant" website:

https://payment-merchant.demo.digitalbazaar.com/

This follows the flow you described above.

@othermaciej

This comment has been minimized.

Show comment
Hide comment
@othermaciej

othermaciej Jan 16, 2018

It does seem like that demo would need to be modified even with this new API in place. It will either need an extra click to look up the default payment method, or the buy button itself needs to be an iframe.

Since this demo is not (as far as I know) in wide actual use, I am not sure it should be a priority to design around its requirements rather than to look at ways to modify the demo.

othermaciej commented Jan 16, 2018

It does seem like that demo would need to be modified even with this new API in place. It will either need an extra click to look up the default payment method, or the buy button itself needs to be an iframe.

Since this demo is not (as far as I know) in wide actual use, I am not sure it should be a priority to design around its requirements rather than to look at ways to modify the demo.

@mikewest

This comment has been minimized.

Show comment
Hide comment
@mikewest

mikewest Jan 16, 2018

Member

Thanks, @johnwilander and @othermaciej for the detailed background. That's helpful information. I'll pull out a few points below:

Mike, do you still think the API should be on navigator given that any access is scoped to the document?

If we model things as a permission, then I think hooking into the existing navigator.permissions and navigator.storage makes more sense than adding one-off methods to Document. I'd also push back a bit on the notion that "access is scoped to the document", as, at least for cookies, HttpOnly cookies wouldn't be accessible to the document, but instead sent on requests to the origin via HTTP requests which initiate from the document (or, presumably, from its parent?). Ideally, those cookies would never be exposed to the document context.

When the user clicks on a YouTube video to play it, or a Facebook like button to like an article, the embedded content may requestStorageAccess(). The API can only be called within the scope of a user action.

I think this addresses some of the use cases you noted above, while partially addressing others. Video sites are good examples of embeds that need to make decisions about what content to show a given user prior user interaction in order to comply with a user's preferences regarding mature content (Vimeo's viewing preferences, YouTube's restricted mode, etc.). It seems like this mechanism might push some of those sites into a client-side rendering model whereby content is locked behind a clickthrough that calls out to the mechanism y'all are proposing before rendering anything. That seems doable from a technical perspective, but would have performance (and aesthetic!) impacts on users.

Although prompting is allowed by our proposal, we expect in most cases we will just grant the permission without prompting, as the user action is sufficient. We will prompt only if we suspect some funny business is going on, and even then we may just choose to always deny. The API is asynchronous just to enable the possibility of prompting. First-party storage access is allowed only in that frame, and only until it is navigated or removed from the document.

All of these restrictions would be compatible with treating storage access as a permission that the browser makes decisions about whether to grant or restrict, with or without user interaction. The scoping and persistence is a bit different than we've done with other permissions in the past (and different still from what Chrome folks are proposing), but the core notion of asking first, and then doing, seems like a reasonable fit.

In the examples above, this would allow YouTube to respect the user's settings, and Facebook to know who they are to register the "like". However, it would not enable passive tracking. The user has to click every time to expose first-party state.

It's somewhat tangential to the core proposal, but I'd suggest that y'all will want to consider whether or not the user gesture is consumed by the call to obtain first-party storage. I know that Chrome's gesture implementation has sometimes caused developers some annoyance by disallowing combinations of actions with a single gesture. I can imagine that applying here as well: perhaps a widget would ask for credentials on click, and use them to make a decision about whether to call window.open() (which I believe Safari also gates on a gesture requirement).

Manual fine-grained cookie settings do not solve this problem. They do not enable the user to make Facebook "like" buttons and YouTube video preferences work, but without enabling these sites to passively track them even on pages where they don't engage with these features.

Chrome's content settings are certainly capable of making this distinction between "B in A" and "B in C" (see the Primary and Secondary Patterns section of the chrome.contentSettings extension API docs, for example), and allows the user to do so in certain cases via the blocked-cookie UX in our omnibox. I suspect we could do a better job exposing those granular options to the user in our settings UI, but that in some ways comes back to third-party contexts being difficult to expose to users in a way that they can be expected to generally understand.

IF the user allowed third-party cookies for youtube.com or facebook.com on all domains, this would enable passive tracking. If the user allowed third-party cookies for these domains when embedded in particular other domains, they'd have to predict exactly the sites where they will watch youtube videos or click like buttons, which is not reasonable.

I know that some users (like @jeisinger above :) ) have developed workflows whereby they toggle Chrome's "Block third-party cookies and site data" option, and then make use of the omnibox UX and the reload button to fix sites after visiting them. It seems to me that that's not a terrible model.

Treating this as a generic permission that is delegated via Feature Policy. We don't want sites to be able to grant their iframes first-party storage access by adding markup to the iframe. This would enable passive tracking even when the user does not engage. And embed providers would be incentivized to add this permission to their standard embed markup. The idea is that embeds only get to identify the user when the user engages with them.

Another way of looking at the same mechanism would be that the top-level document would be able to use Feature Policy to deny access to certain permissions to its children by fiat, the embeddee's wishes notwithstanding.

Moreover, even in a fully realized delegation model, the browser remains in a position of mediating the permission requests, and could certainly make a decision about whether to grant permissions on the basis of information to which the page isn't privy. The permission model means that the request would fall into a well-paved API path for developers, not that you'd be locked into adhering to a page's desires without the potential for override.

Other browsers, including Mozilla and Brave, have expressed interest in denying storage to third-party origins either by default or in optional modes. We believe this API could allow embedded gadgets to function correctly under these types of policies.

/cc @TanviHacks, @dveditz, @diracdeltas from those browsers for feedback. Also tagging in @patrickkettner to get Edge in the loop.

Member

mikewest commented Jan 16, 2018

Thanks, @johnwilander and @othermaciej for the detailed background. That's helpful information. I'll pull out a few points below:

Mike, do you still think the API should be on navigator given that any access is scoped to the document?

If we model things as a permission, then I think hooking into the existing navigator.permissions and navigator.storage makes more sense than adding one-off methods to Document. I'd also push back a bit on the notion that "access is scoped to the document", as, at least for cookies, HttpOnly cookies wouldn't be accessible to the document, but instead sent on requests to the origin via HTTP requests which initiate from the document (or, presumably, from its parent?). Ideally, those cookies would never be exposed to the document context.

When the user clicks on a YouTube video to play it, or a Facebook like button to like an article, the embedded content may requestStorageAccess(). The API can only be called within the scope of a user action.

I think this addresses some of the use cases you noted above, while partially addressing others. Video sites are good examples of embeds that need to make decisions about what content to show a given user prior user interaction in order to comply with a user's preferences regarding mature content (Vimeo's viewing preferences, YouTube's restricted mode, etc.). It seems like this mechanism might push some of those sites into a client-side rendering model whereby content is locked behind a clickthrough that calls out to the mechanism y'all are proposing before rendering anything. That seems doable from a technical perspective, but would have performance (and aesthetic!) impacts on users.

Although prompting is allowed by our proposal, we expect in most cases we will just grant the permission without prompting, as the user action is sufficient. We will prompt only if we suspect some funny business is going on, and even then we may just choose to always deny. The API is asynchronous just to enable the possibility of prompting. First-party storage access is allowed only in that frame, and only until it is navigated or removed from the document.

All of these restrictions would be compatible with treating storage access as a permission that the browser makes decisions about whether to grant or restrict, with or without user interaction. The scoping and persistence is a bit different than we've done with other permissions in the past (and different still from what Chrome folks are proposing), but the core notion of asking first, and then doing, seems like a reasonable fit.

In the examples above, this would allow YouTube to respect the user's settings, and Facebook to know who they are to register the "like". However, it would not enable passive tracking. The user has to click every time to expose first-party state.

It's somewhat tangential to the core proposal, but I'd suggest that y'all will want to consider whether or not the user gesture is consumed by the call to obtain first-party storage. I know that Chrome's gesture implementation has sometimes caused developers some annoyance by disallowing combinations of actions with a single gesture. I can imagine that applying here as well: perhaps a widget would ask for credentials on click, and use them to make a decision about whether to call window.open() (which I believe Safari also gates on a gesture requirement).

Manual fine-grained cookie settings do not solve this problem. They do not enable the user to make Facebook "like" buttons and YouTube video preferences work, but without enabling these sites to passively track them even on pages where they don't engage with these features.

Chrome's content settings are certainly capable of making this distinction between "B in A" and "B in C" (see the Primary and Secondary Patterns section of the chrome.contentSettings extension API docs, for example), and allows the user to do so in certain cases via the blocked-cookie UX in our omnibox. I suspect we could do a better job exposing those granular options to the user in our settings UI, but that in some ways comes back to third-party contexts being difficult to expose to users in a way that they can be expected to generally understand.

IF the user allowed third-party cookies for youtube.com or facebook.com on all domains, this would enable passive tracking. If the user allowed third-party cookies for these domains when embedded in particular other domains, they'd have to predict exactly the sites where they will watch youtube videos or click like buttons, which is not reasonable.

I know that some users (like @jeisinger above :) ) have developed workflows whereby they toggle Chrome's "Block third-party cookies and site data" option, and then make use of the omnibox UX and the reload button to fix sites after visiting them. It seems to me that that's not a terrible model.

Treating this as a generic permission that is delegated via Feature Policy. We don't want sites to be able to grant their iframes first-party storage access by adding markup to the iframe. This would enable passive tracking even when the user does not engage. And embed providers would be incentivized to add this permission to their standard embed markup. The idea is that embeds only get to identify the user when the user engages with them.

Another way of looking at the same mechanism would be that the top-level document would be able to use Feature Policy to deny access to certain permissions to its children by fiat, the embeddee's wishes notwithstanding.

Moreover, even in a fully realized delegation model, the browser remains in a position of mediating the permission requests, and could certainly make a decision about whether to grant permissions on the basis of information to which the page isn't privy. The permission model means that the request would fall into a well-paved API path for developers, not that you'd be locked into adhering to a page's desires without the potential for override.

Other browsers, including Mozilla and Brave, have expressed interest in denying storage to third-party origins either by default or in optional modes. We believe this API could allow embedded gadgets to function correctly under these types of policies.

/cc @TanviHacks, @dveditz, @diracdeltas from those browsers for feedback. Also tagging in @patrickkettner to get Edge in the loop.

@diracdeltas

This comment has been minimized.

Show comment
Hide comment
@diracdeltas

diracdeltas Jan 17, 2018

Hi, Yan from Brave here! Brave does indeed block 3rd party storage (cookies, localStorage, etc.) and referrer by default.

Although prompting is allowed by our proposal, we expect in most cases we will just grant the permission without prompting, as the user action is sufficient.

We (Brave) would almost certainly want to prompt by default with a 'never prompt again' option in the permissions UX. I think this API would be useful but we would want to be careful to not make our current cookie restrictions more lax without alerting the user.

diracdeltas commented Jan 17, 2018

Hi, Yan from Brave here! Brave does indeed block 3rd party storage (cookies, localStorage, etc.) and referrer by default.

Although prompting is allowed by our proposal, we expect in most cases we will just grant the permission without prompting, as the user action is sufficient.

We (Brave) would almost certainly want to prompt by default with a 'never prompt again' option in the permissions UX. I think this API would be useful but we would want to be careful to not make our current cookie restrictions more lax without alerting the user.

@othermaciej

This comment has been minimized.

Show comment
Hide comment
@othermaciej

othermaciej Jan 17, 2018

@diracdeltas The API is designed to allow all the prompting you want (since it's async) so it would be easy to fulfill it with a prompt-always (or prompt-once-per-origin-pair) policy.

othermaciej commented Jan 17, 2018

@diracdeltas The API is designed to allow all the prompting you want (since it's async) so it would be easy to fulfill it with a prompt-always (or prompt-once-per-origin-pair) policy.

@hillbrad

This comment has been minimized.

Show comment
Hide comment
@hillbrad

hillbrad Jan 17, 2018

Yes, it would be great to allow for never prompting again. Many integrations that involve data sharing are moving towards a more granular model of permissions, with an emphasis on prompting only in context and as needed, rather than asking for all permissions that might ever be needed up front. The more friction the browser adds to this, the less likely sites are to adopt these granular and just-in-time models.

hillbrad commented Jan 17, 2018

Yes, it would be great to allow for never prompting again. Many integrations that involve data sharing are moving towards a more granular model of permissions, with an emphasis on prompting only in context and as needed, rather than asking for all permissions that might ever be needed up front. The more friction the browser adds to this, the less likely sites are to adopt these granular and just-in-time models.

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Jan 17, 2018

From today's W3C WebAppSec call, as I interpreted it:

  • Mozilla is “cautiously interested” in implementing. They will monitor the uptake of the API in Safari and if it seems to work, they will try it out.
  • Edge said their status is similar to Mozilla’s.
  • Chrome has no plans but might implement in Chromium for other ports, especially if this gets standardized.

johnwilander commented Jan 17, 2018

From today's W3C WebAppSec call, as I interpreted it:

  • Mozilla is “cautiously interested” in implementing. They will monitor the uptake of the API in Safari and if it seems to work, they will try it out.
  • Edge said their status is similar to Mozilla’s.
  • Chrome has no plans but might implement in Chromium for other ports, especially if this gets standardized.
@diracdeltas

This comment has been minimized.

Show comment
Hide comment
@diracdeltas

diracdeltas Jan 17, 2018

@johnwilander For now, Brave's status is that we would use this if it were already implemented in Chromium. We could be interested in implementing it independent of Chromium depending on adoption.

diracdeltas commented Jan 17, 2018

@johnwilander For now, Brave's status is that we would use this if it were already implemented in Chromium. We could be interested in implementing it independent of Chromium depending on adoption.

@mikewest

This comment has been minimized.

Show comment
Hide comment
@mikewest

mikewest Jan 18, 2018

Member

Chrome has no plans but might implement in Chromium for other ports, especially if this gets standardized.

What I hope I suggested on the call was that I don't think Chrome has a concrete interest in implementing this, but that if a Chromium port (like Brave) wanted to upstream a patch to reduce their maintenance burden, I'd be happy to help them do so.

The WebAppSec discussion's draft minutes are available at https://www.w3.org/2018/01/17-webappsec-minutes.html#item04 if folks here are interested in the points raised there. @dveditz and I re-raised the suggestion that this might fit into the Permissions API rather than building a new one-off on Document, and @jyasskin suggested that if the Permissions API spec contains restrictions on the permission model that make it incompatible with this usage, he'd see it as a bug and fix it.

Member

mikewest commented Jan 18, 2018

Chrome has no plans but might implement in Chromium for other ports, especially if this gets standardized.

What I hope I suggested on the call was that I don't think Chrome has a concrete interest in implementing this, but that if a Chromium port (like Brave) wanted to upstream a patch to reduce their maintenance burden, I'd be happy to help them do so.

The WebAppSec discussion's draft minutes are available at https://www.w3.org/2018/01/17-webappsec-minutes.html#item04 if folks here are interested in the points raised there. @dveditz and I re-raised the suggestion that this might fit into the Permissions API rather than building a new one-off on Document, and @jyasskin suggested that if the Permissions API spec contains restrictions on the permission model that make it incompatible with this usage, he'd see it as a bug and fix it.

@annevk

This comment has been minimized.

Show comment
Hide comment
@annevk

annevk Jan 18, 2018

Member

The "has" method can be modeled as a permission I think. "Request" not so much.

FWIW, there's quite a few people within Mozilla that have a problem with prompts on behalf of third-parties and I'm not really sure how to reconcile that position with this API.

Member

annevk commented Jan 18, 2018

The "has" method can be modeled as a permission I think. "Request" not so much.

FWIW, there's quite a few people within Mozilla that have a problem with prompts on behalf of third-parties and I'm not really sure how to reconcile that position with this API.

@mikewest

This comment has been minimized.

Show comment
Hide comment
@mikewest

mikewest Jan 18, 2018

Member

The "has" method can be modeled as a permission I think. "Request" not so much.

I agree. One of the earlier suggestions in this thread was to tie the request bit to a new method on navigator.storage rather than Document.

FWIW, there's quite a few people within Mozilla that have a problem with prompts on behalf of third-parties and I'm not really sure how to reconcile that position with this API.

That's also something Chrome folks are reluctant to do more of.

Member

mikewest commented Jan 18, 2018

The "has" method can be modeled as a permission I think. "Request" not so much.

I agree. One of the earlier suggestions in this thread was to tie the request bit to a new method on navigator.storage rather than Document.

FWIW, there's quite a few people within Mozilla that have a problem with prompts on behalf of third-parties and I'm not really sure how to reconcile that position with this API.

That's also something Chrome folks are reluctant to do more of.

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Jan 18, 2018

As for prompting, it’s optional in the proposal. Are you saying you’re against optional prompting too? Brave expressed that they’ll definitely prompt. We want the ability if we see abuse of the API down the road.

johnwilander commented Jan 18, 2018

As for prompting, it’s optional in the proposal. Are you saying you’re against optional prompting too? Brave expressed that they’ll definitely prompt. We want the ability if we see abuse of the API down the road.

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Sep 9, 2018

If it’s just your domain A embedding your domain B in iframes to achieve SOP isolation, ITP will not classify domain B as having tracking abilities and cookies will work as in pre-ITP Safari, i.e. you don’t need to request storage access.

johnwilander commented Sep 9, 2018

If it’s just your domain A embedding your domain B in iframes to achieve SOP isolation, ITP will not classify domain B as having tracking abilities and cookies will work as in pre-ITP Safari, i.e. you don’t need to request storage access.

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Sep 9, 2018

Mozilla announced two days ago that they’re implementing the Storage Access API, with some interesting differences from WebKit’s implementation: https://groups.google.com/forum/m/#!msg/mozilla.dev.platform/l8bV4RFgAc4/MKl9jbJpBQAJ

johnwilander commented Sep 9, 2018

Mozilla announced two days ago that they’re implementing the Storage Access API, with some interesting differences from WebKit’s implementation: https://groups.google.com/forum/m/#!msg/mozilla.dev.platform/l8bV4RFgAc4/MKl9jbJpBQAJ

@wilfrem

This comment has been minimized.

Show comment
Hide comment
@wilfrem

wilfrem Sep 10, 2018

@johnwilander

Thank you for your quick response.
I'm worried about the ITP method of determining whether domain has tracking ability.
Are there any guidelines or advice to prevent false-positive detection? it's helpful for any developer for using iframe as sandbox.

wilfrem commented Sep 10, 2018

@johnwilander

Thank you for your quick response.
I'm worried about the ITP method of determining whether domain has tracking ability.
Are there any guidelines or advice to prevent false-positive detection? it's helpful for any developer for using iframe as sandbox.

@annevk

This comment has been minimized.

Show comment
Hide comment
@annevk

annevk Sep 10, 2018

Member

Given that two browsers now want to ship this API in some form it prolly warrants being standardized. Unfortunately, since it's all still rather experimental there needs to be quite some "implementation-defined"-leeway.

Member

annevk commented Sep 10, 2018

Given that two browsers now want to ship this API in some form it prolly warrants being standardized. Unfortunately, since it's all still rather experimental there needs to be quite some "implementation-defined"-leeway.

@rstoneIDBS

This comment has been minimized.

Show comment
Hide comment
@rstoneIDBS

rstoneIDBS Sep 11, 2018

If this starts to become a standardized behaviour can I please ask the browser vendors to consider different user profiles. This proposal is aimed at preventing 'ad tracking' for internet consumers but unfortunately breaks the only reliable (IFRAME) mechanism used by enterprise cloud aware applications that need to support 3rd party integrations.
Allowing enterprise users to disable this feature on a per domain basis (as Chrome currently does) is a much better solution than forcing us to tell our users to disable 3rd party cookie blocking entirely.

rstoneIDBS commented Sep 11, 2018

If this starts to become a standardized behaviour can I please ask the browser vendors to consider different user profiles. This proposal is aimed at preventing 'ad tracking' for internet consumers but unfortunately breaks the only reliable (IFRAME) mechanism used by enterprise cloud aware applications that need to support 3rd party integrations.
Allowing enterprise users to disable this feature on a per domain basis (as Chrome currently does) is a much better solution than forcing us to tell our users to disable 3rd party cookie blocking entirely.

@kushal

This comment has been minimized.

Show comment
Hide comment
@kushal

kushal Sep 19, 2018

@johnwilander

If this is becoming a standard, I'd love to see some thinking about how a slightly larger scope could cover more cases.

As is, StorageAccess faces two hurdles in replacing many current uses of third-party cookies

  1. Permission prompts would be too untargeted and interruptive
  2. Requiring user interaction makes it hard to deliver value on page load

I think there's a small addition that would mitigate both problems while preserving privacy goals: a concept of "storage is present".


Let's start with the the reason StorageAccess feels insufficient as is.

  • Embedded video or music players that want to save plays to a user's history or take advantage of any subscriptions are encouraged to prompt for StorageAccess when the user hits play. However, this is pretty interruptive (prompting them when they hit play is likely to be perceived as annoying), especially since it is untargeted (prompting all users to find only the subset with subscriptions).

  • Sites that offer personalization and subscriptions across multiple domains (Gizmodo, Medium, Scroll), or embedded comment services that might rerank or maintain state based on a user account really want to deliver that value on page load. The reactive nature of StorageAccess (only on user action) is not a great fit.

What if we expose a single bit of information: whether storage exists at all?

With this change, all requests to a given third-party domain (iframe or XHR) where cookies are present but elided would include a Cookies-present HTTP header, and user agents would also provide a document.isStoragePresent() function inside of iframes.

An embed could check if storage data is present, and show a call-to-action requesting access only if there is. These calls-to-action could be significantly more prominent because they are targeted. They would provide a path for requesting access in cases where there is no clear user action to tie into (like pageload), and they would provide a path to request access without interrupting some critical flow (like play).

For example, an embed could check !document.hasStorageAccess() && document.isStoragePresent() or make a XHR call to a domain it uses for tracking subscription state, and if true show a button reading "Let your FooPlayer subscription work on this site", and then when the user clicks, it could request StorageAccess.

Fingerprinting is a concern, but easily mitigated

Although by itself this proposal exposes only a single binary bit that is not vulnerable to tracking, a challenge is avoiding HSTS supercookie-style attacks by using several of these bits in concert. Implementations could choose to police this through heuristics, or they could require permission, or use a mix of the two.

For example, when a user logs in at foosubscription.com, the site might call document.permitStoragePresent() which prompts the user "Allow sites to know that you're logged in to foosubscription.com as you browse the web?" The permission could even require periodic reconfirmation from the user. This permission system would require the user to trust and grant this permission across many domains to allow for fingerprinting, which is quite unlikely.

kushal commented Sep 19, 2018

@johnwilander

If this is becoming a standard, I'd love to see some thinking about how a slightly larger scope could cover more cases.

As is, StorageAccess faces two hurdles in replacing many current uses of third-party cookies

  1. Permission prompts would be too untargeted and interruptive
  2. Requiring user interaction makes it hard to deliver value on page load

I think there's a small addition that would mitigate both problems while preserving privacy goals: a concept of "storage is present".


Let's start with the the reason StorageAccess feels insufficient as is.

  • Embedded video or music players that want to save plays to a user's history or take advantage of any subscriptions are encouraged to prompt for StorageAccess when the user hits play. However, this is pretty interruptive (prompting them when they hit play is likely to be perceived as annoying), especially since it is untargeted (prompting all users to find only the subset with subscriptions).

  • Sites that offer personalization and subscriptions across multiple domains (Gizmodo, Medium, Scroll), or embedded comment services that might rerank or maintain state based on a user account really want to deliver that value on page load. The reactive nature of StorageAccess (only on user action) is not a great fit.

What if we expose a single bit of information: whether storage exists at all?

With this change, all requests to a given third-party domain (iframe or XHR) where cookies are present but elided would include a Cookies-present HTTP header, and user agents would also provide a document.isStoragePresent() function inside of iframes.

An embed could check if storage data is present, and show a call-to-action requesting access only if there is. These calls-to-action could be significantly more prominent because they are targeted. They would provide a path for requesting access in cases where there is no clear user action to tie into (like pageload), and they would provide a path to request access without interrupting some critical flow (like play).

For example, an embed could check !document.hasStorageAccess() && document.isStoragePresent() or make a XHR call to a domain it uses for tracking subscription state, and if true show a button reading "Let your FooPlayer subscription work on this site", and then when the user clicks, it could request StorageAccess.

Fingerprinting is a concern, but easily mitigated

Although by itself this proposal exposes only a single binary bit that is not vulnerable to tracking, a challenge is avoiding HSTS supercookie-style attacks by using several of these bits in concert. Implementations could choose to police this through heuristics, or they could require permission, or use a mix of the two.

For example, when a user logs in at foosubscription.com, the site might call document.permitStoragePresent() which prompts the user "Allow sites to know that you're logged in to foosubscription.com as you browse the web?" The permission could even require periodic reconfirmation from the user. This permission system would require the user to trust and grant this permission across many domains to allow for fingerprinting, which is quite unlikely.

@ehsan

This comment has been minimized.

Show comment
Hide comment
@ehsan

ehsan Sep 19, 2018

Collaborator

Hi @johnwilander,

I've implemented this API in Gecko. I have three questions for you for now:

a) Were you planning on writing a description of the algorithm for Document.hasStorageAccess() as well? For the Gecko implementation I had to reverse engineer what WebKit does, which wasn't too much work, but it seems like we'd need to specify that algorithm too.

b) What plans, if any, do you have with regards to web-platform-tests for this feature? I see that WebKit has some WebKit-specific layout tests, and we also have our own tests for the feature. On our side, in order for us to be able to run tests for this feature in web-platform-tests, we'd need to be able to simulate user gestures, as well as call some Gecko-specific test infrastructure setup/teardown functions for each test to prepare the storage access API to be called from origin https://foo.example. I recently learned that web-platform-tests now are able to do all of this (please see the discussion in https://groups.google.com/d/msg/mozilla.dev.platform/l8bV4RFgAc4/lrLvVK1xBQAJ), so I would be pretty interested in collaborating on an effort to get some tests upstreamed to wpt. (Not sure if WebKit runs wpt tests in CI these days or not, but we do.) One thing to figure out, of course, is the behavior differences across Gecko and WebKit as far as the tests go (e.g. Gecko provides access to the full cookie jar rather than just to cookies). Our process for importing wpt tests into our test infrastructure is capable of handling tests that do not pass in Gecko for one reason or another, so that shouldn't be a big issue for us, hopefully.

c) Just a tiny nit on the IDL in the first comment of the issue, per https://heycam.github.io/webidl/#idl-boolean, hasStorageAccess() should be declared to return Promise<boolean>. :-)

Thanks!

Collaborator

ehsan commented Sep 19, 2018

Hi @johnwilander,

I've implemented this API in Gecko. I have three questions for you for now:

a) Were you planning on writing a description of the algorithm for Document.hasStorageAccess() as well? For the Gecko implementation I had to reverse engineer what WebKit does, which wasn't too much work, but it seems like we'd need to specify that algorithm too.

b) What plans, if any, do you have with regards to web-platform-tests for this feature? I see that WebKit has some WebKit-specific layout tests, and we also have our own tests for the feature. On our side, in order for us to be able to run tests for this feature in web-platform-tests, we'd need to be able to simulate user gestures, as well as call some Gecko-specific test infrastructure setup/teardown functions for each test to prepare the storage access API to be called from origin https://foo.example. I recently learned that web-platform-tests now are able to do all of this (please see the discussion in https://groups.google.com/d/msg/mozilla.dev.platform/l8bV4RFgAc4/lrLvVK1xBQAJ), so I would be pretty interested in collaborating on an effort to get some tests upstreamed to wpt. (Not sure if WebKit runs wpt tests in CI these days or not, but we do.) One thing to figure out, of course, is the behavior differences across Gecko and WebKit as far as the tests go (e.g. Gecko provides access to the full cookie jar rather than just to cookies). Our process for importing wpt tests into our test infrastructure is capable of handling tests that do not pass in Gecko for one reason or another, so that shouldn't be a big issue for us, hopefully.

c) Just a tiny nit on the IDL in the first comment of the issue, per https://heycam.github.io/webidl/#idl-boolean, hasStorageAccess() should be declared to return Promise<boolean>. :-)

Thanks!

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Sep 20, 2018

Splendid news, Ehsan!

a) Let’s fix that.

b) Let’s cooperate on platform tests. I’ll have to look into user gestures. I recall at least one other “by-user-activation” sandbox attribute. Maybe it has platform tests?
Are your tests similar to ours except for your broader scope? (When you say “full cookie jar,” I assume you mean other kinds of storage than cookies, such as LocalStorage.)

c) Sure, let’s fix that as part of a).

We’ve also made two recent updates based on developer feedback:

  1. We now persist storage access through same-site navigations of the iframe.

  2. We now maintain the user gesture status if the document.requestStorageAccess() promise resolves. This allows the iframe to check for cookies and do a popup if the user turns out to not be logged in.

johnwilander commented Sep 20, 2018

Splendid news, Ehsan!

a) Let’s fix that.

b) Let’s cooperate on platform tests. I’ll have to look into user gestures. I recall at least one other “by-user-activation” sandbox attribute. Maybe it has platform tests?
Are your tests similar to ours except for your broader scope? (When you say “full cookie jar,” I assume you mean other kinds of storage than cookies, such as LocalStorage.)

c) Sure, let’s fix that as part of a).

We’ve also made two recent updates based on developer feedback:

  1. We now persist storage access through same-site navigations of the iframe.

  2. We now maintain the user gesture status if the document.requestStorageAccess() promise resolves. This allows the iframe to check for cookies and do a popup if the user turns out to not be logged in.

@michael-oneill

This comment has been minimized.

Show comment
Hide comment
@michael-oneill

michael-oneill Oct 1, 2018

What would be good is a way to pass on information to the user prompt, as well as a revokeStorageAccess(), returning the access state to as it was before requestStorageAccess resolved. This is important in Europe where the GDPR calls for it to be as easy to withdraw consent as to give it.
Information could be provided through a dictionary parameter e.g.

requestStorageAccess({
name: 'BigCo Inc',
purpose: {
category: 'audience measurement',
description: 'A longer description of how personal data collected is used and for what purpose'
},
maxAge: 1000 * 60 * 60 * 24 * 30

});

The maxAge enables duration for the permission, UAs could allow users to set overall limits

revokeStorageAccess();

GDPR ref:

The data subject shall have the right to withdraw his or her consent at any time. The withdrawal of consent shall not affect the lawfulness of processing based on consent before its withdrawal. Prior to giving consent, the data subject shall be informed thereof. It shall be as easy to withdraw as to give consent. Article 7.3

michael-oneill commented Oct 1, 2018

What would be good is a way to pass on information to the user prompt, as well as a revokeStorageAccess(), returning the access state to as it was before requestStorageAccess resolved. This is important in Europe where the GDPR calls for it to be as easy to withdraw consent as to give it.
Information could be provided through a dictionary parameter e.g.

requestStorageAccess({
name: 'BigCo Inc',
purpose: {
category: 'audience measurement',
description: 'A longer description of how personal data collected is used and for what purpose'
},
maxAge: 1000 * 60 * 60 * 24 * 30

});

The maxAge enables duration for the permission, UAs could allow users to set overall limits

revokeStorageAccess();

GDPR ref:

The data subject shall have the right to withdraw his or her consent at any time. The withdrawal of consent shall not affect the lawfulness of processing based on consent before its withdrawal. Prior to giving consent, the data subject shall be informed thereof. It shall be as easy to withdraw as to give consent. Article 7.3

@michael-oneill

This comment has been minimized.

Show comment
Hide comment
@michael-oneill

michael-oneill Oct 1, 2018

Also following from my comment 28/3/2018 it would be useful to have a storage-access feature:
Feature-Policy: storage-access example.com
A site could request that all embeddees used partitioned storage except for an allow-list.
The allow-list would still cause a user request prompt if not granted, but at page load. The information provided would come from a /.well-known JSON resource e.g. /.well-known/dnt or an Origin Manifest when we have one.

michael-oneill commented Oct 1, 2018

Also following from my comment 28/3/2018 it would be useful to have a storage-access feature:
Feature-Policy: storage-access example.com
A site could request that all embeddees used partitioned storage except for an allow-list.
The allow-list would still cause a user request prompt if not granted, but at page load. The information provided would come from a /.well-known JSON resource e.g. /.well-known/dnt or an Origin Manifest when we have one.

@ojame

This comment has been minimized.

Show comment
Hide comment
@ojame

ojame Oct 9, 2018

I know this has already been rolled out in Safari, and it's in progress in Gecko (so I'm late to the party), however we have a use-case that this fundamentally breaks:

  • We have an application[0] that sets a third-party cookie with your authenticated details
  • Our customers embed our widget on their website with a snippet of html, which calls a JavaScript file
  • If the JS file was requested with the authentication cookie, it sends them back the widget code, if not, it sends them back nothing

So basically we conditionally render our widget based on if the user was logged into our main application or not. An important note: Our widget is embedded on our customers production websites, however it doesn't render for the vast majority of users, because they're not authenticated with our main application. A large majority of our customers also embed our widget on multiple websites with different domains.

From my understanding (reading this thread and documentation) this flow is no longer possible with this API because of the need for interaction. The only flow that would work, as far as I can tell:

  • render an iframe to everyone with a call to action to render our widget
  • when/if a user clicks the CTA, request permission via this API and then conditionally render the widget

This has its obvious drawbacks, the biggest one being our tool is (generally) intended for internal use (yes, even on production!) but yet to get it displaying at all, we need to render at least something to everyone (whether it's a CTA that requests permissions, or a basic authentication dialogue).

I understand because of the way our application interacts with our widget (third-party cookies), ITP picks this up as essentially being a tracker, but at our core we are not, and we are a genuinely trusted product for our consumers. There is also no way with this API for users of Safari to tell their browser "I understand the side-effects but I trust [domain] indefinitely until I don't, across all websites".

I would love, if someone has faced similar issues or understands where I'm coming from, to open a discussion around this.

[0]: BugHerd

ojame commented Oct 9, 2018

I know this has already been rolled out in Safari, and it's in progress in Gecko (so I'm late to the party), however we have a use-case that this fundamentally breaks:

  • We have an application[0] that sets a third-party cookie with your authenticated details
  • Our customers embed our widget on their website with a snippet of html, which calls a JavaScript file
  • If the JS file was requested with the authentication cookie, it sends them back the widget code, if not, it sends them back nothing

So basically we conditionally render our widget based on if the user was logged into our main application or not. An important note: Our widget is embedded on our customers production websites, however it doesn't render for the vast majority of users, because they're not authenticated with our main application. A large majority of our customers also embed our widget on multiple websites with different domains.

From my understanding (reading this thread and documentation) this flow is no longer possible with this API because of the need for interaction. The only flow that would work, as far as I can tell:

  • render an iframe to everyone with a call to action to render our widget
  • when/if a user clicks the CTA, request permission via this API and then conditionally render the widget

This has its obvious drawbacks, the biggest one being our tool is (generally) intended for internal use (yes, even on production!) but yet to get it displaying at all, we need to render at least something to everyone (whether it's a CTA that requests permissions, or a basic authentication dialogue).

I understand because of the way our application interacts with our widget (third-party cookies), ITP picks this up as essentially being a tracker, but at our core we are not, and we are a genuinely trusted product for our consumers. There is also no way with this API for users of Safari to tell their browser "I understand the side-effects but I trust [domain] indefinitely until I don't, across all websites".

I would love, if someone has faced similar issues or understands where I'm coming from, to open a discussion around this.

[0]: BugHerd

@rstoneIDBS

This comment has been minimized.

Show comment
Hide comment
@rstoneIDBS

rstoneIDBS Oct 9, 2018

@ojame - you aren't the only one, see my comments earlier in the thread. Unfortunately I don't think our opinions carry any weight - there doesn't seem to be a will to consider enterprise applications/users at all. Like you, I can't see why all the browser vendors can't just support a white list (ala Chrome) for those use cases where a (frankly horrible UX experience) workaround won't be sufficient.

rstoneIDBS commented Oct 9, 2018

@ojame - you aren't the only one, see my comments earlier in the thread. Unfortunately I don't think our opinions carry any weight - there doesn't seem to be a will to consider enterprise applications/users at all. Like you, I can't see why all the browser vendors can't just support a white list (ala Chrome) for those use cases where a (frankly horrible UX experience) workaround won't be sufficient.

@michael-oneill

This comment has been minimized.

Show comment
Hide comment
@michael-oneill

michael-oneill Oct 9, 2018

michael-oneill commented Oct 9, 2018

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Oct 9, 2018

I know this has already been rolled out in Safari, and it's in progress in Gecko (so I'm late to the party), however we have a use-case that this fundamentally breaks:

  • We have an application[0] that sets a third-party cookie with your authenticated details

That has never been possible with Safari's default cookie policy, starting 15 years ago. Third-parties without pre-existing cookies cannot set cookies in Safari. I assume you mean your site sets a cookie as first-party when the user logs in and then uses that cookie to authenticate the user when your content is third-party.

  • Our customers embed our widget on their website with a snippet of html, which calls a JavaScript file

I'm a little confused here. Are your logged in users your customers or other websites your customers?

  • If the JS file was requested with the authentication cookie, it sends them back the widget code, if not, it sends them back nothing

So basically we conditionally render our widget based on if the user was logged into our main application or not. An important note: Our widget is embedded on our customers production websites, however it doesn't render for the vast majority of users, because they're not authenticated with our main application. A large majority of our customers also embed our widget on multiple websites with different domains.

From my understanding (reading this thread and documentation) this flow is no longer possible with this API because of the need for interaction. The only flow that would work, as far as I can tell:

  • render an iframe to everyone with a call to action to render our widget

You don't have to do that. You can render the iframe conditionally. You only need the iframe if and when you've decided you need to authenticate the user.

  • when/if a user clicks the CTA, request permission via this API and then conditionally render the widget

This has its obvious drawbacks, the biggest one being our tool is (generally) intended for internal use (yes, even on production!) but yet to get it displaying at all, we need to render at least something to everyone (whether it's a CTA that requests permissions, or a basic authentication dialogue).

I understand because of the way our application interacts with our widget (third-party cookies), ITP picks this up as essentially being a tracker, but at our core we are not, and we are a genuinely trusted product for our consumers. There is also no way with this API for users of Safari to tell their browser "I understand the side-effects but I trust [domain] indefinitely until I don't, across all websites".

We do not believe users in general understand the consequences of web scale tracking capabilities.

I would love, if someone has faced similar issues or understands where I'm coming from, to open a discussion around this.

Whenever we discuss security or privacy issues, we have to take adversaries into account. In the case of cross-site tracking, we have to assume that trackers will immediately abuse any capability to convince the user to opt out globally for their particular domain or any capability to claim that their particular domain is not a tracker to be able to skip privacy protections. Thus, any suggestions for changing how the Storage Access API works has to cover how we avoid abuse.

Further, this thread is about the Storage Access API as proposed standard web functionality. Moving into the space of managed devices is not handled by web standards. Additionally, ITP is not a standard and not proposed as a standard. So we have to limit what we discuss in this thread to ways to get first-party cookie and website data access under a setting, opt-in or default, in any browser, that restricts a third-party from using its first-party cookies and website data.

johnwilander commented Oct 9, 2018

I know this has already been rolled out in Safari, and it's in progress in Gecko (so I'm late to the party), however we have a use-case that this fundamentally breaks:

  • We have an application[0] that sets a third-party cookie with your authenticated details

That has never been possible with Safari's default cookie policy, starting 15 years ago. Third-parties without pre-existing cookies cannot set cookies in Safari. I assume you mean your site sets a cookie as first-party when the user logs in and then uses that cookie to authenticate the user when your content is third-party.

  • Our customers embed our widget on their website with a snippet of html, which calls a JavaScript file

I'm a little confused here. Are your logged in users your customers or other websites your customers?

  • If the JS file was requested with the authentication cookie, it sends them back the widget code, if not, it sends them back nothing

So basically we conditionally render our widget based on if the user was logged into our main application or not. An important note: Our widget is embedded on our customers production websites, however it doesn't render for the vast majority of users, because they're not authenticated with our main application. A large majority of our customers also embed our widget on multiple websites with different domains.

From my understanding (reading this thread and documentation) this flow is no longer possible with this API because of the need for interaction. The only flow that would work, as far as I can tell:

  • render an iframe to everyone with a call to action to render our widget

You don't have to do that. You can render the iframe conditionally. You only need the iframe if and when you've decided you need to authenticate the user.

  • when/if a user clicks the CTA, request permission via this API and then conditionally render the widget

This has its obvious drawbacks, the biggest one being our tool is (generally) intended for internal use (yes, even on production!) but yet to get it displaying at all, we need to render at least something to everyone (whether it's a CTA that requests permissions, or a basic authentication dialogue).

I understand because of the way our application interacts with our widget (third-party cookies), ITP picks this up as essentially being a tracker, but at our core we are not, and we are a genuinely trusted product for our consumers. There is also no way with this API for users of Safari to tell their browser "I understand the side-effects but I trust [domain] indefinitely until I don't, across all websites".

We do not believe users in general understand the consequences of web scale tracking capabilities.

I would love, if someone has faced similar issues or understands where I'm coming from, to open a discussion around this.

Whenever we discuss security or privacy issues, we have to take adversaries into account. In the case of cross-site tracking, we have to assume that trackers will immediately abuse any capability to convince the user to opt out globally for their particular domain or any capability to claim that their particular domain is not a tracker to be able to skip privacy protections. Thus, any suggestions for changing how the Storage Access API works has to cover how we avoid abuse.

Further, this thread is about the Storage Access API as proposed standard web functionality. Moving into the space of managed devices is not handled by web standards. Additionally, ITP is not a standard and not proposed as a standard. So we have to limit what we discuss in this thread to ways to get first-party cookie and website data access under a setting, opt-in or default, in any browser, that restricts a third-party from using its first-party cookies and website data.

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Oct 9, 2018

@ojame - you aren't the only one, see my comments earlier in the thread. Unfortunately I don't think our opinions carry any weight - there doesn't seem to be a will to consider enterprise applications/users at all. Like you, I can't see why all the browser vendors can't just support a white list (ala Chrome) for those use cases where a (frankly horrible UX experience) workaround won't be sufficient.

Is Chrome's whitelist for cookie use by third-parties when the user has opted into only allowing first-party cookies?

As for opinions carrying weight, we take all your comments into consideration. Our primary goal is to protect users' privacy on the web. We're open to any suggestion that makes more legitimate things work while avoiding abuse.

johnwilander commented Oct 9, 2018

@ojame - you aren't the only one, see my comments earlier in the thread. Unfortunately I don't think our opinions carry any weight - there doesn't seem to be a will to consider enterprise applications/users at all. Like you, I can't see why all the browser vendors can't just support a white list (ala Chrome) for those use cases where a (frankly horrible UX experience) workaround won't be sufficient.

Is Chrome's whitelist for cookie use by third-parties when the user has opted into only allowing first-party cookies?

As for opinions carrying weight, we take all your comments into consideration. Our primary goal is to protect users' privacy on the web. We're open to any suggestion that makes more legitimate things work while avoiding abuse.

@kushal

This comment has been minimized.

Show comment
Hide comment
@kushal

kushal Oct 9, 2018

@johnwilander It sounds like @ojame 's needs are similar to the ones I describe above? We would like to show UI only to users who have authentication data rather than to everybody who visits the page (even if the actual data is then only released through a permission dialogue). I'm curious whether you think asking for user permission for this binary logged-in/not-logged-in state could mitigate fingerprinting risk as I describe in my earlier comment?

kushal commented Oct 9, 2018

@johnwilander It sounds like @ojame 's needs are similar to the ones I describe above? We would like to show UI only to users who have authentication data rather than to everybody who visits the page (even if the actual data is then only released through a permission dialogue). I'm curious whether you think asking for user permission for this binary logged-in/not-logged-in state could mitigate fingerprinting risk as I describe in my earlier comment?

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Oct 9, 2018

@johnwilander It sounds like @ojame 's needs are similar to the ones I describe above? We would like to show UI only to users who have authentication data rather than to everybody who visits the page (even if the actual data is then only released through a permission dialogue). I'm curious whether you think asking for user permission for this binary logged-in/not-logged-in state could mitigate fingerprinting risk as I describe in my earlier comment?

A way to check state is a proposal we're taking into consideration.

However, "logged-in/not-logged-in" is not something the browser knows. Plenty of sites have cookies set for logged out users and some of those cookies may even be secure and HttpOnly. Allowing third-parties to ask for the existence of specific cookies is an obvious cross-site tracking vector so the only thing on the table is a binary "has cookies/has no cookies." That would mean that sites who want to leverage such an API would have to expire all their cookies at once when the user actively logs out or is timed out. That's how I interpret your request.

johnwilander commented Oct 9, 2018

@johnwilander It sounds like @ojame 's needs are similar to the ones I describe above? We would like to show UI only to users who have authentication data rather than to everybody who visits the page (even if the actual data is then only released through a permission dialogue). I'm curious whether you think asking for user permission for this binary logged-in/not-logged-in state could mitigate fingerprinting risk as I describe in my earlier comment?

A way to check state is a proposal we're taking into consideration.

However, "logged-in/not-logged-in" is not something the browser knows. Plenty of sites have cookies set for logged out users and some of those cookies may even be secure and HttpOnly. Allowing third-parties to ask for the existence of specific cookies is an obvious cross-site tracking vector so the only thing on the table is a binary "has cookies/has no cookies." That would mean that sites who want to leverage such an API would have to expire all their cookies at once when the user actively logs out or is timed out. That's how I interpret your request.

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Oct 9, 2018

@johnwilander It sounds like @ojame 's needs are similar to the ones I describe above? We would like to show UI only to users who have authentication data rather than to everybody who visits the page (even if the actual data is then only released through a permission dialogue). I'm curious whether you think asking for user permission for this binary logged-in/not-logged-in state could mitigate fingerprinting risk as I describe in my earlier comment?

A way to check state is a proposal we're taking into consideration.

However, "logged-in/not-logged-in" is not something the browser knows. Plenty of sites have cookies set for logged out users and some of those cookies may even be secure and HttpOnly. Allowing third-parties to ask for the existence of specific cookies is an obvious cross-site tracking vector so the only thing on the table is a binary "has cookies/has no cookies." That would mean that sites who want to leverage such an API would have to expire all their cookies at once when the user actively logs out or is timed out. That's how I interpret your request.

And to be clear, we worry about trackers setting up multiple domains and loading one iframe each from those domains to read out one bit at a time with the proposed "has cookies/has no cookies" API. With those bits they will be able to read a cross-site tracking ID and that we will not allow.

johnwilander commented Oct 9, 2018

@johnwilander It sounds like @ojame 's needs are similar to the ones I describe above? We would like to show UI only to users who have authentication data rather than to everybody who visits the page (even if the actual data is then only released through a permission dialogue). I'm curious whether you think asking for user permission for this binary logged-in/not-logged-in state could mitigate fingerprinting risk as I describe in my earlier comment?

A way to check state is a proposal we're taking into consideration.

However, "logged-in/not-logged-in" is not something the browser knows. Plenty of sites have cookies set for logged out users and some of those cookies may even be secure and HttpOnly. Allowing third-parties to ask for the existence of specific cookies is an obvious cross-site tracking vector so the only thing on the table is a binary "has cookies/has no cookies." That would mean that sites who want to leverage such an API would have to expire all their cookies at once when the user actively logs out or is timed out. That's how I interpret your request.

And to be clear, we worry about trackers setting up multiple domains and loading one iframe each from those domains to read out one bit at a time with the proposed "has cookies/has no cookies" API. With those bits they will be able to read a cross-site tracking ID and that we will not allow.

@ojame

This comment has been minimized.

Show comment
Hide comment
@ojame

ojame Oct 9, 2018

@michael-oneill

Is the authenticated cookie created by a top level (first-party) site?, i.e. when the user logs-in? >Could you ask for informed consent (for the widget showing up on other sites) there when they do that?

Yes, it is, and yes, that sounds like something reasonable. It provides better context, too.

@johnwilander

I assume you mean your site sets a cookie as first-party when the user logs in and then uses that cookie to authenticate the user when your content is third-party.

Yes, sorry for my terminology confusion.

I'm a little confused here. Are your logged in users your customers or other websites your customers?

The authenticated users are our customers (in the context of they're authenticated with our application).

You don't have to do that. You can render the iframe conditionally. You only need the iframe if and when you've decided you need to authenticate the user.

I don't understand how we can render the iframe conditionally. It appears via this api, in order to gain access to our authentication cookie (which we can base our conditional render on), we first need to prompt the user for permission, which means we need to display an initial iframe providing some call to action the user can interact with. That initial iframe needs to be shown to everyone then, because at that point, there's no way to tell if the user has an authenticated cookie or not?

Thus, any suggestions for changing how the Storage Access API works has to cover how we avoid abuse.

I'm not on any disagreement here. I love the philosophy of this API and I understand what we do as a product is quite similar to how trackers work - which makes this discussion challenging!

A way to check state is a proposal we're taking into consideration.

Is there any documentation or link I can check out that goes through this proposal? This might meet our needs.

Thanks for being open to discussion 👍

ojame commented Oct 9, 2018

@michael-oneill

Is the authenticated cookie created by a top level (first-party) site?, i.e. when the user logs-in? >Could you ask for informed consent (for the widget showing up on other sites) there when they do that?

Yes, it is, and yes, that sounds like something reasonable. It provides better context, too.

@johnwilander

I assume you mean your site sets a cookie as first-party when the user logs in and then uses that cookie to authenticate the user when your content is third-party.

Yes, sorry for my terminology confusion.

I'm a little confused here. Are your logged in users your customers or other websites your customers?

The authenticated users are our customers (in the context of they're authenticated with our application).

You don't have to do that. You can render the iframe conditionally. You only need the iframe if and when you've decided you need to authenticate the user.

I don't understand how we can render the iframe conditionally. It appears via this api, in order to gain access to our authentication cookie (which we can base our conditional render on), we first need to prompt the user for permission, which means we need to display an initial iframe providing some call to action the user can interact with. That initial iframe needs to be shown to everyone then, because at that point, there's no way to tell if the user has an authenticated cookie or not?

Thus, any suggestions for changing how the Storage Access API works has to cover how we avoid abuse.

I'm not on any disagreement here. I love the philosophy of this API and I understand what we do as a product is quite similar to how trackers work - which makes this discussion challenging!

A way to check state is a proposal we're taking into consideration.

Is there any documentation or link I can check out that goes through this proposal? This might meet our needs.

Thanks for being open to discussion 👍

@kushal

This comment has been minimized.

Show comment
Hide comment
@kushal

kushal Oct 9, 2018

@johnwilander

A way to check state is a proposal we're taking into consideration.

Awesome, really appreciate that.

However, "logged-in/not-logged-in" is not something the browser knows. Plenty of sites have cookies set for logged out users and some of those cookies may even be secure and HttpOnly. Allowing third-parties to ask for the existence of specific cookies is an obvious cross-site tracking vector so the only thing on the table is a binary "has cookies/has no cookies." That would mean that sites who want to leverage such an API would have to expire all their cookies at once when the user actively logs out or is timed out. That's how I interpret your request.

Definitely. I was imagining many sites, including ours, have some subdomain where cookies should only be present if and only if the user is logged in, i.e. connect.foo.com vs www.foo.com. The browser could still limit the ability to peek at this state to one subdomain per TLD. i.e.

  1. user logs in at www.foo.com
  2. site redirects to page on connect.foo.com that sets a cookie and requests permission from the user to access login state across the web using document.permitStoragePresent()
  3. if donuts.foo.com later tries to request the same permission, it is automatically rejected
  4. if a user logs out of www.foo.com, their connect.foo.com cookie is deleted

And to be clear, we worry about trackers setting up multiple domains and loading one iframe each from those domains to read out one bit at a time with the proposed "has cookies/has no cookies" API. With those bits they will be able to read a cross-site tracking ID and that we will not allow.

I appreciate this. Our hope is that if a domain has to request permission through document.permitStoragePresent() and has to renew that permission every 30 days, that very substantially limits the ability for one malicious actor to get a single user to authorize many bits of information.

In addition, it's possible to imagine various browser heuristics about how many times this is used per page, or how many iframes are opened per script, or patterns of collaboration between domains, but the core permission seems like it would go a long way.

kushal commented Oct 9, 2018

@johnwilander

A way to check state is a proposal we're taking into consideration.

Awesome, really appreciate that.

However, "logged-in/not-logged-in" is not something the browser knows. Plenty of sites have cookies set for logged out users and some of those cookies may even be secure and HttpOnly. Allowing third-parties to ask for the existence of specific cookies is an obvious cross-site tracking vector so the only thing on the table is a binary "has cookies/has no cookies." That would mean that sites who want to leverage such an API would have to expire all their cookies at once when the user actively logs out or is timed out. That's how I interpret your request.

Definitely. I was imagining many sites, including ours, have some subdomain where cookies should only be present if and only if the user is logged in, i.e. connect.foo.com vs www.foo.com. The browser could still limit the ability to peek at this state to one subdomain per TLD. i.e.

  1. user logs in at www.foo.com
  2. site redirects to page on connect.foo.com that sets a cookie and requests permission from the user to access login state across the web using document.permitStoragePresent()
  3. if donuts.foo.com later tries to request the same permission, it is automatically rejected
  4. if a user logs out of www.foo.com, their connect.foo.com cookie is deleted

And to be clear, we worry about trackers setting up multiple domains and loading one iframe each from those domains to read out one bit at a time with the proposed "has cookies/has no cookies" API. With those bits they will be able to read a cross-site tracking ID and that we will not allow.

I appreciate this. Our hope is that if a domain has to request permission through document.permitStoragePresent() and has to renew that permission every 30 days, that very substantially limits the ability for one malicious actor to get a single user to authorize many bits of information.

In addition, it's possible to imagine various browser heuristics about how many times this is used per page, or how many iframes are opened per script, or patterns of collaboration between domains, but the core permission seems like it would go a long way.

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Oct 10, 2018

@johnwilander

A way to check state is a proposal we're taking into consideration.

Awesome, really appreciate that.

However, "logged-in/not-logged-in" is not something the browser knows. Plenty of sites have cookies set for logged out users and some of those cookies may even be secure and HttpOnly. Allowing third-parties to ask for the existence of specific cookies is an obvious cross-site tracking vector so the only thing on the table is a binary "has cookies/has no cookies." That would mean that sites who want to leverage such an API would have to expire all their cookies at once when the user actively logs out or is timed out. That's how I interpret your request.

Definitely. I was imagining many sites, including ours, have some subdomain where cookies should only be present if and only if the user is logged in, i.e. connect.foo.com vs www.foo.com. The browser could still limit the ability to peek at this state to one subdomain per TLD. i.e.

The majority of authentication cookies I see are set for the site's eTLD+1. They may very well be set on sub.domain.example, but be set for domain.example. For instance, I just tried logging into google.com which happens on accounts.google.com but sets login cookies for .google.com.

Are you saying you often see sites setting login cookies for a specific subdomain so as to not have them be sent in requests to their eTLD+1?

And if we allow subdomain-specific API calls, wouldn't trackers be able to:

  1. Set up bit1.domain.example, bit2.domain.example, bit3.domain.example, … bit32.domain.example.
  2. Create 32-bit tracking ID for a user and create a cookie for the subdomains that correspond to the '1's in the bit string of the tracking ID.
  3. Open 32 invisible third-party iframes and call the proposed API to read out the '1's and '0's.
  4. PostMessage the bits to a master iframe and resurrect the tracking ID.

Is such abuse what you're gating with the additional document.permitStoragePresent() you mention below?

1. user logs in at [www.foo.com](http://www.foo.com)

2. site redirects to page on connect.foo.com that sets a cookie and requests permission from the user to access login state across the web using `document.permitStoragePresent()`

3. if donuts.foo.com later tries to request the same permission, it is automatically rejected

4. if a user logs out of [www.foo.com](http://www.foo.com), their connect.foo.com cookie is deleted

And to be clear, we worry about trackers setting up multiple domains and loading one iframe each from those domains to read out one bit at a time with the proposed "has cookies/has no cookies" API. With those bits they will be able to read a cross-site tracking ID and that we will not allow.

I appreciate this. Our hope is that if a domain has to request permission through document.permitStoragePresent() and has to renew that permission every 30 days, that very substantially limits the ability for one malicious actor to get a single user to authorize many bits of information.

This is starting to sound like a complicated API. Let's see if I follow what you're saying:

  1. The site that wants to enable authenticated embeds logs the user in on connect.domain.example.
  2. As part of the login, a cookie is set specifically for connect.domain.example. No other cookies are ever set for this domain and it is deleted as soon as the user logs out.
  3. After successful login, the page on connect.domain.example calls document.permitStoragePresent() which prompts the user with some UI that explains what "Allow" and "Don't allow" implies for them.
  4. If the user taps/clicks "Allow," now third-party iframes from connect.domain.example can call document.isStoragePresent() and get a resolved promise if there exist cookies for connect.domain.example.

Is this correct?

In addition, it's possible to imagine various browser heuristics about how many times this is used per page, or how many iframes are opened per script, or patterns of collaboration between domains, but the core permission seems like it would go a long way.

We try to avoid heuristics if we can since they are particularly hard for developers to test their sites under.

johnwilander commented Oct 10, 2018

@johnwilander

A way to check state is a proposal we're taking into consideration.

Awesome, really appreciate that.

However, "logged-in/not-logged-in" is not something the browser knows. Plenty of sites have cookies set for logged out users and some of those cookies may even be secure and HttpOnly. Allowing third-parties to ask for the existence of specific cookies is an obvious cross-site tracking vector so the only thing on the table is a binary "has cookies/has no cookies." That would mean that sites who want to leverage such an API would have to expire all their cookies at once when the user actively logs out or is timed out. That's how I interpret your request.

Definitely. I was imagining many sites, including ours, have some subdomain where cookies should only be present if and only if the user is logged in, i.e. connect.foo.com vs www.foo.com. The browser could still limit the ability to peek at this state to one subdomain per TLD. i.e.

The majority of authentication cookies I see are set for the site's eTLD+1. They may very well be set on sub.domain.example, but be set for domain.example. For instance, I just tried logging into google.com which happens on accounts.google.com but sets login cookies for .google.com.

Are you saying you often see sites setting login cookies for a specific subdomain so as to not have them be sent in requests to their eTLD+1?

And if we allow subdomain-specific API calls, wouldn't trackers be able to:

  1. Set up bit1.domain.example, bit2.domain.example, bit3.domain.example, … bit32.domain.example.
  2. Create 32-bit tracking ID for a user and create a cookie for the subdomains that correspond to the '1's in the bit string of the tracking ID.
  3. Open 32 invisible third-party iframes and call the proposed API to read out the '1's and '0's.
  4. PostMessage the bits to a master iframe and resurrect the tracking ID.

Is such abuse what you're gating with the additional document.permitStoragePresent() you mention below?

1. user logs in at [www.foo.com](http://www.foo.com)

2. site redirects to page on connect.foo.com that sets a cookie and requests permission from the user to access login state across the web using `document.permitStoragePresent()`

3. if donuts.foo.com later tries to request the same permission, it is automatically rejected

4. if a user logs out of [www.foo.com](http://www.foo.com), their connect.foo.com cookie is deleted

And to be clear, we worry about trackers setting up multiple domains and loading one iframe each from those domains to read out one bit at a time with the proposed "has cookies/has no cookies" API. With those bits they will be able to read a cross-site tracking ID and that we will not allow.

I appreciate this. Our hope is that if a domain has to request permission through document.permitStoragePresent() and has to renew that permission every 30 days, that very substantially limits the ability for one malicious actor to get a single user to authorize many bits of information.

This is starting to sound like a complicated API. Let's see if I follow what you're saying:

  1. The site that wants to enable authenticated embeds logs the user in on connect.domain.example.
  2. As part of the login, a cookie is set specifically for connect.domain.example. No other cookies are ever set for this domain and it is deleted as soon as the user logs out.
  3. After successful login, the page on connect.domain.example calls document.permitStoragePresent() which prompts the user with some UI that explains what "Allow" and "Don't allow" implies for them.
  4. If the user taps/clicks "Allow," now third-party iframes from connect.domain.example can call document.isStoragePresent() and get a resolved promise if there exist cookies for connect.domain.example.

Is this correct?

In addition, it's possible to imagine various browser heuristics about how many times this is used per page, or how many iframes are opened per script, or patterns of collaboration between domains, but the core permission seems like it would go a long way.

We try to avoid heuristics if we can since they are particularly hard for developers to test their sites under.

@kushal

This comment has been minimized.

Show comment
Hide comment
@kushal

kushal Oct 10, 2018

@johnwilander

Are you saying you often see sites setting login cookies for a specific subdomain so as to not have them be sent in requests to their eTLD+1?

Yeah, I've seen this occasionally, but I guess it's definitely not universal. I think I was also imagining that some sites could add a subdomain specifically for use with this API. However, this conversation is making me realize there's probably a simpler option, see below. :)

Set up bit1.domain.example, bit2.domain.example, bit3.domain.example, … bit32.domain.example.
Create 32-bit tracking ID for a user and create a cookie for the subdomains that correspond to the '1's in the bit string of the tracking ID.
Open 32 invisible third-party iframes and call the proposed API to read out the '1's and '0's.
PostMessage the bits to a master iframe and resurrect the tracking ID.
Is such abuse what you're gating with the additional document.permitStoragePresent() you mention below?

There is where I imagined that you would limit use of the permitStoragePresent to once per eTLD+1, regardless of which subdomain it's used on, so that once bit1.domain.example is enabled, bit2.domain.example would just be rejected automatically since the slot for domain.example is already taken.

But an equal part of the value of permitStoragePresent would be to prevent many collaborating eTLD+1s, i.e. bit1domain.example, bit2domain.example, etc., because a user would need to give that permission N times and also keep refreshing those permissions every 30 days, and especially if permitStoragePresent only could be called on user interaction.

This is starting to sound like a complicated API. Let's see if I follow what you're saying:

The site that wants to enable authenticated embeds logs the user in on connect.domain.example.
As part of the login, a cookie is set specifically for connect.domain.example. No other cookies are ever set for this domain and it is deleted as soon as the user logs out.
After successful login, the page on connect.domain.example calls document.permitStoragePresent() which prompts the user with some UI that explains what "Allow" and "Don't allow" implies for them.
If the user taps/clicks "Allow," now third-party iframes from connect.domain.example can call document.isStoragePresent() and get a resolved promise if there exist cookies for connect.domain.example.

Yup, that's the proposal. With one variant that maybe domains with storage present also append a HTTP headers to CORS requests so that some logic could happen even before building an iframe.

But your point is well taken that this is pretty complicated. This made me wonder if you could simplify and detach permitStoragePresent() entirely from cookies themselves (although it might need a different name?). In this model, there's no need to fuss around with a special authentication subdomain. Instead, each eTLD+1 can call document.permitStoragePresent from any subdomain or from the eTLD+1 itself, and that just marks a bit for that eTLD+1 in the browser. Then, any iframe from the same eTLD+1 can call document.isStoragePresent to find out if that bit is present, which implies true. Then if a user logs out, the browser calls document.removeStoragePresent(), or the bit is automatically cleared after 30 days or if the user clears cookies. This is effectively a single-bit cross-domain cookie, one per eTLD+1, that can be set and unset using a simple API that captures explicit user permission. I think this is much easier to wrap your head around. It would effectively be document.advertiseLoggedIn() / document.isLoggedIn().

kushal commented Oct 10, 2018

@johnwilander

Are you saying you often see sites setting login cookies for a specific subdomain so as to not have them be sent in requests to their eTLD+1?

Yeah, I've seen this occasionally, but I guess it's definitely not universal. I think I was also imagining that some sites could add a subdomain specifically for use with this API. However, this conversation is making me realize there's probably a simpler option, see below. :)

Set up bit1.domain.example, bit2.domain.example, bit3.domain.example, … bit32.domain.example.
Create 32-bit tracking ID for a user and create a cookie for the subdomains that correspond to the '1's in the bit string of the tracking ID.
Open 32 invisible third-party iframes and call the proposed API to read out the '1's and '0's.
PostMessage the bits to a master iframe and resurrect the tracking ID.
Is such abuse what you're gating with the additional document.permitStoragePresent() you mention below?

There is where I imagined that you would limit use of the permitStoragePresent to once per eTLD+1, regardless of which subdomain it's used on, so that once bit1.domain.example is enabled, bit2.domain.example would just be rejected automatically since the slot for domain.example is already taken.

But an equal part of the value of permitStoragePresent would be to prevent many collaborating eTLD+1s, i.e. bit1domain.example, bit2domain.example, etc., because a user would need to give that permission N times and also keep refreshing those permissions every 30 days, and especially if permitStoragePresent only could be called on user interaction.

This is starting to sound like a complicated API. Let's see if I follow what you're saying:

The site that wants to enable authenticated embeds logs the user in on connect.domain.example.
As part of the login, a cookie is set specifically for connect.domain.example. No other cookies are ever set for this domain and it is deleted as soon as the user logs out.
After successful login, the page on connect.domain.example calls document.permitStoragePresent() which prompts the user with some UI that explains what "Allow" and "Don't allow" implies for them.
If the user taps/clicks "Allow," now third-party iframes from connect.domain.example can call document.isStoragePresent() and get a resolved promise if there exist cookies for connect.domain.example.

Yup, that's the proposal. With one variant that maybe domains with storage present also append a HTTP headers to CORS requests so that some logic could happen even before building an iframe.

But your point is well taken that this is pretty complicated. This made me wonder if you could simplify and detach permitStoragePresent() entirely from cookies themselves (although it might need a different name?). In this model, there's no need to fuss around with a special authentication subdomain. Instead, each eTLD+1 can call document.permitStoragePresent from any subdomain or from the eTLD+1 itself, and that just marks a bit for that eTLD+1 in the browser. Then, any iframe from the same eTLD+1 can call document.isStoragePresent to find out if that bit is present, which implies true. Then if a user logs out, the browser calls document.removeStoragePresent(), or the bit is automatically cleared after 30 days or if the user clears cookies. This is effectively a single-bit cross-domain cookie, one per eTLD+1, that can be set and unset using a simple API that captures explicit user permission. I think this is much easier to wrap your head around. It would effectively be document.advertiseLoggedIn() / document.isLoggedIn().

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Oct 10, 2018

But your point is well taken that this is pretty complicated. This made me wonder if you could simplify and detach permitStoragePresent() entirely from cookies themselves (although it might need a different name?). In this model, there's no need to fuss around with a special authentication subdomain. Instead, each eTLD+1 can call document.permitStoragePresent from any subdomain or from the eTLD+1 itself, and that just marks a bit for that eTLD+1 in the browser. Then, any iframe from the same eTLD+1 can call document.isStoragePresent to find out if that bit is present, which implies true. Then if a user logs out, the browser calls document.removeStoragePresent(), or the bit is automatically cleared after 30 days or if the user clears cookies. This is effectively a single-bit cross-domain cookie, one per eTLD+1, that can be set and unset using a simple API that captures explicit user permission. I think this is much easier to wrap your head around. It would effectively be document.advertiseLoggedIn() / document.isLoggedIn().

At this point I think we should back out a little and look at what we're trying to solve.

A better solution here should simply be something like navigator.setLoggedIn(boolean, [optional sameOrigin], [optional timeToLive]) which by default sets logged in state for the eTLD+1 (sameSite) and allows for optional restriction to only cover the specific domain and an optional timeout.

This navigator.setLoggedIn() API would only be callable when the eTLD+1 is first-party site and the document from where the call is made has received a user gesture. That way, we'd have an accurate state instead of building something off of cookie state.

Then we could match that with the ability to ask navigator.isLoggedIn() in third-party iframes.

We would have to think through possible abuse scenarios but at least the above is simple enough for developers to use.

[Edit: Corrected a .loggedIn() to .setLoggedIn() for consistency.]

johnwilander commented Oct 10, 2018

But your point is well taken that this is pretty complicated. This made me wonder if you could simplify and detach permitStoragePresent() entirely from cookies themselves (although it might need a different name?). In this model, there's no need to fuss around with a special authentication subdomain. Instead, each eTLD+1 can call document.permitStoragePresent from any subdomain or from the eTLD+1 itself, and that just marks a bit for that eTLD+1 in the browser. Then, any iframe from the same eTLD+1 can call document.isStoragePresent to find out if that bit is present, which implies true. Then if a user logs out, the browser calls document.removeStoragePresent(), or the bit is automatically cleared after 30 days or if the user clears cookies. This is effectively a single-bit cross-domain cookie, one per eTLD+1, that can be set and unset using a simple API that captures explicit user permission. I think this is much easier to wrap your head around. It would effectively be document.advertiseLoggedIn() / document.isLoggedIn().

At this point I think we should back out a little and look at what we're trying to solve.

A better solution here should simply be something like navigator.setLoggedIn(boolean, [optional sameOrigin], [optional timeToLive]) which by default sets logged in state for the eTLD+1 (sameSite) and allows for optional restriction to only cover the specific domain and an optional timeout.

This navigator.setLoggedIn() API would only be callable when the eTLD+1 is first-party site and the document from where the call is made has received a user gesture. That way, we'd have an accurate state instead of building something off of cookie state.

Then we could match that with the ability to ask navigator.isLoggedIn() in third-party iframes.

We would have to think through possible abuse scenarios but at least the above is simple enough for developers to use.

[Edit: Corrected a .loggedIn() to .setLoggedIn() for consistency.]

@kushal

This comment has been minimized.

Show comment
Hide comment
@kushal

kushal Oct 10, 2018

At this point I think we should back out a little and look at what we're trying to solve.
A better solution here should simply be something like navigator.setLoggedIn(boolean, [optional sameOrigin], [optional timeToLive]) which by default sets logged in state for the eTLD+1 (sameSite) and allows for optional restriction to only cover the specific domain and an optional timeout.
This navigator.loggedIn() API would only be callable when the eTLD+1 is first-party site and the document from where the call is made has received a user gesture. That way, we'd have an accurate state instead of building something off of cookie state.
Then we could match that with the ability to ask navigator.isLoggedIn() in third-party iframes.
We would have to think through possible abuse scenarios but at least the above is simple enough for developers to use.

This makes a ton of sense, much clearer! :) And it would definitely address our needs and what I understand of the needs of others. I'm not even sure supporting the ability to toggle sameOrigin is needed, although the flexibility is nice. If there are still abuse concerns, would love to help work through possible mitigations.

kushal commented Oct 10, 2018

At this point I think we should back out a little and look at what we're trying to solve.
A better solution here should simply be something like navigator.setLoggedIn(boolean, [optional sameOrigin], [optional timeToLive]) which by default sets logged in state for the eTLD+1 (sameSite) and allows for optional restriction to only cover the specific domain and an optional timeout.
This navigator.loggedIn() API would only be callable when the eTLD+1 is first-party site and the document from where the call is made has received a user gesture. That way, we'd have an accurate state instead of building something off of cookie state.
Then we could match that with the ability to ask navigator.isLoggedIn() in third-party iframes.
We would have to think through possible abuse scenarios but at least the above is simple enough for developers to use.

This makes a ton of sense, much clearer! :) And it would definitely address our needs and what I understand of the needs of others. I'm not even sure supporting the ability to toggle sameOrigin is needed, although the flexibility is nice. If there are still abuse concerns, would love to help work through possible mitigations.

@michael-oneill

This comment has been minimized.

Show comment
Hide comment
@michael-oneill

michael-oneill Oct 12, 2018

I like this also. So I understand, does setLoggedIn replace requestStorageAccess i.e. an embed would no longer be able to get cross-domain cookies other than by calling setLoggedIn when the user actually logs in on a first-party site? Could we also have an optional parameter for a purpose declaration text string (no markup) to be displayed to the user in the UA prompt?

michael-oneill commented Oct 12, 2018

I like this also. So I understand, does setLoggedIn replace requestStorageAccess i.e. an embed would no longer be able to get cross-domain cookies other than by calling setLoggedIn when the user actually logs in on a first-party site? Could we also have an optional parameter for a purpose declaration text string (no markup) to be displayed to the user in the UA prompt?

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander Oct 12, 2018

I like this also. So I understand, does setLoggedIn replace requestStorageAccess i.e. an embed would no longer be able to get cross-domain cookies other than by calling setLoggedIn when the user actually logs in on a first-party site? Could we also have an optional parameter for a purpose declaration text string (no markup) to be displayed to the user in the UA prompt?

No. Sorry for being vague.

I meant that navigator.setLoggedIn() and navigator.isLoggedIn() would be independent web APIs, not tied to the Storage Access API. Third-party iframes who want to know whether or not it's useful to request storage access, can first call navigator.isLoggedIn().

Down the road, the Storage Access API could be restricted to require the logged in state to be set for it to provide storage access but that's not necessary.

johnwilander commented Oct 12, 2018

I like this also. So I understand, does setLoggedIn replace requestStorageAccess i.e. an embed would no longer be able to get cross-domain cookies other than by calling setLoggedIn when the user actually logs in on a first-party site? Could we also have an optional parameter for a purpose declaration text string (no markup) to be displayed to the user in the UA prompt?

No. Sorry for being vague.

I meant that navigator.setLoggedIn() and navigator.isLoggedIn() would be independent web APIs, not tied to the Storage Access API. Third-party iframes who want to know whether or not it's useful to request storage access, can first call navigator.isLoggedIn().

Down the road, the Storage Access API could be restricted to require the logged in state to be set for it to provide storage access but that's not necessary.

@johnwilander

This comment has been minimized.

Show comment
Hide comment
@johnwilander

johnwilander commented Oct 18, 2018

Mozilla has published documentation on this API: https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment