1 of 41

ECMAScript Realms

Stage 2, requesting Stage 3

TC39 November, 2020� https://github.com/tc39/proposal-realms/

2 of 41

Realm API

3 of 41

Realm API

4 of 41

Perks

  • Control the execution of a program
  • A new global object
  • A new set of intrinsics
  • No default access to the incubator Realm
  • A separate module graph
  • Sync communication with the incubator Realm with values being immediately shared

5 of 41

Motivations

  • Applications containing programs from multiple sources, whether from different teams, vendors, package managers, etc, or just programs with different set of requirements from the environment.
  • These programs must currently contend for the global shared resources, specifically, the shared global object, and the side effect of executing those programs are often hard to observe, causing conflicts between the different programs, and potentially affecting the integrity of the app itself.
  • Virtualization and portability: current inability to virtualize the environment where the program should be executed.

6 of 41

Prior art

7 of 41

HTML behavior: (PR)�Synthetic Realms behave like parent Realm

  • Two types of Realms, in new HTML nomenclature:
    • Synthetic Realms: Realms created through the new API
    • Principal Realms: Window, Worker, Worklet global scopes, created by HTML
  • HTML keys some state and behavior off of principal Realms
  • All synthetic Realms have a "parent" which is a principal Realm.
  • Look up state and behavior on parent Realm, not synthetic Realm.
    • "current Realm" ⇒ "current principal Realm"
  • Synthetic Realms also have their own module map
    • To support Realm.prototype.import, since modules close over global objects

8 of 41

Previous key concerns

  • What problems does this solve?
  • Is it a net win over the status quo of using iframes?

9 of 41

Ongoing TAG Review

10 of 41

Some clarifications from the ongoing TAG review

  • Realms only have the ECMAScript APIs available
  • Many libraries won't work unless they add dependencies manually
  • The current Realm cannot be accessed from within the Realm
  • Realms' MVP API has only `import()` and `globalThis`

11 of 41

New questions from the TAG review

  • What host extensions you expect hosts to add?
  • What are the new communication channels that will be possible with having this new capability?

12 of 41

Realms only have the built-in JS APIs available

Yes.

Could hosts add properties if they want to?

The current proposal explains that hosts are expected to not add properties to the Realm's global object on construction. We are considering making this a requirement. (#284)

The HTML integration PR does not add any properties to Realms.

13 of 41

Many libraries won't work unless they add dependencies manually

Yes, the clean slate of Realms is one of the goals of this proposal.

14 of 41

The current Realm cannot be accessed from within the Incubator Realm

Executed code doesn't need to know it's in a realm. Ideally, code executed in a realm would run seamlessly.

15 of 41

Realms API has only `import()` and `globalThis`

This is our MVP max/min proposal. We may explore extensions in the future but not during this proposal.

16 of 41

17 of 41

Frequently Raised Aspects

  • Realms are not a security boundary and does not encourage insecure application architecture.
  • Going async is not an option for virtualization between trusted sides.
  • Our place at TC39 and the Web Platform.
  • No need to change application configuration to evaluate code. Realms sit on top of the existing application settings.
  • Realms might not be as complex as it seems.

18 of 41

Not a security boundary and does not encourage insecure application architecture.

Security means different things to many people, but what is worth of web applications, Realms won't introduce a new security boundary.

The Realms are not promoting safe zones for experimentation of insecure features in applications.

The goals aims to the integrity of componentized applications, that is partially done today with prior art features, such as iframes, Node vm, JSCore JSContextGroupCreate(), Android's V8 Context::New, etc.

19 of 41

Async is not an option for virtualization

The mentioned goal for usage with componentized applications requires synchronous execution to get proper states and tailor changes of web applications such as manipulating the DOM. E.g. the Google AMP Virtualization

There are many goals towards process and thread level isolations and we see the Realms as a complement to those, not a replacement or an immediate alternative.

20 of 41

Our place at TC39 and the Web Platform.

Most of the current concerns are related to the current ongoing HTML integration.

There is a given concern on differentiating primordials from the web platform globals to users. We believe this has sailed with NodeJS and the respective native platforms exposing V8 and JSCore to developers.

The de-facto distribution model for JS code via NPM already highlight this issue extensively, and developers, and more important, the tools available for developers, have helped to mitigate this in some extend.

21 of 41

No need to change application configuration to evaluate code

The Realms API does not require enabling eval, much less encourages it.

The usage of dynamic import - realmObj.import() - is strongly encouraged to properly execute code in a synthetic Realm.

There is realmObj.globalThis.eval(), subject to CSP policy, but the given access to the current state of the Realm's globalThis and operation through dynamic import creates a much more appealing approach.

22 of 41

Realms might not be as complex as it seems.

We've seen many applications and usages for Realms while working on this proposal, including reports of multiple sandbox and virtualization frameworks.

Complexity here seems like a opt-in for the user who wants to use Realms, but not to the code to be run in a Realm.

23 of 41

Use Cases

24 of 41

In the last update we covered the following use cases:

  • Trusted scripts and web app plugins
  • Code testing
  • Codebase segmentation
  • DOM Virtualization, the AMP Project

25 of 41

Trusted Scripts

  • We want a quick and simple execution of trusted scripts.
  • Not one, not two, not three, but many scripts.
  • We don't need a new host/agent, but just integrity of the expected Intrinsics.
  • Non-blocking async loading and execution via realm.import.
  • No immediate access to application globals (e.g. Window) is also convenient.
  • No immediate access to unforgeables (e.g. window.top, window.location) is great.

26 of 41

Trusted Scripts: Plugin Example

import { api } from 'plugingFramework';

const realm = new Realm();

realm.globalThis.api = api;

await realm.import('./plugin1.js');

27 of 41

Code Testing

  • While threading is good for testing, the layering from Realms is also great.
  • Test frameworks can use Realms to inject code
  • And also control the order the injections if necessary.

28 of 41

Code Testing: Running tests in a realm

import { test } from 'testFramework';

const realm = new Realm();

realm.globalThis.test = test;

await realm.import('./main-spec.js');

test.report();

29 of 41

Code Testing: Running test FW and tests in a realm

const realm = new Realm();

const [ framework, { tap } ] = await Promise.all([

realm.import('testFramework'),

realm.import('reporters')

]);

framework.use(tap);

await realm.import('./main-spec.js');

30 of 41

Codebase segmentation

  • A big codebase tend to evolve slowly
  • Old code vs new code is a constant struggle
  • Modifying code to resolve a conflict (e.g.: global variables) is non-trivial.
  • With a lightweight mechanism to preserve the integrity of the intrinsics you could isolate libraries, or logical pieces of the codebase

31 of 41

DOM Virtualization

  • We still want things to still interact with the DOM
  • We don't want to spend any excessive amount of resources
  • We want to emulate the DOM as best as possible
    • Requiring other libraries to change to meet our requirements is difficult

32 of 41

DOM Virtualization: AMP WorkerDOM Challenge

google.com

AMP

Worker

(Virtual DOM)

???.cdn.ampproject.org

Runs AMP Framework

Runs NYT Scripts

async comm

Problem: Element.getBoundingClientRect() doesn't work over async comm channels (i.e. worker-dom)

Preloaded�

cross-domain iframe

33 of 41

DOM Virtualization

import virtualDocument from 'virtual-document';

const realm = new Realm();

realm.globalThis.document = virtualDocument;

await realm.import('./publisher-amin.js');

34 of 41

Previous key concerns

  • What problems does this solve?
  • Is it a net win over the status quo of using iframes?

This resolves #238: "Realms is counter to the current design principles of the web platform"

35 of 41

Other clarifications

36 of 41

Evaluation and security

  • Realm API does not introduce a new way to evaluate code, it reuses the existing evaluation mechanisms:
    • If you disable CSP unsafe-eval, you cannot evaluate code synchronously
    • If you disable CSP default-src, you cannot use Realm.prototype.import()

37 of 41

Evaluation and security

  • Realm API does not introduce a new way to evaluate code, it reuses the existing evaluation mechanisms:
    • If you disable CSP unsafe-eval, you cannot evaluate code synchronously
    • If you disable CSP default-src, you cannot use Realm.prototype.import()

38 of 41

Own module graph

const realm = new Realm();

// imports code that executes within its own environment.

const { doSomething } = await realm.import('./file.js');

doSomething();

  • Every Realm object has its own module graph (at host's discretion)

39 of 41

Stage 3?

40 of 41

Next steps and requesting stage 3 in January

41 of 41

Review

  • Editors need to follow up on the HTML Integration, we have an open PR.
  • More reviewers?