Share a secret across ES6 specific modules, so that other modules cannot access the secret?

/#!/JoePea joe at
Sun Apr 15 18:10:43 UTC 2018


That's an interesting idea, Bradley, thanks! I originally wanted this for
implementing "protected" class members (i.e. sharing a WeakMap across
subclasses in different files), but I've since done this another way that
is even better:

With lowclass we can also make what I'm calling "module protected" access
(similar to "friends" in C or "package protected" in Java) by simply
leaking access helpers to outside scope inside a module. Here's the example
in the README

But now that I've revisited this thread, I realize that with a GATEWAY it
is possible to share a "leaked" access helper across files too, thus making
something that is more like Java's "package protected"! Cool!

> note: all dependencies of these modules could access GATEWAY

This can be prevented by having the `GATEWAY` function count how many times
it is called. If we hard code the number of modules that will call GATEWAY
in a project, we can throw an error if the number of accesses is higher
than expected and blatantly breaking an app to force people not to do it.
Automated tests can ensure that the number is hard coded properly. It could
also be possible to add a build step to automatically detect and add the
hard-coded number.

> With Realms

That's also interesting, but I think it would be too heavy-weight to create
new JS contexts just for sharing some private references. The GATEWAY idea
I think is much slimmer. Plus sharing across Realms can introduce all sorts
of other problems like `instanceof` checks failing due to one global not
being the same reference to the equivalent global in the other realm
(`console.assert(window.Object !== realm.Object)`). Here's is the same
problem with Jest <> (with
Node's `vm` rather than Realms, but essentially its the same issue).

It'd be better if there were some sort of spec added to Modules that
allowed some set of modules to import private exports from each other with
simple syntax, or similar. Maybe it would be based on folder structure, or
maybe module identifiers referenced in each other so that there's no
physical circular dependency, only harmless circular mentioning of each
other at worst, so that runtime circular dependency issues
don't become a problem.

> If you are interested to look at it, I’ve implemented a module loader
with a secret shared across the Doodad framework

Thanks for sharing that Claude. It's interesting to see how others are
implementing public/protected/private for their classes. :)

- Joe


On Mon, Apr 24, 2017 at 12:34 PM, Bradley Meck <bradley.meck at>

> To an extent, yes. You can use hoisting of function declarations and
> circular dependencies to create a "gateway". During circular dependencies,
> you have a time where function declarations are available but evaluation
> has not occured. During that time you can setup your private state. Then,
> immediately on evaluation, remove your gateway.
> ```
> // file: ./secrets
> // import all friendly modules (note: all dependencies of these modules
> could access GATEWAY)
> import './a'
> GATEWAY = void 0;
> // storage for shared secrets
> let SECRET;
> // gateway
> function GATEWAY() {
>   if (!SECRET) SECRET = {};
>   return SECRET;
> }
> export {GATEWAY};
> ```
> ```
> // file: ./a
> import {GATEWAY} from './secrets';
> if (typeof GATEWAY !== 'function') {
>   throw Error('import secrets *first*.');
> }
> const SECRET = GATEWAY();
> ```
> With Realms ( you may be able to
> use the completion value of Module Evaluation to also achieve a way to
> share private state in a more sane way. VM implementations allow this in
> some ways as well :
> a71c338d9e24e55b47125108a0fce754076751d0/include/v8.h#L1109
> On Sun, Apr 23, 2017 at 6:02 PM, Jordan Harband <ljharb at> wrote:
>> Nope. This is exactly why it seems that "protected" couldn't have any way
>> to work that has "hard" enforcement.
>> The only true privacy in JS is via closure (including WeakMaps), or via
>> the upcoming "private fields" proposal, assuming it stays as "hard
>> private". Anything shared is publicly accessible.
>> I'd be very interested to hear any idea that would allow modules A and B
>> to privately share something, without module C being able to; the only
>> thing I could think of would be some sort of private export that explicitly
>> included a list of module specifiers that were allowed to import it - which
>> would still not be secure whenever loader hooks exist.
>> On Sun, Apr 23, 2017 at 1:42 PM, /#!/JoePea <joe at> wrote:
>>> Is there a way to share some secret value across a few modules, and
>>> prevent other modules? f.e. prevent modules of an app dev who is importing
>>> modules of a library where the library wants to share private stuff across
>>> its modules. Is this possible to implement somehow?
>>> WeakMaps can be encapsulated inside a module to implement "private"
>>> properties for a class defined inside that module and then exported. But
>>> "protected" can't be implemented with a WeakMap shared with modules because
>>> then end-user app code can import the WeakMap and read all the stuff. Is
>>> there some way to share a WeakMap private with classes defined across
>>> modules?
>>> */#!/*JoePea
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list