[w3c/ServiceWorker] Registering service workers for unique origins? (#1437)

# Problem
I am looking for a way to register a service worker runs for a unique origin. The lifetime of the service worker would be tied to the lifetime of the page with that unique origin.

### Details
I develop VS Code's [webview API](https://code.visualstudio.com/api/extension-guides/webview), which lets VS Code extensions render arbitrary html inside of the VS Code editor. I am currently trying to set up a sandboxed environment for webviews using iframes + service workers. Here's the basic structure:

```
// Serve up from a unique origin so that the iframe cannot effect our main page
<iframe src="https://cdn.contoso.com" sandbox="allow-same-origin">
  <html>
     <body>

     // This is a static html page served up from cdn.contoso.com. It is where
     // we have VS Code's scripts for managing webview content. 
     //
     // This is also where we register a service worker for cdn.contoso.com. We use 
     // the service worker to implement a virtual `/vscode-resource/` endpoint
     // that the untrusted html provided by extension can use to load resources
     // from the user's workspace (while letting us allow or deny this)

    <iframe width="100%" height="100%" sandbox="allow-same-origin">
        // Actual html content coming from an extension

        <img src="/vscode-resource/Users/matt/workspace/cat.git"> // This goes through the service worker
     </iframe>
    </body>
  </html>
</webview>
```

The main issue with this approach is that all the webview content ends up being served from the same `cdn.contoso.com` origin, which means that webviews can end up effecting each other indirectly. I've tried various incantations of `allow-same-origin` and `srcdoc` and data uris, but have not been able to find a means to serve the iframe in a unique origin so that we can still register a service worker for it.

A secondary issue is that we need to stand up `cdn.contoso.com` to serve up the outer iframe content in the first place. This adds extra setup and maintenance cost for people hosting VS Code.

Here's the actual code that implements all this today:

- [Outer iframe](https://github.com/microsoft/vscode/blob/3c698386915e5bd1636256d9ff1a996a74521cfb/src/vs/workbench/contrib/webview/browser/pre/index.html#L1)
- [Service worker](https://github.com/microsoft/vscode/blob/3c698386915e5bd1636256d9ff1a996a74521cfb/src/vs/workbench/contrib/webview/browser/pre/service-worker.js#L1)
- [Main page handlers for loading resources](https://github.com/microsoft/vscode/blob/3c698386915e5bd1636256d9ff1a996a74521cfb/src/vs/workbench/contrib/webview/browser/webviewElement.ts#L115)


# Proposals
I believe that allowing service workers to be registered in sandboxed iframe that does not set `allow-same-origin` would solve the main issue for us. Since the origin of the page in that case is unique, my expectation is that the service worker's lifetime would be tied to that of the document itself. Once the document is unloaded, the browser could delete the service worker and clean up any related resources.


Another approach would be an API for registering a one-time service worker that runs on a unique origin. The page would then be able to use the unique origin to serve up content. The lifetime of the worker would be the same as the page itself (similar to `URL.createObjectURL`).

For example, this could look something like: 

```js
const worker = await navigator.createServiceWorkerEndpoint('source of my virtual server worker');

const iframe = document.createElement('iframe');
iframe.src = worker.url; // This will result in a `fetch` against our worker for `/` at our unique origin
document.body.appendChild(iframe);
```

The `url` would be a guaranteed unique origin, perhaps by using a unique identifier: `sw-endpoint://00071f0e-fd75-4525-acde-cacb6fc7a1cd`. The `url` would be usable on the page that created the worker as well as on any pages it embeds.

The registered service worker itself would behave just like a normal service worker. However its lifetime would be linked to the page that created it. This would also simplify the creation of a virtual server for us (because we do not use many parts of service workers, such as them being shared across multiple pages).

# Possibly Related issues

- https://github.com/w3c/ServiceWorker/issues/1390
- https://github.com/w3ctag/design-principles/issues/111



-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/ServiceWorker/issues/1437

Received on Wednesday, 19 June 2019 20:06:26 UTC