#888: Web Install API - Same Origin

Visit on Github.

Opened Aug 29, 2023

Hola TAG! I'm requesting an early TAG review of the Web Install API.

The Web Install API allows a web site to install a web app (same domain). This functionality allows the creation of web based catalogues that can install PWAs directly from the web and into multiple platforms.

  • Explainer¹ (minimally containing user needs and example code): Explainer
  • User research: N/A
  • Security and Privacy self-review²: Security Questionnaire
  • GitHub repo (if you prefer feedback filed there): GitHub repo
  • Primary contacts (and their relationship to the specification):
  • Organization/project driving the design: Microsoft Edge
  • External status/issue trackers for this feature: Chrome Status

Further details:

  • [ X ] I have reviewed the TAG's Web Platform Design Principles
  • The group where the incubation/design work on this is being done (or is intended to be done in the future):
  • The group where standardization of this work is intended to be done ("unknown" if not known): Unknown/webapps
  • Existing major pieces of multi-stakeholder review or discussion of this design: N/A
  • Major unresolved issues with or opposition to this design: N/A
  • This work is being funded by: Microsoft Edge

You should also know that...

there's plenty of positive developer feedback for an API like this one!

We'd prefer the TAG provide feedback as (please delete all but the desired option):

🐛 open issues in our GitHub repo for each point of feedback

Discussions

Discussed Sep 1, 2023 (See Github)

Dan: there's going to be a breakout on installation at tpac, but I can't be there. Sangwhan can you be there?

Sangwhan: yes

Discussed Sep 1, 2023 (See Github)

Tess: there was a breakout at TPAC that I attended - I gave the authors a lot for feedback. tl;dr the core idea navigator.install being an API that would invoke the UA's install flow - is a good idea - we should do something like that. Everything else is fuzzy - lots of additional complexity - they are imagining a fairly complex future where you have a web app that's an app store for other webapps.. I get why but it feels like a lot more complexity... If there's a user gesture restriction on navigator.install and same origin only - this seems sensible. It's easier to envision that flow as something browsers might be willing to expose to users. The indirect case ... might enable malicious actors...

Dan: there does need to be a permission granted from the webapp manifest file to which origins are allowed to install it...

Peter: they want to know if it's been installed...

Tess: they want to know if'ts already installed - but a malicious opt in ...

Dan: it would be interesting to see if we could get broad consensus for a same-origin only navigator.install - and then build from there...?

Tess: we shouldn't block the simple case that we already have consensus on ...

Lea: makes sense.

Peter: they say "the biggest risk is installation spam" - i don't think that's the biggest risk...

Tess: open question in browser land about PWAs and capabilities - because the user installed the thing do you give it more capabilities or not. Mozilla has held the line that you shouldn't. One concern here - if you trick a user into installing a thing - it's a PWA - but if the browser / OS platform gives additional capabilities to installed webapps then this now has those capabilities... Do PWAs get certain capabilities for free - this makes that attack more concerning. There's a coupling - the easier you make it to install a thing, the woser it is to allow PWAs to have additional capabilities...

<blockquote> Hi @diekus - thanks for this and thanks also for the TPAC session on this topic which was really interesting!

Some initial feedback form our TAG breakout today:

We're concerned about potential abuse of the "Web app installation from associated domain" use case, especially in a world where installed webapps might be auto-granted additional permissions.

We're generally happy with the same-origin-bound use case of navigator.install(). We're wondering if you might consider a phased approach to this where phase 1 tackles the same origin case and phase 2 works on the more complex use cases - as this will give some opportunity to explore how the installation function itself works and will give time to explore and design mitigations for potential abuse cases for associated domain installation.

We think the expected venue should probably be Web Applications working group (after this graduates from WICG) and/or the WHATWG HTML workstream.

</blockquote>

Dan: leaves comment

Comment by @iVanlIsh Sep 5, 2023 (See Github)

I got a few questions:

  • Is it true that any random Origins will be able to show an APP installing permission? That sounds like a spam to me. Maybe a "don't show any" option would make sense?
  • Does the APP need to go through some reviews or be the existing APPs in a former APP store? Or will there be any restrictions/warning? If not, this means allowing users to jump outside the security boundary of the browser by a browser prompt in a sudden to a world that the APP might access every information.
Comment by @torgo Sep 7, 2023 (See Github)

Hi @diekus we discussed briefly in today's TAG session and someone from TAG will be at the breakout session you're holding at TPAC next week so we hope to progress then.

Comment by @torgo Sep 25, 2023 (See Github)

Hi @diekus - thanks for this and thanks also for the TPAC session on this topic which was really interesting!

Some initial feedback form our TAG breakout today:

We're concerned about potential abuse of the "Web app installation from associated domain" use case, especially in a world where installed webapps might be auto-granted additional permissions.

We're generally happy with the same-origin-bound use case of navigator.install(). We're wondering if you might consider a phased approach to this where phase 1 tackles the same origin case and phase 2 works on the more complex use cases - as this will give some opportunity to explore how the installation function itself works and will give time to explore and design mitigations for potential abuse cases for associated domain installation.

We think the expected venue should probably be Web Applications working group (after this graduates from WICG) and/or the WHATWG HTML workstream.

Discussed Dec 1, 2023 (See Github)

No reply from them since Sept, marked pending external feedback. Dan to nudge Diego

Comment by @torgo Dec 18, 2023 (See Github)

Hi @diekus any update on this from your PoV? Thanks!

Discussed Jan 1, 2024 (See Github)

Dan: We received feedback from Diego...

Discussed Jan 1, 2024 (See Github)

assigned to Tess & Lea - noting that we got feedback from Diego and should therefor discuss this week assigned to 7b

Comment by @diekus Jan 18, 2024 (See Github)

Hola TAG. I've missed you ✨.

So getting back to business. We've completely reworked the shape of the API. Both explainers (for same and cross-origin) have been updated and I am pleased to inform you of the following:

(cc @iVanlIsh)

  • an origin can request permission to install web applications, the same way it can request for geolocation and camera access. Even if this permission is granted by the user, web apps/PWAs would need to list this origin in its install_sources for them to be installed. This means that the origin can't simply start installing random content or apps even if it has permissions. These permissions can also be set to expire by the implementor. I agree that having a "don't show any" option on the prompt is a good idea, and in a similar way to expiration, this is relevant to the specific browser UX implementation.

  • the content/app does not need to go through review neither does it need to be already in an app store. This would be terribly limiting to a lot of content and would put the final decision of installation in the hands of a few app stores, defeating the purpose of a better, fairer and more democratic distribution process. We believe the user is the one that should always be in control of what content they want to install. The idea of the API is not to comply to existing reviews or guidelines set by app stores... it is only to install an app. For same-origin content, this is not different to going onto Safari and adding the content to the Dock, or in a Chromium browser to add the app to the homescreen/start menu. For cross-origin content, the app will comply with installability criteria that is defined by the browser. In Chromium this means it must have a manifest with a field that allows the installation from the installation origin, is delivered over HTTPS and complies with a set of security and privacy considerations. It doesn't allow users to jump outside of the security boundary of the browser since the app that is being installed is web content.

(cc @torgo)

  • the main use case is to allow installation of web content (apps). Content installed using the navigator.install method does not inherit or auto-grant permissions from the installation origin. The API does not break the same-origin security model of the web. These remain independent and fully customizable by the user. Nothing is actually changing here, as each origin has its own set of permissions and there is no scenario or use case where a third party domain could set these for the installed app.

  • We have considered a phased approach, starting with same-origin (and looking for consensus with other vendors, which is something I am excited about tbh) and then cross-origin. Both scenarios are quite similar in how they are used, we wanted to achieve consistency between both use cases and make them very similar. I must note that the cross-origin scenario has tougher security constraints, as it is a new capability that until now hasn't been possible in the web platform. Same-origin installs is something that is already doable on the Web.

We've got several store partners in line to try it, including 3P developers that are very excited about the possibilities to democratise application distribution!

I whole heartly agree with you that WebApps WG is the right place for this work 💖.

Discussed Apr 1, 2024 (See Github)

Questioning what a manfest id is, and why use that instead of a url to the manifest.

Questioning why cross-origin re-invents a CORS-like mechanism for install sources.

  • Discussed that the web needs a cross-server mechanism to declaratively set server beahviors, like setting headers.

Issues:

  • Separate the two reviews

Same-origin:

  • Related apps doesn't make sense without cross-origin version of the API

Cross-origin:

  • CORS vs manifest fields
  • What is a manifest id?
Discussed Apr 1, 2024 (See Github)
<blockquote>

Hi @diekus, after reading your comment both @plinss were still confused about several aspects of this API:

Wrt related_applications:

  • We don’t understand what the use cases are. Say, I have a website with a manifest file. Why would that website prefer to be installed from another repository instead of using itself as the source of truth? What are the use cases? Is it monetization? Analytics? Something else?
  • Orthogonal to the use cases, it seems like it would require the Cross-Origin version of the API to work? How is related_applications useful if it's restricted to the same origin?

Wrt installing multiple PWAs from the same origin and related_applications / prefer_related_appliations:

When separating the API into a same-origin and a cross-origin version, it’s important that the separation is "clean", i.e. that the same origin version can be implemented independently and no parts of it should require the cross-origin version of the API. With that in mind:

  • It is unclear to us what same origin use cases the parameters of the navigator.install() function serve, since it seems they are primarily geared around verification, which is not really needed in the same origin case.
  • Same for the arbitrary referral-info parameter: what is the use case for it in a same-origin context?
  • Same for related_applications / prefer_related_appliations: it seems that for these to function they require the cross-origin version of the API?

Also, given the text in the explainer, it is still unclear to use what the author flow is for e.g. having a website that includes multiple apps (website.com/foo, website.com/bar, etc.). A code example would help!

We also don’t quite understand the signature of navigator.install(): it seems that manifest_id is optional but it is possible to provide manifest_id without install_url. What is the use case of that in a same-origin context? It also seems like in the case of a single website containing multiple apps, one would probably want to provide an install_url, and it seems like it's the manifest id that should be optional?

Also please note that TAG principle around preferring a dictionary for optional arguments.

</blockquote>
Comment by @plinss Apr 15, 2024 (See Github)

Given that the request has split into same-origin and cross-origin versions, we split the review accordingly (as we feel one may be able to proceed faster than the other). This review is now about the same-origin behavior, the cross-origin behavior issue is here

Comment by @LeaVerou Apr 15, 2024 (See Github)

This generally looked good to us. Our only comment relates to "related applications". We did not understand what this is for, but it seems to require the Cross-origin version of the API to work. If that assumption is correct, it should be moved there. It is also unclear how navigator.install() supports the use case of multiple PWAs that live under the same origin.

Comment by @diekus Apr 16, 2024 (See Github)

Hola @LeaVerou, thanks for your valuable feedback.

The related_applications part refers to the behaviour an implementer might take when the install API is invoked and that field is present in the manifest file. If present, this means that the developer would prefer their app to be installed from another repository (like the itunes store or the play store) instead. If this is the case, this field points to the appropriate repositories per platform and the UA may decide to handoff the installation to that repository. The alternative is the default method where a web app is packaged and installed by the browser.

Regarding multiple apps on a same origin, they can be installed as they can have different manifest ids and different scopes. For example, https://example.com/app1 and https://example.com/app2 can both be installed even if from the same origin.

Comment by @LeaVerou Apr 22, 2024 (See Github)

Hi @diekus, after reading your comment both @plinss were still confused about several aspects of this API:

Wrt related_applications:

  • We don’t understand what the use cases are. Say, I have a website with a manifest file. Why would that website prefer to be installed from another repository instead of using itself as the source of truth? What are the use cases? Is it monetization? Analytics? Something else?
  • Orthogonal to the use cases, it seems like it would require the Cross-Origin version of the API to work? How is related_applications useful if it's restricted to the same origin?

Wrt installing multiple PWAs from the same origin and related_applications / prefer_related_appliations:

When separating the API into a same-origin and a cross-origin version, it’s important that the separation is "clean", i.e. that the same origin version can be implemented independently and no parts of it should require the cross-origin version of the API. With that in mind:

  • It is unclear to us what same origin use cases the parameters of the navigator.install() function serve, since it seems they are primarily geared around verification, which is not really needed in the same origin case.
  • Same for the arbitrary referral-info parameter: what is the use case for it in a same-origin context?
  • Same for related_applications / prefer_related_appliations: it seems that for these to function they require the cross-origin version of the API?

Also, given the text in the explainer, it is still unclear to use what the author flow is for e.g. having a website that includes multiple apps (website.com/foo, website.com/bar, etc.). A code example would help!

We also don’t quite understand the signature of navigator.install(): it seems that manifest_id is optional but it is possible to provide manifest_id without install_url. What is the use case of that in a same-origin context? It also seems like in the case of a single website containing multiple apps, one would probably want to provide an install_url, and it seems like it's the manifest id that should be optional?

Also please note that TAG principle around preferring a dictionary for optional arguments.

Comment by @diekus Jun 26, 2024 (See Github)

Hola @LeaVerou and @plinss,

Thank you for your patience. I will try to answer your doubts to the best of my knowledge.

Wrt related_applications and prefer_related_applications

When referring to related_applications, it is the developer the one that specifies that they'd rather have the app be installed from another place instead of, as you put it, "using itself as the source of truth". I 100% agree with your view.

I believe this was more relevant when PWAs started in mobile and were mostly a run-down, "lite" version of the native/platform-specific counterpart. Similar behaviour is present in Safari when it adds a "Smart App Banner" prompting that there is a related application on the App Store. I am personally not a fan of these behaviours, nonetheless, I believe if a developer prefers to have their app installed from the platform's app-repo, and explicitly adds the related_applications and prefers_related_applications fields to the manifest, then the installation should try to respect that.

Now, I also believe this is up to the implementer if they want to honour that request the developer is doing. Safari does this with the meta tag apple-itunes-app. On the other hand, the proposal in WICG and documented in MDN WebDocs accomplishes this same behaviour through those fields in the manifest file, and if implemented into the official Manifest spec, would include support for multiple platforms, including the Apple App Store, Google Play and MS Stores.

I put this in the explainer in the section of "Relation with other web APIs" as I think the installation flow could be different if these fields are present in the manifest file. Again, implementors could decide to ignore these or to implement different UX (like showing the install prompt with an option for the end user to choose where they would like the app to be installed from, for example). These are orthogonal to the API itself, and same-origin use cases are completely independent of the cross-origin ones.

Wrt same-origin parameters and referral-info

The parameters are there as a way to pass more information if the developer needed. For example, with the referral-info, a user might be browsing in siteA.com, see an ad for appB, click on that ad that takes them to siteB.com, and siteB.com can retrieve the campaign id associated to that referral and pass it as a parameter when it is installing itself to remember a possible associated campaign effort.

There is currently an ongoing discussion about the requirement of manifest_id as a parameter for same-origin installs. At the moment same-origin could install any web content (as per Webkit's petition), whilst the option of allowing content with a manifest id only. I will promptly update the explainer and post back here once consensus is reached on this.

Wrt to optional parameters

I will update the explainer to reflect that it is a dictionary, not an object as it is currently stated. (and thanks for the heads up!)

Discussed Aug 1, 2024 (See Github)

This is waiting on proponents still.

Discussed Aug 1, 2024 (See Github)

Peter: there is a lot of commonality with cross-origin... e.g. manifest IDs... a lot of these features in the same origin case seem to be tied into cross origin...

Dan: feels like same origin API should be the less contraversial and simpler thing...

Peter: .. i think certain things (like IDs) are in there to support the cross-origin cases. So why have an ID separate from the URL? Why not just the URL of the webapp? You're giving the URL of the webapp you's installing... so don't see what the ID does. The reason for having the ID in the API is when you're installing an app that doesn't have a manifest... so having that ID is only useful in the appstore context.

Dan: Having an ID ... unique ID ... that is extraneous to the URL for the APP... is adding developer complexity...

Peter: I'm ok with being OK with this API but pushing back on "why the ID"?

<blockquote>

Hi @diekus we discussed on today's call. One thing we are not clear on is the need for the separate ID in the case of same origin installation. Are there other cases, not related to app store cases, that would require a separate ID (separate from the URL to the webapp itself)? Otherwise it seems like this could be simplified (and thereby reduce developer complexity) by removing the need for a separate ID?

</blockquote>

Dan: leaves comment

Discussed Aug 1, 2024 (See Github)

Dan: outlines history

Jeffrey: seems like cross-origin case exists in order to compete with native apps so - do we think of new APIs as changing the web or changing the whole ecosystem... centralization/ decentralization...

Tess: I usually talk about ... camp that thinks that the web and native are in competition... and that's the battle ... there's another camp that sees them as complementary... The first camp can often come across as antagonistic towards native & think we need feature parity..

Tess: on same origin... are we agreed that any web site can call it? Originally there were a bunch of requirements - e.g. manifest, manifest can have a bunch of things in it... to me, as long as it's gated on a user gesture, it feels like any web site can call it.

We take a look at the explainer - it says

In order for an application/site to be installed, it must comply with installability criteria. This criteria is entirely up to the UA, can vary depending on the installation target, and can be optional.

Tess: I get that...

<blockquote> Hi Diego - thanks for sending this our way. We're happy to see this move forward and would like to review again when you have a specification in the Web Apps working group.

We're happy to see that the installability criteria is indicated as up to the UA.

We're going to close this for now with a satisfied label. Please ping us to re-open when you want a follow-up review.

</blockquote>

Dan: we can review at the plenary.

Comment by @diekus Aug 12, 2024 (See Github)

gentle ping, would love to continue with work on Web Install! @LeaVerou @plinss @torgo

Comment by @torgo Aug 12, 2024 (See Github)

Hi @diekus we discussed on today's call. One thing we are not clear on is the need for the separate ID in the case of same origin installation. Are there other cases, not related to app store cases, that would require a separate ID (separate from the URL to the webapp itself)? Otherwise it seems like this could be simplified (and thereby reduce developer complexity) by removing the need for a separate ID?

Comment by @diekus Aug 13, 2024 (See Github)

Hola @torgo! Let me try to elaborate on the id. I'd start by saying that this id is an arbitrary string and this doesn't mean that the same-origin content needs to be an app or have a manifest file associated.

The idea of an id is to be able to reference and differentiate the content once it is "installed". Follow on this example:

  • a template is created that includes in its header a button to install the current page as an app.
  • There is no id present and then a web dev creates a web site that has 5 different pages with this template.
  • A user comes into the site, thinks it is useful and wants to add it to its dock in macOS, so they click on the button, and they get the web content right from their dock.
  • They carry on navigating to any of the remaining 4 apps and click the button again. This packages the content into an app and adds it to the dock. The user now has 2 same but different apps.
  • If the developer wanted to expand its web site into a web application, they could add a manifest file, but then this would represent a third different app since there is no way to reference or identify that the content previously installed is the same app, if the manifest file that is added has an id that does not match.

We've tried to (and I wanted to) enable a no params install call, but thinking about upgradability and installed content management it makes sense to have this id. If a developer wants each page to be its own separate app, they can do so by specifying a different id on each page, but also if a developer wants to group the web content, they can also specify the same id and avoid having multiple installations of the same "app". It's more flexible

I see it more of a futureproofing/upgradability good practice... does this make sense, or do you have any considerations or comments we might have not thought of?

cc @dmurph @amandabaker

Comment by @diekus Aug 13, 2024 (See Github)

There was a previous idea that in the absence of an id then this will take the shape of the default fallback manifest id, which is the start_url and if there isn't a manifest file or start_url this falls back to the document url. But this doesn't meant that there is no id. it'll just be a computed automatic one that wouldn't allow the option to group several pages of a website as the same content/app.

The upside is that the developer gets to call navigator.install() instead of navigator.install('shoeapp'), but then the downside is if shoeapp.com has an install button on its header it can quickly allow for multiple installations of the same app and the platform would treat them as different ones, and that would be messy for end users.

considering how much web dev gets done by copy and pasting code samples from stackoverflow or MDN web docs I think the developer simplicity of not requiring an arbitrary id will come and bite back in the future when users have N of the same apps installed because they were installed from different pages, even though they are related/the same app.

Comment by @dmurph Aug 13, 2024 (See Github)

@torgo Here is a public doc I made in the past that describes the edge cases that are solved by always requiring an id: https://bit.ly/navigator-install-and-manifest-identity

Main problems briefly:

  • Developers can get into an unescapable situation where many users have 'broken' apps installed if used without an id. This can easily happen for copy-pasted code, or adding a manifest when there wasn't one previously, or if the manifest sometimes fails to load via 40X, 50X.
  • The manifest file can fail to load / 40X / 50X. Providing a manifest allows install to still succeed and the app can update itself later.
Comment by @torgo Aug 29, 2024 (See Github)

Hi Diego - thanks for sending this our way. We're happy to see this move forward and would like to review again when you have a specification in the Web Apps working group. We're happy to see that the installability criteria is indicated as up to the UA.

We're going to close this for now with a satisfied label. Please ping us to re-open when you want a follow-up review.