Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(compartment-mapper): add policy-related types #1839

Merged
merged 5 commits into from
Jan 10, 2024

Conversation

boneskull
Copy link
Contributor

@boneskull boneskull commented Oct 26, 2023

Description

This adds/narrows types for policies and exports them from the compartment-mapper entry point. It also updates some usages of existing and new types (e.g., removing "@typedef references", squashing some null-reference bugs, etc.).

Note

This does not change the fact that @endo/compartment-mapper does not export types properly to node16/nodenext-resolution consumers (see #1803).

Reviewers: please scrutinize the types added to src/types.js closely. The generics allow an attenuator implementation to define the types of custom params which it expects. For example:

// policy-converter.js

/**
 * @typedef {'$root'} RootPolicy
 * @typedef {'write'} WritePolicy
 */

/**
 * Extends Endo's `PolicyItem` with the special {@link RootPolicy} and {@link WritePolicy}
 * @typedef {RootPolicy | WritePolicy} LavaMoatGlobalPolicyItem
 */

/**
 * Extends Endo's `PolicyItem` with the special {@link RootPolicy}
 * @typedef {RootPolicy} LavaMoatPackagePolicyItem
 */

/**
 * An Endo policy tailored to LavaMoat's default attenuator
 * @typedef {import('@endo/compartment-mapper').Policy<LavaMoatPackagePolicyItem, LavaMoatGlobalPolicyItem>} LavaMoatEndoPolicy
 */

/**
 * Package policy based on {@link LavaMoatPackagePolicyItem} and {@link LavaMoatGlobalPolicyItem}.
 *
 * Member of {@link LavaMoatEndoPolicy}
 * @typedef {import('@endo/compartment-mapper').PackagePolicy<LavaMoatPackagePolicyItem, LavaMoatGlobalPolicyItem>} LavaMoatPackagePolicy
 */

And in the attenuator:

// my-attenuator.js

export default {
  /**
   * @type {import('@endo/compartment-mapper').GlobalAttenuatorFn<[import('./policy-converter.js').LavaMoatPackagePolicy['globals']]>}
   */
  attenuateGlobals(params, originalGlobalThis, packageCompartmentGlobalThis) {
    // ...
  },
  /**
   * @type {import('@endo/compartment-mapper').ModuleAttenuatorFn<[import('./policy-converter.js').LavaMoatPackagePolicy['packages']]>}
   */
  attenuateModule(params, originalObject) {
    // ...
  }
}

Documentation Considerations

Does Endo consider type changes to be breaking? These types will likely change in the future, and am curious about whether that should be a major bump.

Testing Considerations

I could use tsd to test some of these to avoid regressions, if desired.

Upgrade Considerations

none

@boneskull
Copy link
Contributor Author

cc @naugtur

@boneskull boneskull force-pushed the boneskull/add-policy-types branch 2 times, most recently from 5519cab to 4826f54 Compare October 27, 2023 21:17
@kriskowal kriskowal requested a review from naugtur November 1, 2023 03:14
* @param {Record<PropertyKey, any>} originalObject
* @param {Record<PropertyKey, any>} globalThis
* @returns {void}
* @todo Unsure if we can do much typing of `originalObject` and `globalThis` here.
Copy link
Member

@naugtur naugtur Dec 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

originalObject is the same as the value passed in as global to importLocation options. I don't think it's reasonable to thread it all the way if TS can't infer.
globalThis is the Compartment instance's globalThis field, might be possible to derive from ses types eventually.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure if there's something actionable here

* @template [GlobalsPolicyItem=void]
* @template [BuiltinsPolicyItem=void]
* @typedef {object} PackagePolicy
* @property {string} [defaultAttenuator] - The default attenuator.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nit) There's no defaultAttenuator field on the individual resource in policy in the public API.
I'm guessing this is the consequence of defaultAttenuator being saved in the package policy of the attenuators compartment. Should we document it here? Should we sub-type internally? Should we implement a valid usecase for it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw it referenced here, but I can't answer your other questions. If it's intended to be public, then great, but if not, we should subtype.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd lean towards subtyping it (though I'm not sure where that type assignment needs to happen) for now unless there's an obvious use-case.

@naugtur
Copy link
Member

naugtur commented Dec 13, 2023

I wanted to rebase this and add cleanup to one of mine functions but noticed this is from a fork.
@boneskull want me to fold this into a branch on the endo repo?

patch I wish to apply after rebase on master:

diff --git a/packages/compartment-mapper/src/policy.js b/packages/compartment-mapper/src/policy.js
index 8604bcb2a..c646c37c3 100644
--- a/packages/compartment-mapper/src/policy.js
+++ b/packages/compartment-mapper/src/policy.js
@@ -339,26 +339,28 @@ const diagnoseModulePolicy = errorHint => {
  *
  * @param {string} specifier
  * @param {import('./types.js').CompartmentDescriptor} compartmentDescriptor
- * @param {object} [info]
+ * @param {object} [options]
+ * @param {boolean} [options.exit] - Whether it is an exit module
+ * @param {string} [options.errorHint] - Error hint message
  */
 export const enforceModulePolicy = (
   specifier,
   compartmentDescriptor,
-  info = {},
+  { exit, errorHint } = {},
 ) => {
   const { policy, modules, label } = compartmentDescriptor;
   if (!policy) {
     return;
   }
 
-  if (!info.exit) {
+  if (!exit) {
     if (!modules[specifier]) {
       throw Error(
         `Importing ${q(specifier)} in ${q(
           label,
         )} was not allowed by packages policy ${q(
           policy.packages,
-        )}${diagnoseModulePolicy(info.errorHint)}`,
+        )}${diagnoseModulePolicy(errorHint)}`,
       );
     }
     return;
@@ -368,7 +370,7 @@ export const enforceModulePolicy = (
     throw Error(
       `Importing ${q(specifier)} was not allowed by policy builtins:${q(
         policy.builtins,
-      )}${diagnoseModulePolicy(info.errorHint)}`,
+      )}${diagnoseModulePolicy(errorHint)}`,
     );
   }
 };

@boneskull boneskull force-pushed the boneskull/add-policy-types branch from 16e065c to 11b0c05 Compare December 14, 2023 21:43
@boneskull
Copy link
Contributor Author

@naugtur Resolved

@boneskull boneskull force-pushed the boneskull/add-policy-types branch from 11b0c05 to f0d2d16 Compare December 14, 2023 22:23
@boneskull
Copy link
Contributor Author

@naugtur OK, so, it's slightly different than the diff you gave me, since the diff you gave me did not match the snapshots; I retained the use of the label prop from the compartment descriptor

Please take another look at the changes I made based on your comments.

@boneskull boneskull requested a review from naugtur December 14, 2023 22:24
@boneskull boneskull self-assigned this Dec 14, 2023
This adds types for policies and exports them from the `compartment-mapper` entry point. It also updates some usages of existing and new types.
...as requested by @naugtur.

also change some return types to use TS' `asserts` keyword.
The logic forbids it, but type inference doesn't necessarily--better to be safe.
@boneskull boneskull force-pushed the boneskull/add-policy-types branch from 3e44c0d to ece09e2 Compare January 9, 2024 23:52
@boneskull boneskull enabled auto-merge January 9, 2024 23:54
@boneskull boneskull merged commit 1034fce into endojs:master Jan 10, 2024
14 checks passed
@boneskull boneskull deleted the boneskull/add-policy-types branch January 10, 2024 20:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants