summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Gonzaga <rafael.nunu@hotmail.com>2022-09-05 13:07:45 -0300
committerGitHub <noreply@github.com>2022-09-05 16:07:45 +0000
commit03553c55705d1778d85638ae5303232250fa3bba (patch)
tree6b99958de860e05fa17e1edc43f757ef77a685c7
parent4af0a264da734a9d0943d633128eb0315dab4050 (diff)
downloadnode-new-03553c55705d1778d85638ae5303232250fa3bba.tar.gz
doc: move policy docs to the permissions scope
PR-URL: https://github.com/nodejs/node/pull/44222 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
-rw-r--r--doc/api/errors.md2
-rw-r--r--doc/api/index.md2
-rw-r--r--doc/api/permissions.md446
-rw-r--r--doc/api/policy.md421
-rw-r--r--test/doctool/test-make-doc.mjs6
5 files changed, 456 insertions, 421 deletions
diff --git a/doc/api/errors.md b/doc/api/errors.md
index 1ad36bd757..c6c8140e25 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -3587,7 +3587,7 @@ The native call from `process.cpuUsage` could not be processed.
[domains]: domain.md
[event emitter-based]: events.md#class-eventemitter
[file descriptors]: https://en.wikipedia.org/wiki/File_descriptor
-[policy]: policy.md
+[policy]: permissions.md#policies
[self-reference a package using its name]: packages.md#self-referencing-a-package-using-its-name
[stream-based]: stream.md
[syscall]: https://man7.org/linux/man-pages/man2/syscalls.2.html
diff --git a/doc/api/index.md b/doc/api/index.md
index c999258769..9c35550f5d 100644
--- a/doc/api/index.md
+++ b/doc/api/index.md
@@ -45,7 +45,7 @@
* [OS](os.md)
* [Path](path.md)
* [Performance hooks](perf_hooks.md)
-* [Policies](policy.md)
+* [Permissions](permissions.md)
* [Process](process.md)
* [Punycode](punycode.md)
* [Query strings](querystring.md)
diff --git a/doc/api/permissions.md b/doc/api/permissions.md
new file mode 100644
index 0000000000..a4be1a7c39
--- /dev/null
+++ b/doc/api/permissions.md
@@ -0,0 +1,446 @@
+# Permissions
+
+Permissions can be used to control what system resources the
+Node.js process has access to or what actions the process can take
+with those resources. Permissions can also control what modules can
+be accessed by other modules.
+
+* [Module-based permissions](#module-based-permissions) control which files
+ or URLs are available to other modules during application execution.
+ This can be used to control what modules can be accessed by third-party
+ dependencies, for example.
+
+If you find a potential security vulnerability, please refer to our
+[Security Policy][].
+
+## Module-based permissions
+
+### Policies
+
+<!--introduced_in=v11.8.0-->
+
+<!-- type=misc -->
+
+> Stability: 1 - Experimental
+
+<!-- name=policy -->
+
+Node.js contains experimental support for creating policies on loading code.
+
+Policies are a security feature intended to allow guarantees
+about what code Node.js is able to load. The use of policies assumes
+safe practices for the policy files such as ensuring that policy
+files cannot be overwritten by the Node.js application by using
+file permissions.
+
+A best practice would be to ensure that the policy manifest is read-only for
+the running Node.js application and that the file cannot be changed
+by the running Node.js application in any way. A typical setup would be to
+create the policy file as a different user id than the one running Node.js
+and granting read permissions to the user id running Node.js.
+
+#### Enabling
+
+<!-- type=misc -->
+
+The `--experimental-policy` flag can be used to enable features for policies
+when loading modules.
+
+Once this has been set, all modules must conform to a policy manifest file
+passed to the flag:
+
+```bash
+node --experimental-policy=policy.json app.js
+```
+
+The policy manifest will be used to enforce constraints on code loaded by
+Node.js.
+
+To mitigate tampering with policy files on disk, an integrity for
+the policy file itself may be provided via `--policy-integrity`.
+This allows running `node` and asserting the policy file contents
+even if the file is changed on disk.
+
+```bash
+node --experimental-policy=policy.json --policy-integrity="sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0" app.js
+```
+
+#### Features
+
+##### Error behavior
+
+When a policy check fails, Node.js by default will throw an error.
+It is possible to change the error behavior to one of a few possibilities
+by defining an "onerror" field in a policy manifest. The following values are
+available to change the behavior:
+
+* `"exit"`: will exit the process immediately.
+ No cleanup code will be allowed to run.
+* `"log"`: will log the error at the site of the failure.
+* `"throw"`: will throw a JS error at the site of the failure. This is the
+ default.
+
+```json
+{
+ "onerror": "log",
+ "resources": {
+ "./app/checked.js": {
+ "integrity": "sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0"
+ }
+ }
+}
+```
+
+##### Integrity checks
+
+Policy files must use integrity checks with Subresource Integrity strings
+compatible with the browser
+[integrity attribute](https://www.w3.org/TR/SRI/#the-integrity-attribute)
+associated with absolute URLs.
+
+When using `require()` or `import` all resources involved in loading are checked
+for integrity if a policy manifest has been specified. If a resource does not
+match the integrity listed in the manifest, an error will be thrown.
+
+An example policy file that would allow loading a file `checked.js`:
+
+```json
+{
+ "resources": {
+ "./app/checked.js": {
+ "integrity": "sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0"
+ }
+ }
+}
+```
+
+Each resource listed in the policy manifest can be of one the following
+formats to determine its location:
+
+1. A [relative-URL string][] to a resource from the manifest such as `./resource.js`, `../resource.js`, or `/resource.js`.
+2. A complete URL string to a resource such as `file:///resource.js`.
+
+When loading resources the entire URL must match including search parameters
+and hash fragment. `./a.js?b` will not be used when attempting to load
+`./a.js` and vice versa.
+
+To generate integrity strings, a script such as
+`node -e 'process.stdout.write("sha256-");process.stdin.pipe(crypto.createHash("sha256").setEncoding("base64")).pipe(process.stdout)' < FILE`
+can be used.
+
+Integrity can be specified as the boolean value `true` to accept any
+body for the resource which can be useful for local development. It is not
+recommended in production since it would allow unexpected alteration of
+resources to be considered valid.
+
+##### Dependency redirection
+
+An application may need to ship patched versions of modules or to prevent
+modules from allowing all modules access to all other modules. Redirection
+can be used by intercepting attempts to load the modules wishing to be
+replaced.
+
+```json
+{
+ "resources": {
+ "./app/checked.js": {
+ "dependencies": {
+ "fs": true,
+ "os": "./app/node_modules/alt-os",
+ "http": { "import": true }
+ }
+ }
+ }
+}
+```
+
+The dependencies are keyed by the requested specifier string and have values
+of either `true`, `null`, a string pointing to a module to be resolved,
+or a conditions object.
+
+The specifier string does not perform any searching and must match exactly what
+is provided to the `require()` or `import` except for a canonicalization step.
+Therefore, multiple specifiers may be needed in the policy if it uses multiple
+different strings to point to the same module (such as excluding the extension).
+
+Specifier strings are canonicalized but not resolved prior to be used for
+matching in order to have some compatibility with import maps, for example if a
+resource `file:///C:/app/server.js` was given the following redirection from a
+policy located at `file:///C:/app/policy.json`:
+
+```json
+{
+ "resources": {
+ "file:///C:/app/utils.js": {
+ "dependencies": {
+ "./utils.js": "./utils-v2.js"
+ }
+ }
+ }
+}
+```
+
+Any specifier used to load `file:///C:/app/utils.js` would then be intercepted
+and redirected to `file:///C:/app/utils-v2.js` instead regardless of using an
+absolute or relative specifier. However, if a specifier that is not an absolute
+or relative URL string is used, it would not be intercepted. So, if an import
+such as `import('#utils')` was used, it would not be intercepted.
+
+If the value of the redirection is `true`, a "dependencies" field at the top of
+the policy file will be used. If that field at the top of the policy file is
+`true` the default node searching algorithms are used to find the module.
+
+If the value of the redirection is a string, it is resolved relative to
+the manifest and then immediately used without searching.
+
+Any specifier string for which resolution is attempted and that is not listed in
+the dependencies results in an error according to the policy.
+
+Redirection does not prevent access to APIs through means such as direct access
+to `require.cache` or through `module.constructor` which allow access to
+loading modules. Policy redirection only affects specifiers to `require()` and
+`import`. Other means, such as to prevent undesired access to APIs through
+variables, are necessary to lock down that path of loading modules.
+
+A boolean value of `true` for the dependencies map can be specified to allow a
+module to load any specifier without redirection. This can be useful for local
+development and may have some valid usage in production, but should be used
+only with care after auditing a module to ensure its behavior is valid.
+
+Similar to `"exports"` in `package.json`, dependencies can also be specified to
+be objects containing conditions which branch how dependencies are loaded. In
+the preceding example, `"http"` is allowed when the `"import"` condition is
+part of loading it.
+
+A value of `null` for the resolved value causes the resolution to fail. This
+can be used to ensure some kinds of dynamic access are explicitly prevented.
+
+Unknown values for the resolved module location cause failures but are
+not guaranteed to be forward compatible.
+
+##### Example: Patched dependency
+
+Redirected dependencies can provide attenuated or modified functionality as fits
+the application. For example, log data about timing of function durations by
+wrapping the original:
+
+```js
+const original = require('fn');
+module.exports = function fn(...args) {
+ console.time();
+ try {
+ return new.target ?
+ Reflect.construct(original, args) :
+ Reflect.apply(original, this, args);
+ } finally {
+ console.timeEnd();
+ }
+};
+```
+
+#### Scopes
+
+Use the `"scopes"` field of a manifest to set configuration for many resources
+at once. The `"scopes"` field works by matching resources by their segments.
+If a scope or resource includes `"cascade": true`, unknown specifiers will
+be searched for in their containing scope. The containing scope for cascading
+is found by recursively reducing the resource URL by removing segments for
+[special schemes][], keeping trailing `"/"` suffixes, and removing the query and
+hash fragment. This leads to the eventual reduction of the URL to its origin.
+If the URL is non-special the scope will be located by the URL's origin. If no
+scope is found for the origin or in the case of opaque origins, a protocol
+string can be used as a scope. If no scope is found for the URL's protocol, a
+final empty string `""` scope will be used.
+
+Note, `blob:` URLs adopt their origin from the path they contain, and so a scope
+of `"blob:https://nodejs.org"` will have no effect since no URL can have an
+origin of `blob:https://nodejs.org`; URLs starting with
+`blob:https://nodejs.org/` will use `https://nodejs.org` for its origin and
+thus `https:` for its protocol scope. For opaque origin `blob:` URLs they will
+have `blob:` for their protocol scope since they do not adopt origins.
+
+##### Example
+
+```json
+{
+ "scopes": {
+ "file:///C:/app/": {},
+ "file:": {},
+ "": {}
+ }
+}
+```
+
+Given a file located at `file:///C:/app/bin/main.js`, the following scopes would
+be checked in order:
+
+1. `"file:///C:/app/bin/"`
+
+This determines the policy for all file based resources within
+`"file:///C:/app/bin/"`. This is not in the `"scopes"` field of the policy and
+would be skipped. Adding this scope to the policy would cause it to be used
+prior to the `"file:///C:/app/"` scope.
+
+2. `"file:///C:/app/"`
+
+This determines the policy for all file based resources within
+`"file:///C:/app/"`. This is in the `"scopes"` field of the policy and it would
+determine the policy for the resource at `file:///C:/app/bin/main.js`. If the
+scope has `"cascade": true`, any unsatisfied queries about the resource would
+delegate to the next relevant scope for `file:///C:/app/bin/main.js`, `"file:"`.
+
+3. `"file:///C:/"`
+
+This determines the policy for all file based resources within `"file:///C:/"`.
+This is not in the `"scopes"` field of the policy and would be skipped. It would
+not be used for `file:///C:/app/bin/main.js` unless `"file:///"` is set to
+cascade or is not in the `"scopes"` of the policy.
+
+4. `"file:///"`
+
+This determines the policy for all file based resources on the `localhost`. This
+is not in the `"scopes"` field of the policy and would be skipped. It would not
+be used for `file:///C:/app/bin/main.js` unless `"file:///"` is set to cascade
+or is not in the `"scopes"` of the policy.
+
+5. `"file:"`
+
+This determines the policy for all file based resources. It would not be used
+for `file:///C:/app/bin/main.js` unless `"file:///"` is set to cascade or is not
+in the `"scopes"` of the policy.
+
+6. `""`
+
+This determines the policy for all resources. It would not be used for
+`file:///C:/app/bin/main.js` unless `"file:"` is set to cascade.
+
+##### Integrity using scopes
+
+Setting an integrity to `true` on a scope will set the integrity for any
+resource not found in the manifest to `true`.
+
+Setting an integrity to `null` on a scope will set the integrity for any
+resource not found in the manifest to fail matching.
+
+Not including an integrity is the same as setting the integrity to `null`.
+
+`"cascade"` for integrity checks will be ignored if `"integrity"` is explicitly
+set.
+
+The following example allows loading any file:
+
+```json
+{
+ "scopes": {
+ "file:": {
+ "integrity": true
+ }
+ }
+}
+```
+
+##### Dependency redirection using scopes
+
+The following example, would allow access to `fs` for all resources within
+`./app/`:
+
+```json
+{
+ "resources": {
+ "./app/checked.js": {
+ "cascade": true,
+ "integrity": true
+ }
+ },
+ "scopes": {
+ "./app/": {
+ "dependencies": {
+ "fs": true
+ }
+ }
+ }
+}
+```
+
+The following example, would allow access to `fs` for all `data:` resources:
+
+```json
+{
+ "resources": {
+ "data:text/javascript,import('node:fs');": {
+ "cascade": true,
+ "integrity": true
+ }
+ },
+ "scopes": {
+ "data:": {
+ "dependencies": {
+ "fs": true
+ }
+ }
+ }
+}
+```
+
+##### Example: [import maps][] emulation
+
+Given an import map:
+
+```json
+{
+ "imports": {
+ "react": "./app/node_modules/react/index.js"
+ },
+ "scopes": {
+ "./ssr/": {
+ "react": "./app/node_modules/server-side-react/index.js"
+ }
+ }
+}
+```
+
+```json
+{
+ "dependencies": true,
+ "scopes": {
+ "": {
+ "cascade": true,
+ "dependencies": {
+ "react": "./app/node_modules/react/index.js"
+ }
+ },
+ "./ssr/": {
+ "cascade": true,
+ "dependencies": {
+ "react": "./app/node_modules/server-side-react/index.js"
+ }
+ }
+ }
+}
+```
+
+Import maps assume you can get any resource by default. This means
+`"dependencies"` at the top level of the policy should be set to `true`.
+Policies require this to be opt-in since it enables all resources of the
+application cross linkage which doesn't make sense for many scenarios. They also
+assume any given scope has access to any scope above its allowed dependencies;
+all scopes emulating import maps must set `"cascade": true`.
+
+Import maps only have a single top level scope for their "imports". So for
+emulating `"imports"` use the `""` scope. For emulating `"scopes"` use the
+`"scopes"` in a similar manner to how `"scopes"` works in import maps.
+
+Caveats: Policies do not use string matching for various finding of scope. They
+do URL traversals. This means things like `blob:` and `data:` URLs might not be
+entirely interoperable between the two systems. For example import maps can
+partially match a `data:` or `blob:` URL by partitioning the URL on a `/`
+character, policies intentionally cannot. For `blob:` URLs import map scopes do
+not adopt the origin of the `blob:` URL.
+
+Additionally, import maps only work on `import` so it may be desirable to add a
+`"import"` condition to all dependency mappings.
+
+[Security Policy]: https://github.com/nodejs/node/blob/main/SECURITY.md
+[import maps]: https://url.spec.whatwg.org/#relative-url-with-fragment-string
+[relative-url string]: https://url.spec.whatwg.org/#relative-url-with-fragment-string
+[special schemes]: https://url.spec.whatwg.org/#special-scheme
diff --git a/doc/api/policy.md b/doc/api/policy.md
index 233d6c9464..cf2ff88b7f 100644
--- a/doc/api/policy.md
+++ b/doc/api/policy.md
@@ -6,423 +6,6 @@
> Stability: 1 - Experimental
-<!-- name=policy -->
+The former Policies documentation is now at [Permissions documentation][]
-Node.js contains experimental support for creating policies on loading code.
-
-Policies are a security feature intended to allow guarantees
-about what code Node.js is able to load. The use of policies assumes
-safe practices for the policy files such as ensuring that policy
-files cannot be overwritten by the Node.js application by using
-file permissions.
-
-A best practice would be to ensure that the policy manifest is read-only for
-the running Node.js application and that the file cannot be changed
-by the running Node.js application in any way. A typical setup would be to
-create the policy file as a different user id than the one running Node.js
-and granting read permissions to the user id running Node.js.
-
-## Enabling
-
-<!-- type=misc -->
-
-The `--experimental-policy` flag can be used to enable features for policies
-when loading modules.
-
-Once this has been set, all modules must conform to a policy manifest file
-passed to the flag:
-
-```bash
-node --experimental-policy=policy.json app.js
-```
-
-The policy manifest will be used to enforce constraints on code loaded by
-Node.js.
-
-To mitigate tampering with policy files on disk, an integrity for
-the policy file itself may be provided via `--policy-integrity`.
-This allows running `node` and asserting the policy file contents
-even if the file is changed on disk.
-
-```bash
-node --experimental-policy=policy.json --policy-integrity="sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0" app.js
-```
-
-## Features
-
-### Error behavior
-
-When a policy check fails, Node.js by default will throw an error.
-It is possible to change the error behavior to one of a few possibilities
-by defining an "onerror" field in a policy manifest. The following values are
-available to change the behavior:
-
-* `"exit"`: will exit the process immediately.
- No cleanup code will be allowed to run.
-* `"log"`: will log the error at the site of the failure.
-* `"throw"`: will throw a JS error at the site of the failure. This is the
- default.
-
-```json
-{
- "onerror": "log",
- "resources": {
- "./app/checked.js": {
- "integrity": "sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0"
- }
- }
-}
-```
-
-### Integrity checks
-
-Policy files must use integrity checks with Subresource Integrity strings
-compatible with the browser
-[integrity attribute](https://www.w3.org/TR/SRI/#the-integrity-attribute)
-associated with absolute URLs.
-
-When using `require()` or `import` all resources involved in loading are checked
-for integrity if a policy manifest has been specified. If a resource does not
-match the integrity listed in the manifest, an error will be thrown.
-
-An example policy file that would allow loading a file `checked.js`:
-
-```json
-{
- "resources": {
- "./app/checked.js": {
- "integrity": "sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0"
- }
- }
-}
-```
-
-Each resource listed in the policy manifest can be of one the following
-formats to determine its location:
-
-1. A [relative-URL string][] to a resource from the manifest such as `./resource.js`, `../resource.js`, or `/resource.js`.
-2. A complete URL string to a resource such as `file:///resource.js`.
-
-When loading resources the entire URL must match including search parameters
-and hash fragment. `./a.js?b` will not be used when attempting to load
-`./a.js` and vice versa.
-
-To generate integrity strings, a script such as
-`node -e 'process.stdout.write("sha256-");process.stdin.pipe(crypto.createHash("sha256").setEncoding("base64")).pipe(process.stdout)' < FILE`
-can be used.
-
-Integrity can be specified as the boolean value `true` to accept any
-body for the resource which can be useful for local development. It is not
-recommended in production since it would allow unexpected alteration of
-resources to be considered valid.
-
-### Dependency redirection
-
-An application may need to ship patched versions of modules or to prevent
-modules from allowing all modules access to all other modules. Redirection
-can be used by intercepting attempts to load the modules wishing to be
-replaced.
-
-```json
-{
- "resources": {
- "./app/checked.js": {
- "dependencies": {
- "fs": true,
- "os": "./app/node_modules/alt-os",
- "http": { "import": true }
- }
- }
- }
-}
-```
-
-The dependencies are keyed by the requested specifier string and have values
-of either `true`, `null`, a string pointing to a module to be resolved,
-or a conditions object.
-
-The specifier string does not perform any searching and must match exactly what
-is provided to the `require()` or `import` except for a canonicalization step.
-Therefore, multiple specifiers may be needed in the policy if it uses multiple
-different strings to point to the same module (such as excluding the extension).
-
-Specifier strings are canonicalized but not resolved prior to be used for
-matching in order to have some compatibility with import maps, for example if a
-resource `file:///C:/app/server.js` was given the following redirection from a
-policy located at `file:///C:/app/policy.json`:
-
-```json
-{
- "resources": {
- "file:///C:/app/utils.js": {
- "dependencies": {
- "./utils.js": "./utils-v2.js"
- }
- }
- }
-}
-```
-
-Any specifier used to load `file:///C:/app/utils.js` would then be intercepted
-and redirected to `file:///C:/app/utils-v2.js` instead regardless of using an
-absolute or relative specifier. However, if a specifier that is not an absolute
-or relative URL string is used, it would not be intercepted. So, if an import
-such as `import('#utils')` was used, it would not be intercepted.
-
-If the value of the redirection is `true`, a "dependencies" field at the top of
-the policy file will be used. If that field at the top of the policy file is
-`true` the default node searching algorithms are used to find the module.
-
-If the value of the redirection is a string, it is resolved relative to
-the manifest and then immediately used without searching.
-
-Any specifier string for which resolution is attempted and that is not listed in
-the dependencies results in an error according to the policy.
-
-Redirection does not prevent access to APIs through means such as direct access
-to `require.cache` or through `module.constructor` which allow access to
-loading modules. Policy redirection only affects specifiers to `require()` and
-`import`. Other means, such as to prevent undesired access to APIs through
-variables, are necessary to lock down that path of loading modules.
-
-A boolean value of `true` for the dependencies map can be specified to allow a
-module to load any specifier without redirection. This can be useful for local
-development and may have some valid usage in production, but should be used
-only with care after auditing a module to ensure its behavior is valid.
-
-Similar to `"exports"` in `package.json`, dependencies can also be specified to
-be objects containing conditions which branch how dependencies are loaded. In
-the preceding example, `"http"` is allowed when the `"import"` condition is
-part of loading it.
-
-A value of `null` for the resolved value causes the resolution to fail. This
-can be used to ensure some kinds of dynamic access are explicitly prevented.
-
-Unknown values for the resolved module location cause failures but are
-not guaranteed to be forward compatible.
-
-#### Example: Patched dependency
-
-Redirected dependencies can provide attenuated or modified functionality as fits
-the application. For example, log data about timing of function durations by
-wrapping the original:
-
-```js
-const original = require('fn');
-module.exports = function fn(...args) {
- console.time();
- try {
- return new.target ?
- Reflect.construct(original, args) :
- Reflect.apply(original, this, args);
- } finally {
- console.timeEnd();
- }
-};
-```
-
-### Scopes
-
-Use the `"scopes"` field of a manifest to set configuration for many resources
-at once. The `"scopes"` field works by matching resources by their segments.
-If a scope or resource includes `"cascade": true`, unknown specifiers will
-be searched for in their containing scope. The containing scope for cascading
-is found by recursively reducing the resource URL by removing segments for
-[special schemes][], keeping trailing `"/"` suffixes, and removing the query and
-hash fragment. This leads to the eventual reduction of the URL to its origin.
-If the URL is non-special the scope will be located by the URL's origin. If no
-scope is found for the origin or in the case of opaque origins, a protocol
-string can be used as a scope. If no scope is found for the URL's protocol, a
-final empty string `""` scope will be used.
-
-Note, `blob:` URLs adopt their origin from the path they contain, and so a scope
-of `"blob:https://nodejs.org"` will have no effect since no URL can have an
-origin of `blob:https://nodejs.org`; URLs starting with
-`blob:https://nodejs.org/` will use `https://nodejs.org` for its origin and
-thus `https:` for its protocol scope. For opaque origin `blob:` URLs they will
-have `blob:` for their protocol scope since they do not adopt origins.
-
-#### Example
-
-```json
-{
- "scopes": {
- "file:///C:/app/": {},
- "file:": {},
- "": {}
- }
-}
-```
-
-Given a file located at `file:///C:/app/bin/main.js`, the following scopes would
-be checked in order:
-
-1. `"file:///C:/app/bin/"`
-
-This determines the policy for all file based resources within
-`"file:///C:/app/bin/"`. This is not in the `"scopes"` field of the policy and
-would be skipped. Adding this scope to the policy would cause it to be used
-prior to the `"file:///C:/app/"` scope.
-
-2. `"file:///C:/app/"`
-
-This determines the policy for all file based resources within
-`"file:///C:/app/"`. This is in the `"scopes"` field of the policy and it would
-determine the policy for the resource at `file:///C:/app/bin/main.js`. If the
-scope has `"cascade": true`, any unsatisfied queries about the resource would
-delegate to the next relevant scope for `file:///C:/app/bin/main.js`, `"file:"`.
-
-3. `"file:///C:/"`
-
-This determines the policy for all file based resources within `"file:///C:/"`.
-This is not in the `"scopes"` field of the policy and would be skipped. It would
-not be used for `file:///C:/app/bin/main.js` unless `"file:///"` is set to
-cascade or is not in the `"scopes"` of the policy.
-
-4. `"file:///"`
-
-This determines the policy for all file based resources on the `localhost`. This
-is not in the `"scopes"` field of the policy and would be skipped. It would not
-be used for `file:///C:/app/bin/main.js` unless `"file:///"` is set to cascade
-or is not in the `"scopes"` of the policy.
-
-5. `"file:"`
-
-This determines the policy for all file based resources. It would not be used
-for `file:///C:/app/bin/main.js` unless `"file:///"` is set to cascade or is not
-in the `"scopes"` of the policy.
-
-6. `""`
-
-This determines the policy for all resources. It would not be used for
-`file:///C:/app/bin/main.js` unless `"file:"` is set to cascade.
-
-#### Integrity using scopes
-
-Setting an integrity to `true` on a scope will set the integrity for any
-resource not found in the manifest to `true`.
-
-Setting an integrity to `null` on a scope will set the integrity for any
-resource not found in the manifest to fail matching.
-
-Not including an integrity is the same as setting the integrity to `null`.
-
-`"cascade"` for integrity checks will be ignored if `"integrity"` is explicitly
-set.
-
-The following example allows loading any file:
-
-```json
-{
- "scopes": {
- "file:": {
- "integrity": true
- }
- }
-}
-```
-
-#### Dependency redirection using scopes
-
-The following example, would allow access to `fs` for all resources within
-`./app/`:
-
-```json
-{
- "resources": {
- "./app/checked.js": {
- "cascade": true,
- "integrity": true
- }
- },
- "scopes": {
- "./app/": {
- "dependencies": {
- "fs": true
- }
- }
- }
-}
-```
-
-The following example, would allow access to `fs` for all `data:` resources:
-
-```json
-{
- "resources": {
- "data:text/javascript,import('node:fs');": {
- "cascade": true,
- "integrity": true
- }
- },
- "scopes": {
- "data:": {
- "dependencies": {
- "fs": true
- }
- }
- }
-}
-```
-
-#### Example: [import maps][] emulation
-
-Given an import map:
-
-```json
-{
- "imports": {
- "react": "./app/node_modules/react/index.js"
- },
- "scopes": {
- "./ssr/": {
- "react": "./app/node_modules/server-side-react/index.js"
- }
- }
-}
-```
-
-```json
-{
- "dependencies": true,
- "scopes": {
- "": {
- "cascade": true,
- "dependencies": {
- "react": "./app/node_modules/react/index.js"
- }
- },
- "./ssr/": {
- "cascade": true,
- "dependencies": {
- "react": "./app/node_modules/server-side-react/index.js"
- }
- }
- }
-}
-```
-
-Import maps assume you can get any resource by default. This means
-`"dependencies"` at the top level of the policy should be set to `true`.
-Policies require this to be opt-in since it enables all resources of the
-application cross linkage which doesn't make sense for many scenarios. They also
-assume any given scope has access to any scope above its allowed dependencies;
-all scopes emulating import maps must set `"cascade": true`.
-
-Import maps only have a single top level scope for their "imports". So for
-emulating `"imports"` use the `""` scope. For emulating `"scopes"` use the
-`"scopes"` in a similar manner to how `"scopes"` works in import maps.
-
-Caveats: Policies do not use string matching for various finding of scope. They
-do URL traversals. This means things like `blob:` and `data:` URLs might not be
-entirely interoperable between the two systems. For example import maps can
-partially match a `data:` or `blob:` URL by partitioning the URL on a `/`
-character, policies intentionally cannot. For `blob:` URLs import map scopes do
-not adopt the origin of the `blob:` URL.
-
-Additionally, import maps only work on `import` so it may be desirable to add a
-`"import"` condition to all dependency mappings.
-
-[import maps]: https://url.spec.whatwg.org/#relative-url-with-fragment-string
-[relative-url string]: https://url.spec.whatwg.org/#relative-url-with-fragment-string
-[special schemes]: https://url.spec.whatwg.org/#special-scheme
+[Permissions documentation]: permissions.md#policies
diff --git a/test/doctool/test-make-doc.mjs b/test/doctool/test-make-doc.mjs
index 54483c7d68..5771f4e1ce 100644
--- a/test/doctool/test-make-doc.mjs
+++ b/test/doctool/test-make-doc.mjs
@@ -45,6 +45,7 @@ const linkedHtmls = [...new Set(links)].map((link) => link.match(re)[1])
const expectedJsons = linkedHtmls
.map((name) => name.replace('.html', '.json'));
const expectedDocs = linkedHtmls.concat(expectedJsons);
+const renamedDocs = ['policy.json', 'policy.html'];
// Test that all the relative links in the TOC match to the actual documents.
for (const expectedDoc of expectedDocs) {
@@ -54,6 +55,11 @@ for (const expectedDoc of expectedDocs) {
// Test that all the actual documents match to the relative links in the TOC
// and that they are not empty files.
for (const actualDoc of actualDocs) {
+ // When renaming the documentation, the old url is lost
+ // Unless the old file is still available pointing to the correct location
+ // 301 redirects are not yet automated. So keeping the old URL is a
+ // reasonable workaround.
+ if (renamedDocs.includes(actualDoc)) continue;
assert.ok(
expectedDocs.includes(actualDoc), `${actualDoc} does not match TOC`);