#331: Portals

Visit on Github.

Opened Dec 4, 2018

こんにちはTAG!Bonjour le TAG!

I'm requesting a TAG review of:

Further details (optional):

You should also know that...

  • Background for this work:
  • TAG finding
  • AMP blog post
  • WICG thread
  • Demos at Chrome Dev Summit with a prototype: this might help understand some of the use cases.
  • There is an experimental implementation in Chrome but it's missing key features. We expect to have something useful behind the flag in a couple of weeks.

We'd prefer the TAG provide feedback as (please select one):

  • open issues in our Github repo for each point of feedback
  • open a single issue in our Github repo for the entire review
  • leave review feedback as a comment in this issue and @-notify: KenjiBaheux, jeremyroman, lucasgadani (because the repo is temporary)

Discussions

Comment by @torgo Feb 5, 2019 (See Github)

On our f2f agenda for Wednesday 6-Feb.

Comment by @dbaron Feb 6, 2019 (See Github)

We had a 45-minute discussion of this at our Tokyo face-to-face (Wednesday 2019-02-06, 14:35 to 15:20); the minutes should be available tomorrow. One of the outcomes was that we're hoping to get a little more information added to the explainer that we'll then read and probably have some more feedback on.

We'll want to come back to this at some point in the future.

Comment by @dbaron Feb 7, 2019 (See Github)

I think a few of the things we discussed were:

  • We need to get a clear idea of how this differs from <iframe>
    • this will both provide input into the decision about whether it should be an attribute on <iframe> or its own element, and
    • this will also help review what's actually going on.
  • There was a bunch of discussion about things such as whether something loaded in a portal behaves for a bit like it's in a unique origin, and then transitions to being the real origin... and if so how that would work. I don't think the sense of the room was that it was clear that any of the options discussed were workable, but we didn't even understand which option was being suggested (hence the previous comment).
  • a bunch of other things (see the minutes)
Comment by @lucasgadani Feb 8, 2019 (See Github)

Thanks for the feedback.

I've looked through the notes, and would like to address some of the points discussed:

  • Why are we proposing this as a new element instead of an attribute on <iframe>:
    • Immutability of the frame tree: The web platform contains many assumptions about the immutability of the frame tree, in particular, the fact that a frame's parent never changes. Chrome experimented in the past with magic iframes, which allowed some iframes to be reparented. This has caused many issues that have lead to the removal of the feature.
    • In order to mitigate some of the risks, we are proposing that portals should not have their WindowProxy's exposed to their embedders. In particular, this implies that they would not be part of the same unit of related browsing contexts, and the only means of communication between a portal and its embedder would be via asynchronous APIs (such as postMessage). This also has other advantages, as it would allow implementers to use separate threads/processes for content embedded in a portal, resulting in better performance.
  • At least for the initial version of portals, we are planning to have a page embedded in a portal behave more or less like a tab, so any privacy-preserving pre-rendering would have to be guaranteed by the embedding page. That means that things like state or storage would be allowed inside the portal (as its real origin) and our expectation is that the embedder would inspect the content being served (either via a CDN or SXG) in order to guarantee the user's privacy. In the future, we'd like to explore other options, such as restricted storage and network access in order to lower the requirements on the embedder page to guarantee privacy, but it's important to note that the embedder page will always need to cooperate with the portal to some extent in order to achieve privacy preserving pre-rendering.
Comment by @othermaciej Feb 9, 2019 (See Github)

That means that things like state or storage would be allowed inside the portal (as its real origin)

That sounds like a privacy showstopper for browsers that try to limit cross-site tracking.

Comment by @cynthia Feb 9, 2019 (See Github)

I’m assuming the concern is about cross-site tracking through mechanisms like URL query parameters? (I’ve seen Facebook do this.)

(Since window isn’t exposed, seems like this would be the easiest mechanism to exploit)

Comment by @othermaciej Feb 9, 2019 (See Github)

@cynthia To expand on this a bit:

The portal host can send any information it wants to the <portal>, either by encoding it in the URL, or by sending it via postMessage(), since it has access to postMessage() the guest browsing context. This could include the URL of the page, or a logged in user ID.

Why is that a problem?

Many browsers deny access to cookies and other state in a third-party context, including cross-origin iframes. Safari has done so for a long time, and continues to expand those protections with various forms of partitioning and complete blocking. Firefox is moving in this direction as well.

So if a site passes info to an <iframe> in a browser with tracking protection, the origin inside the frame won't be able to associate that with a tracking cookie. For example, if a social or video embed is also a very popular site that many users are logged into, it won't be able to associate this page visit (or whatever other info got passed) with your login cookie.

Per @lucasgadani, the plan for <portal> is that content inside the portal gets full access to state and storage. This would completely break that privacy protection. If browsers implemented this proposal, and if embeds switched from iframe to portal embedding, they could completely bypass tracking protection and would once again be able to freely track users across the web.

(This concern does not apply to browsers that lack any built-in on-by-default tracking protection, such as Chrome.)

Comment by @lucasgadani Feb 11, 2019 (See Github)

Thanks for the feedback @othermaciej. I completely agree with you that browsers that already support tracking protection through a storage API should continue to do so inside a portal. In fact, this is something we have described in the explainer.

That said, as you mentioned, Chrome does not currently have any built-in tracking protection, and given that our implementation is on top of Chromium, we are trying to keep our scope manageable, so we are not tackling the storage access just yet on our implementation.

At this point, our main focuses are:

  • Solving the origin attribution problem.
  • Providing a richer API that allows developers to implement faster navigations and more interesting page transitions.
Comment by @jeremyroman Feb 11, 2019 (See Github)

It seems to me that third-party content inside a portal could be restricted in a similar way to third-party iframes in those UAs, as long as those restrictions could be lifted on activation.

If I understand correctly, WebKit's mechanism does have a way of lifting storage access restrictions at runtime already. Do you think it would be fundamentally incompatible with this approach?

Comment by @othermaciej Feb 12, 2019 (See Github)

@jeremyroman Unfortunately, I think restricting in a portal and then lifting those restrictions on promotion is not workable. So this would remain a showstopper for Safari (and maybe Firefox too, not sure of their tracking protection details these days).

To expand a bit: we have a way of lifting storage restrictions based on an API call for the site, with user consent (it pops up an alert). It's called Storage Access API. Mozilla also implements this API. Lifting storage restrictions transparently without any interaction by the site would likely not work. Sites would get a mix of data from different storage partitions if they were not prepared for this happening. Or they might see only the stale info. The site has to know to reload the relevant state, which is why we ask embeds to opt into this. Based on this, auto-promoting portals to unrestricted storage when they get promoted to full screen is likely not viable.

Comment by @jeremyroman Feb 13, 2019 (See Github)

@othermaciej As I understand it, Safari's model allows for certain interactions (like a user gesture, conditionally paired with a user prompt) to change the UA's answer as to whether storage access should be granted to content which was loaded in a third-party context, and an API for authors to indicate that the document is prepared for a change in its storage access.

Portal activation is conceptually similar to navigating the browsing context (possibly cross-origin), and as I understand it Safari's model does grant storage access to the document that is navigated to. Given that, would something like this work (deferring the actual access change until the document requests it)?

onload = async function() {
  const supportsStorageAccessApi = !!document.hasStorageAccess;
  const canPersonalize = !supportsStorageAccessApi || await document.hasStorageAccess();
  if (canPersonalize)
    populateWithPersonalizedContent();
  else
    populateWithGenericContent();
};

onportalactivate = async function() {
  if (hasBeenPersonalized || window.portalHost)
    return;

  // This was activated into a top-level context, so the UA can
  // reasonably approve this storage request without prompt.
  await document.requestStorageAccess();
  populateWithPersonalizedContent();
};

There's a more uncommon case in which a nested portal is promoted into a context which is first-party to the top-level context (A->B->A becomes A->A) where it might be useful for the author to be able to request storage access but accept a silent refusal instead of triggering a user prompt, but I don't see that case being common at all.

Comment by @othermaciej Feb 13, 2019 (See Github)

@jeremyroman I am not sure if I fully understand what your script is trying to do, sorry.

I think you are suggesting that webpages could be modified to request storage access when promoted from a portal to top level, and that access could be always granted and without the need for a user action or user consent. This wouldn't confuse those pages with unexpected mixes of storage. But it also wouldn't work in unmodified webpages. They would end up always stuck on restricted/partioned storage even after promotion, even in this implied proposal. Remaining stuck on the partitioned storage is also a privacy risk, because it would give what appears to be a top level page access to a partitioned storage in a particular domain. A site could rewrite itself to always use immediately activated portals to effectively gain cross-site tracking capability.

The one thing I can think of that might work for privacy purposes is to completely deny all storage access (even cookies) while in the portal, but allow the site to request storage access on activation as you suggest. I am not sure of the web compatibility of this approach.

Comment by @jeremyroman Feb 13, 2019 (See Github)

@othermaciej

I think you are suggesting that webpages could be modified to request storage access when promoted from a portal to top level, and that access could be always granted and without the need for a user action or user consent.

Yes, this is what I'm suggesting.

But it also wouldn't work in unmodified webpages.

Yes, it wouldn't be transparent to unmodified documents. This isn't the only way in which a document may have its context meaningfully changed by transitioning from being embedded to not, so we're still contemplating whether content should have to opt-in to being loaded in a portal context (which reduces surprise, since it gives a signal that authors have given some thought to the consequences), or opt-out (for reasons similar to frames, content must be able to refuse to be embedded).

Remaining stuck on the partitioned storage is also a privacy risk, because it would give what appears to be a top level page access to a partitioned storage in a particular domain. A site could rewrite itself to always use immediately activated portals to effectively gain cross-site tracking capability.

I admit I don't really understand how what you're proposing here would allow pervasive tracking, but if so, having the UA choose to provide no storage access instead of partitioned storage in such cases seems like a viable approach to me.

Discussed Mar 12, 2019 (See Github)

KC: nothing much has happened since f2f.

Dan: who are we waiting for feedback from?

KC: we got them to to back to the drawing board and consider if it could be based in iframes.

David: we had comments on their explainer.

David: has the explainer been updated?

Lukasz: the document is unfinished in my opinion - i am seriously concerned with the privacy [discussion] in the github thread. data leaks between the origins. not clatified in thread.

Dan: maybe bump and come back to it?

Peter: bump and wait?

KC: lot of feedback from Alex Russell here.

KC: I can monitor it.

Peter: kicked it 3 weeks

Comment by @dbaron Mar 13, 2019 (See Github)

So one of the recent additions to the explainer was:

How does this work in browsers that restrict third-party cookies?

We imagine that in such cases, the browser would provide functionality for gaining access to first-party cookies (and other storage) at the author's request after activation. For instance, the browser could allow using the Storage Access API for this purpose.

This doesn't seem sufficient for anything that works by keying storage to the pair of the toplevel origin and the frame origin (known as "double-keying"). I'm not sure which (if any) browsers use double-keying today for which kinds of storage, but it's certainly been something that's been discussed in the past.

This would break double-keying because it would transition script from being in one pair to another, and allow matching the storage from one to the storage from another.

I don't see an obvious solution to this within the double-keying model.


Additionally, I still don't think the explainer answers the key question of how this differs from iframe. To consider a few of the many possible examples: Is the document in the portal able to request permissions? Does feature-policy delegation from the containing document still matter? What about the various mechanisms referenced in the first two comments of w3ctag/design-principles#41?

I don't think we necessarily expect complete answers at this stage of the design, but if not answers it would be good to at least understand your current intentions and how you plan to make those decisions.


I agree that using a new element name rather than an attribute is convenient since it means you don't have to worry about the portal-ness changing dynamically; however, there are certainly other ways to restrict dynamic changes. And it still seems quite concerning given how much this has in common with iframe.

Discussed Apr 3, 2019 (See Github)

Ken: David summarized a bit.

GOTO JUMPBACK;

PORTALS:

Ken: Two big issues, why is this not an iframe, tried on Chrome but didn't work out well. FP didn't work well for Portals. The explainer needs to be clarified why it can't be an iframe, also there was the part about double keyed cookies. Some comments on the

Sangwhan: When you jump into the portal by throwing out the existing state it won't work..

Ken: kind of the point...

Sangwhan: i don't know about others but I feel like this is rather inellegant. We've done so much work - one weird element iFrame that we've spent a lot of time making it work.

Ken: they are trying to work around restrictions with iframe but ... really really good explanation of why this is not an iframe. and how they are going to solve these points of different specs refering to iFrames.

Sangwhan: Wonder if there will be other cases aside from AMP that would benefit from this.

Kenneth: Commerce might, Denmark has a bunch of third party payment handlers running on different origins.

Sangwhan: That feels like web payments would be the solution, doesn't feel like the right tool for this.

Dan: Parenthetically: there is an advisory council about AMP which some signers of the AMP letter have been a part of. If anyone is interested I can explain later.

Kenneth: Explainer could use a bit more detail on use cases. Should ask for a update.

Alice: There is a key scenarios link from the original request.

Ken: "nice transition" [as a key feature]

Alice: use case down at the bottom is interesting - making a multi-page application look like a single-page application.

Ken: you might not need all these things for same originl - so you could make a simnpler solution that works for same origin.

Dan: The provenance of the content has been a constant issue, and a smooth transition could actually obstruct that there is a change of the origin.

Hadley: It feels like a feature to work around SOP.

Peter: If you embed a third party origin as yourself, and then switching over without a transition doesn't seem right.

ylafon: https://github.com/jakearchibald/navigation-transitions

Dan: We have provided feedback, whether or not that is enough and whether this is addressable is something we should follow up on.

Comment by @kenchris Apr 3, 2019 (See Github)

iframe is one of the features that has required a lot of work to get right (it is a bit alien on the platform and has resulted in a lot of corner-cases) and which is referred to in multiple places and different specs.

How are you going to handle all of these, like feature-policy, as pointed out by @dbaron above.

We are a bit afraid that this feature will land and it will be a multi-year effort to make it integrate properly in the web platform, similarly to iframes.

I think that you can calm our nerves by going through specs mentioning iframe like HTML and look at all the cases and see if things would work as they are for portals or need monkey patching.

Like you need to define how this works for browsing contexts: https://html.spec.whatwg.org/multipage/browsers.html#windows

Also check all cases involving iframes like fully active etc. https://html.spec.whatwg.org/multipage/browsers.html#fully-active

Discussed May 8, 2019 (See Github)

Alice: there was a talk about it at I/O

Tess: how should we handle cases where we generated questions during our review and they go awol? Seems like we shouldn't leave the issue open indefinitely.

Dan: I think we at least need some additional labels to show when TAG feedback isn't acted on...

Alice: we need a time-out state

Tess: follow-up question which is a blink question... is the expectation that raising the question to the tag satisfies the blink process requirement or are they expected to take the feedback into account.

Alice: that's an active question. It suffices to file a review - the gate is a "lgtm" - link to the review - at the intent-to-ship stage you should already have a review. if in between those things the TAG review hasn't happened, it is up to the API owners to make a judgement call. If they look at the TAG review thread and see that the requester hasn't taken the feedback onboard then they might not progress it.

Alice: what is the user-facing [end user facing] problem that this solves, what is the proposed solution, worked excamples showing how the solution solves the problem...

Hadley: this solves a frustration I have where we are getting specs that are for developer needs as opposed to user needs.

Alice: yeah, though there are many dev-focused specs that have an end user benefit e.g. Intersection Observer.

Dan: I'd like to cover a lot of this in the f2f - including how we can be more effective / responsive to review requesters....

Alice: the last 2 comments are from us - we haven't heard from blink since feb 14.

[...discussion on closing it...]

David: there's a bunch of stuff we don't udnerstand about the design.. feels like this feature has moved forward [in blink]

Alice: we could say "we have had this feedback - no responses..."

Dan: is this overtaken by events?

Tess: I have concern - minting a new element that is a way of embedding other content. Is adding new things like this something we should be doing instead of adding these features to iFrame. I feel like adding a feature like this has to pass a pretty high bar. Yes it's been overtaken by events in the sense that [blink] has proceeded full teams. I'm concerned about closing it "overtaken by events" and they look at this as tacit approval.

Alice: seems like there are valid concerns - listing them out succintly...

Tess: [takes an action to summarize state on the issue] Peter and Dan can you try to figure out set of new labels to use for this.

Dan: I'll do some research and propose something on slack.

Hadley: we could use something like "unresolved"

Tess: where we close issues and are not satisfied - in TC39 and WHATWG they have "needs x" labels. We could have "needs explainer"

Dan: I'll add it

Comment by @jeremyroman May 13, 2019 (See Github)

Apologies that we haven't been more responsive in this discussion recently. We do realize that there are significant unresolved issues here (including whether the feature ought to be exposed as a new tag name or be controlled by a content attribute on the existing <iframe> element).

We intend to follow up on these concerns shortly, and though we are experimenting with the feature in Chrome, we have no intention of shipping with this feedback unaddressed.

Comment by @domenic May 13, 2019 (See Github)

To @kenchris's point, I want to note that in my role as HTML spec editor, I've been really, really happy and excited about the idea of portals as "iframes done right". Although popular articles or explainers may focus on the flashy features like transitioning the URL bar or adopting your predecessor, @jeremyroman and others have put a lot of thought into the foundations. For a spec that is still in the experimentation stages, it's quite solid and integrates well with existing primitives.

For an example of what I mean by "iframes done right", iframes have many features that complicate their model. Those features can be convenient at times, but in my opinion don't pull their weight for the complexity they add.

The biggest of these is synchronous access to the framed document. This has caused huge spec complexity, security, and implementation hurdles, which we are still sorting out today. Portals omit that, in favor of simple postMessage-based communication. Other such features are things like srcdoc, the observable initial about:blank transition, the weird load event (still buggy), etc.

I do think there are still some things that need porting, such as the story around feature policy/sandbox. But even that will be a simplification opportunity, most likely; instead of allow + allowfullscreen + allowpaymentrequest + sandbox, I'm hopeful we'll have something more coherent and unified.

Finally, the biggest missing piece is session history integration, tracked at https://github.com/WICG/portals/issues/19. That will affect things like "fully active", indeed. This is complicated by known issues with the session history spec. Perhaps more generally, there are probably other things where the notion of "nested browsing contexts" should apply to portal browsing contexts as well (e.g. update the rendering?). Portals add more complexity here on top of iframes due to the activation possibilities. Still, I am confident that because portals allow us to start with a clean slate, and because they decrease the synchronous observable interactions, the editors will be able to find and spec a model that works well.

I hope this helps!

Comment by @jeremyroman May 15, 2019 (See Github)

Here is an expanded explanation of our current thinking on the question of introducing a new <portal> element, compared to adding an attribute to the existing <iframe> element.

Comment by @jeremyroman Aug 14, 2019 (See Github)

This issue is still marked as "pending external feedback", but I believe we have replied to the concerns raised. Are there further issues we need to address before TAG can take another look?

Comment by @plinss Sep 10, 2019 (See Github)

Discussed at our Tokyo F2F.

We keep coming back to the element vs attribute discussion, some of the reasons we've heard about the need for a new element seem to stem from implementation difficulty. We feel that those reasons violate the priority of constituencies, by putting implementation concerns before those of authors.

Regarding the notion of iframe's "done right", we accept the fact that iframes have a lot of baggage. If the real need here is to fix iframes, then let's fix iframes. Perhaps we should be creating a new element (or set of interfaces) that can serve as the base class for embedded content with a simplified model. Then special case elements that provide extra behaviors and properties serving the various use cases for iframes can be built on top of that model in a cleaner fashion. Rather than build yet another higher-level special element with a bunch of unique attributes, we'd rather see a layered approach that exposes the various primitives and needs of embedded content in its different forms.

Comment by @plinss Dec 5, 2019 (See Github)

Discussed again at our Cupertino F2F with @hober, @dbaron, and myself. We feel that we had a good discussion with you, while in Tokyo last, about our concerns with the current state of the proposal and the direction we'd like this to take instead. We're going to close this issue for now, please ping us to reopen or file a new one when the next steps are ready for review.