Freezing only freezes properties. JavaScript objects can hold mutable state that is unaffected by freeze. The harden
function from https://github.com/Agoric/harden freezes everything it can find by transitive own property traversal[*]. If harden(obj)
returns successfully, then all the object reachable from obj
by own property traversal and inheritance are frozen. Usually, the most useful way to think about harden(obj)
is as a way to make API surface tamper proof, rather than as a way to achieve immutability, aka, purity.
let x = 3;
const count = harden(function() => { return x++; });
The count
function above is hardened but not pure.
However, if the subgraph reached from harden(obj)
has no hidden mutable state, such that after harden(obj)
successfully returns we know obj
is pure, then before harden is called, we say that obj
is purifiable.
In the default configuration of SES, all the intrinsic objects (i.e., the primordials, the objects that must exist before user code starts running) are pure. If two subgraphs share pure objects but are otherwise isolated, they cannot overtly communicate. By default, SES also denies them the special powers they need to read side channels and covert channels, like the ability to sense the duration of time. In that case, these subgraphs simply cannot communicate.
A pure module is one whose exports are pure values. A statically pure module is one that passes our static checking rules that ensure a module is pure under the assumption that it is executing under the SES default configuration and that it imports only pure values. A module that is not a pure module is a resource module. A module that is not statically pure must conservatively be assumed to be a resource module.
SES will provide a pure loader, to be shared by default by all code within the same SES root realm. The pure loader will only load statically pure modules. It will resolve all their imports only to statically pure modules, thereby ensuring that these modules only import and export pure values.
Jessie only supports pure modules. SES will also support per-compartment resource loaders that load resource modules. These resource loader can be configured to delegate to each other, and to their shared pure loader, to arrange for least-authority wiring of resource modules, as explained in the safe-modules repository.
[*] Technically, transitive reflective own property traversal. For data properties, this remains as expected — harden
recurs on the property’s value. For accessor properties, harden
does not call the getter. Rather, harden
recurs on the getter and setter function themselves. Again, see the harden repository for details.
For reference, see