11cb0ef41Sopenharmony_ci# Permissions 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciPermissions can be used to control what system resources the 41cb0ef41Sopenharmony_ciNode.js process has access to or what actions the process can take 51cb0ef41Sopenharmony_ciwith those resources. Permissions can also control what modules can 61cb0ef41Sopenharmony_cibe accessed by other modules. 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci* [Module-based permissions](#module-based-permissions) control which files 91cb0ef41Sopenharmony_ci or URLs are available to other modules during application execution. 101cb0ef41Sopenharmony_ci This can be used to control what modules can be accessed by third-party 111cb0ef41Sopenharmony_ci dependencies, for example. 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ciIf you find a potential security vulnerability, please refer to our 141cb0ef41Sopenharmony_ci[Security Policy][]. 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci## Module-based permissions 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ci### Policies 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ci<!--introduced_in=v11.8.0--> 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci<!-- type=misc --> 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ci> Stability: 1 - Experimental 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci<!-- name=policy --> 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciNode.js contains experimental support for creating policies on loading code. 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ciPolicies are a security feature intended to allow guarantees 311cb0ef41Sopenharmony_ciabout what code Node.js is able to load. The use of policies assumes 321cb0ef41Sopenharmony_cisafe practices for the policy files such as ensuring that policy 331cb0ef41Sopenharmony_cifiles cannot be overwritten by the Node.js application by using 341cb0ef41Sopenharmony_cifile permissions. 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ciA best practice would be to ensure that the policy manifest is read-only for 371cb0ef41Sopenharmony_cithe running Node.js application and that the file cannot be changed 381cb0ef41Sopenharmony_ciby the running Node.js application in any way. A typical setup would be to 391cb0ef41Sopenharmony_cicreate the policy file as a different user id than the one running Node.js 401cb0ef41Sopenharmony_ciand granting read permissions to the user id running Node.js. 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci#### Enabling 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci<!-- type=misc --> 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ciThe `--experimental-policy` flag can be used to enable features for policies 471cb0ef41Sopenharmony_ciwhen loading modules. 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ciOnce this has been set, all modules must conform to a policy manifest file 501cb0ef41Sopenharmony_cipassed to the flag: 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci```bash 531cb0ef41Sopenharmony_cinode --experimental-policy=policy.json app.js 541cb0ef41Sopenharmony_ci``` 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ciThe policy manifest will be used to enforce constraints on code loaded by 571cb0ef41Sopenharmony_ciNode.js. 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ciTo mitigate tampering with policy files on disk, an integrity for 601cb0ef41Sopenharmony_cithe policy file itself may be provided via `--policy-integrity`. 611cb0ef41Sopenharmony_ciThis allows running `node` and asserting the policy file contents 621cb0ef41Sopenharmony_cieven if the file is changed on disk. 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci```bash 651cb0ef41Sopenharmony_cinode --experimental-policy=policy.json --policy-integrity="sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0" app.js 661cb0ef41Sopenharmony_ci``` 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci#### Features 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci##### Error behavior 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ciWhen a policy check fails, Node.js by default will throw an error. 731cb0ef41Sopenharmony_ciIt is possible to change the error behavior to one of a few possibilities 741cb0ef41Sopenharmony_ciby defining an "onerror" field in a policy manifest. The following values are 751cb0ef41Sopenharmony_ciavailable to change the behavior: 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci* `"exit"`: will exit the process immediately. 781cb0ef41Sopenharmony_ci No cleanup code will be allowed to run. 791cb0ef41Sopenharmony_ci* `"log"`: will log the error at the site of the failure. 801cb0ef41Sopenharmony_ci* `"throw"`: will throw a JS error at the site of the failure. This is the 811cb0ef41Sopenharmony_ci default. 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci```json 841cb0ef41Sopenharmony_ci{ 851cb0ef41Sopenharmony_ci "onerror": "log", 861cb0ef41Sopenharmony_ci "resources": { 871cb0ef41Sopenharmony_ci "./app/checked.js": { 881cb0ef41Sopenharmony_ci "integrity": "sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0" 891cb0ef41Sopenharmony_ci } 901cb0ef41Sopenharmony_ci } 911cb0ef41Sopenharmony_ci} 921cb0ef41Sopenharmony_ci``` 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci##### Integrity checks 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ciPolicy files must use integrity checks with Subresource Integrity strings 971cb0ef41Sopenharmony_cicompatible with the browser 981cb0ef41Sopenharmony_ci[integrity attribute](https://www.w3.org/TR/SRI/#the-integrity-attribute) 991cb0ef41Sopenharmony_ciassociated with absolute URLs. 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ciWhen using `require()` or `import` all resources involved in loading are checked 1021cb0ef41Sopenharmony_cifor integrity if a policy manifest has been specified. If a resource does not 1031cb0ef41Sopenharmony_cimatch the integrity listed in the manifest, an error will be thrown. 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ciAn example policy file that would allow loading a file `checked.js`: 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci```json 1081cb0ef41Sopenharmony_ci{ 1091cb0ef41Sopenharmony_ci "resources": { 1101cb0ef41Sopenharmony_ci "./app/checked.js": { 1111cb0ef41Sopenharmony_ci "integrity": "sha384-SggXRQHwCG8g+DktYYzxkXRIkTiEYWBHqev0xnpCxYlqMBufKZHAHQM3/boDaI/0" 1121cb0ef41Sopenharmony_ci } 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci} 1151cb0ef41Sopenharmony_ci``` 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ciEach resource listed in the policy manifest can be of one the following 1181cb0ef41Sopenharmony_ciformats to determine its location: 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci1. A [relative-URL string][] to a resource from the manifest such as `./resource.js`, `../resource.js`, or `/resource.js`. 1211cb0ef41Sopenharmony_ci2. A complete URL string to a resource such as `file:///resource.js`. 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ciWhen loading resources the entire URL must match including search parameters 1241cb0ef41Sopenharmony_ciand hash fragment. `./a.js?b` will not be used when attempting to load 1251cb0ef41Sopenharmony_ci`./a.js` and vice versa. 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ciTo generate integrity strings, a script such as 1281cb0ef41Sopenharmony_ci`node -e 'process.stdout.write("sha256-");process.stdin.pipe(crypto.createHash("sha256").setEncoding("base64")).pipe(process.stdout)' < FILE` 1291cb0ef41Sopenharmony_cican be used. 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ciIntegrity can be specified as the boolean value `true` to accept any 1321cb0ef41Sopenharmony_cibody for the resource which can be useful for local development. It is not 1331cb0ef41Sopenharmony_cirecommended in production since it would allow unexpected alteration of 1341cb0ef41Sopenharmony_ciresources to be considered valid. 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci##### Dependency redirection 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ciAn application may need to ship patched versions of modules or to prevent 1391cb0ef41Sopenharmony_cimodules from allowing all modules access to all other modules. Redirection 1401cb0ef41Sopenharmony_cican be used by intercepting attempts to load the modules wishing to be 1411cb0ef41Sopenharmony_cireplaced. 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci```json 1441cb0ef41Sopenharmony_ci{ 1451cb0ef41Sopenharmony_ci "resources": { 1461cb0ef41Sopenharmony_ci "./app/checked.js": { 1471cb0ef41Sopenharmony_ci "dependencies": { 1481cb0ef41Sopenharmony_ci "fs": true, 1491cb0ef41Sopenharmony_ci "os": "./app/node_modules/alt-os", 1501cb0ef41Sopenharmony_ci "http": { "import": true } 1511cb0ef41Sopenharmony_ci } 1521cb0ef41Sopenharmony_ci } 1531cb0ef41Sopenharmony_ci } 1541cb0ef41Sopenharmony_ci} 1551cb0ef41Sopenharmony_ci``` 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ciThe dependencies are keyed by the requested specifier string and have values 1581cb0ef41Sopenharmony_ciof either `true`, `null`, a string pointing to a module to be resolved, 1591cb0ef41Sopenharmony_cior a conditions object. 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_ciThe specifier string does not perform any searching and must match exactly what 1621cb0ef41Sopenharmony_ciis provided to the `require()` or `import` except for a canonicalization step. 1631cb0ef41Sopenharmony_ciTherefore, multiple specifiers may be needed in the policy if it uses multiple 1641cb0ef41Sopenharmony_cidifferent strings to point to the same module (such as excluding the extension). 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ciSpecifier strings are canonicalized but not resolved prior to be used for 1671cb0ef41Sopenharmony_cimatching in order to have some compatibility with import maps, for example if a 1681cb0ef41Sopenharmony_ciresource `file:///C:/app/server.js` was given the following redirection from a 1691cb0ef41Sopenharmony_cipolicy located at `file:///C:/app/policy.json`: 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ci```json 1721cb0ef41Sopenharmony_ci{ 1731cb0ef41Sopenharmony_ci "resources": { 1741cb0ef41Sopenharmony_ci "file:///C:/app/utils.js": { 1751cb0ef41Sopenharmony_ci "dependencies": { 1761cb0ef41Sopenharmony_ci "./utils.js": "./utils-v2.js" 1771cb0ef41Sopenharmony_ci } 1781cb0ef41Sopenharmony_ci } 1791cb0ef41Sopenharmony_ci } 1801cb0ef41Sopenharmony_ci} 1811cb0ef41Sopenharmony_ci``` 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ciAny specifier used to load `file:///C:/app/utils.js` would then be intercepted 1841cb0ef41Sopenharmony_ciand redirected to `file:///C:/app/utils-v2.js` instead regardless of using an 1851cb0ef41Sopenharmony_ciabsolute or relative specifier. However, if a specifier that is not an absolute 1861cb0ef41Sopenharmony_cior relative URL string is used, it would not be intercepted. So, if an import 1871cb0ef41Sopenharmony_cisuch as `import('#utils')` was used, it would not be intercepted. 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ciIf the value of the redirection is `true`, a "dependencies" field at the top of 1901cb0ef41Sopenharmony_cithe policy file will be used. If that field at the top of the policy file is 1911cb0ef41Sopenharmony_ci`true` the default node searching algorithms are used to find the module. 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_ciIf the value of the redirection is a string, it is resolved relative to 1941cb0ef41Sopenharmony_cithe manifest and then immediately used without searching. 1951cb0ef41Sopenharmony_ci 1961cb0ef41Sopenharmony_ciAny specifier string for which resolution is attempted and that is not listed in 1971cb0ef41Sopenharmony_cithe dependencies results in an error according to the policy. 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ciRedirection does not prevent access to APIs through means such as direct access 2001cb0ef41Sopenharmony_cito `require.cache` or through `module.constructor` which allow access to 2011cb0ef41Sopenharmony_ciloading modules. Policy redirection only affects specifiers to `require()` and 2021cb0ef41Sopenharmony_ci`import`. Other means, such as to prevent undesired access to APIs through 2031cb0ef41Sopenharmony_civariables, are necessary to lock down that path of loading modules. 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ciA boolean value of `true` for the dependencies map can be specified to allow a 2061cb0ef41Sopenharmony_cimodule to load any specifier without redirection. This can be useful for local 2071cb0ef41Sopenharmony_cidevelopment and may have some valid usage in production, but should be used 2081cb0ef41Sopenharmony_cionly with care after auditing a module to ensure its behavior is valid. 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ciSimilar to `"exports"` in `package.json`, dependencies can also be specified to 2111cb0ef41Sopenharmony_cibe objects containing conditions which branch how dependencies are loaded. In 2121cb0ef41Sopenharmony_cithe preceding example, `"http"` is allowed when the `"import"` condition is 2131cb0ef41Sopenharmony_cipart of loading it. 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_ciA value of `null` for the resolved value causes the resolution to fail. This 2161cb0ef41Sopenharmony_cican be used to ensure some kinds of dynamic access are explicitly prevented. 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ciUnknown values for the resolved module location cause failures but are 2191cb0ef41Sopenharmony_cinot guaranteed to be forward compatible. 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ci##### Example: Patched dependency 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ciRedirected dependencies can provide attenuated or modified functionality as fits 2241cb0ef41Sopenharmony_cithe application. For example, log data about timing of function durations by 2251cb0ef41Sopenharmony_ciwrapping the original: 2261cb0ef41Sopenharmony_ci 2271cb0ef41Sopenharmony_ci```js 2281cb0ef41Sopenharmony_ciconst original = require('fn'); 2291cb0ef41Sopenharmony_cimodule.exports = function fn(...args) { 2301cb0ef41Sopenharmony_ci console.time(); 2311cb0ef41Sopenharmony_ci try { 2321cb0ef41Sopenharmony_ci return new.target ? 2331cb0ef41Sopenharmony_ci Reflect.construct(original, args) : 2341cb0ef41Sopenharmony_ci Reflect.apply(original, this, args); 2351cb0ef41Sopenharmony_ci } finally { 2361cb0ef41Sopenharmony_ci console.timeEnd(); 2371cb0ef41Sopenharmony_ci } 2381cb0ef41Sopenharmony_ci}; 2391cb0ef41Sopenharmony_ci``` 2401cb0ef41Sopenharmony_ci 2411cb0ef41Sopenharmony_ci#### Scopes 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ciUse the `"scopes"` field of a manifest to set configuration for many resources 2441cb0ef41Sopenharmony_ciat once. The `"scopes"` field works by matching resources by their segments. 2451cb0ef41Sopenharmony_ciIf a scope or resource includes `"cascade": true`, unknown specifiers will 2461cb0ef41Sopenharmony_cibe searched for in their containing scope. The containing scope for cascading 2471cb0ef41Sopenharmony_ciis found by recursively reducing the resource URL by removing segments for 2481cb0ef41Sopenharmony_ci[special schemes][], keeping trailing `"/"` suffixes, and removing the query and 2491cb0ef41Sopenharmony_cihash fragment. This leads to the eventual reduction of the URL to its origin. 2501cb0ef41Sopenharmony_ciIf the URL is non-special the scope will be located by the URL's origin. If no 2511cb0ef41Sopenharmony_ciscope is found for the origin or in the case of opaque origins, a protocol 2521cb0ef41Sopenharmony_cistring can be used as a scope. If no scope is found for the URL's protocol, a 2531cb0ef41Sopenharmony_cifinal empty string `""` scope will be used. 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ciNote, `blob:` URLs adopt their origin from the path they contain, and so a scope 2561cb0ef41Sopenharmony_ciof `"blob:https://nodejs.org"` will have no effect since no URL can have an 2571cb0ef41Sopenharmony_ciorigin of `blob:https://nodejs.org`; URLs starting with 2581cb0ef41Sopenharmony_ci`blob:https://nodejs.org/` will use `https://nodejs.org` for its origin and 2591cb0ef41Sopenharmony_cithus `https:` for its protocol scope. For opaque origin `blob:` URLs they will 2601cb0ef41Sopenharmony_cihave `blob:` for their protocol scope since they do not adopt origins. 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ci##### Example 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ci```json 2651cb0ef41Sopenharmony_ci{ 2661cb0ef41Sopenharmony_ci "scopes": { 2671cb0ef41Sopenharmony_ci "file:///C:/app/": {}, 2681cb0ef41Sopenharmony_ci "file:": {}, 2691cb0ef41Sopenharmony_ci "": {} 2701cb0ef41Sopenharmony_ci } 2711cb0ef41Sopenharmony_ci} 2721cb0ef41Sopenharmony_ci``` 2731cb0ef41Sopenharmony_ci 2741cb0ef41Sopenharmony_ciGiven a file located at `file:///C:/app/bin/main.js`, the following scopes would 2751cb0ef41Sopenharmony_cibe checked in order: 2761cb0ef41Sopenharmony_ci 2771cb0ef41Sopenharmony_ci1. `"file:///C:/app/bin/"` 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_ciThis determines the policy for all file based resources within 2801cb0ef41Sopenharmony_ci`"file:///C:/app/bin/"`. This is not in the `"scopes"` field of the policy and 2811cb0ef41Sopenharmony_ciwould be skipped. Adding this scope to the policy would cause it to be used 2821cb0ef41Sopenharmony_ciprior to the `"file:///C:/app/"` scope. 2831cb0ef41Sopenharmony_ci 2841cb0ef41Sopenharmony_ci2. `"file:///C:/app/"` 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ciThis determines the policy for all file based resources within 2871cb0ef41Sopenharmony_ci`"file:///C:/app/"`. This is in the `"scopes"` field of the policy and it would 2881cb0ef41Sopenharmony_cidetermine the policy for the resource at `file:///C:/app/bin/main.js`. If the 2891cb0ef41Sopenharmony_ciscope has `"cascade": true`, any unsatisfied queries about the resource would 2901cb0ef41Sopenharmony_cidelegate to the next relevant scope for `file:///C:/app/bin/main.js`, `"file:"`. 2911cb0ef41Sopenharmony_ci 2921cb0ef41Sopenharmony_ci3. `"file:///C:/"` 2931cb0ef41Sopenharmony_ci 2941cb0ef41Sopenharmony_ciThis determines the policy for all file based resources within `"file:///C:/"`. 2951cb0ef41Sopenharmony_ciThis is not in the `"scopes"` field of the policy and would be skipped. It would 2961cb0ef41Sopenharmony_cinot be used for `file:///C:/app/bin/main.js` unless `"file:///"` is set to 2971cb0ef41Sopenharmony_cicascade or is not in the `"scopes"` of the policy. 2981cb0ef41Sopenharmony_ci 2991cb0ef41Sopenharmony_ci4. `"file:///"` 3001cb0ef41Sopenharmony_ci 3011cb0ef41Sopenharmony_ciThis determines the policy for all file based resources on the `localhost`. This 3021cb0ef41Sopenharmony_ciis not in the `"scopes"` field of the policy and would be skipped. It would not 3031cb0ef41Sopenharmony_cibe used for `file:///C:/app/bin/main.js` unless `"file:///"` is set to cascade 3041cb0ef41Sopenharmony_cior is not in the `"scopes"` of the policy. 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ci5. `"file:"` 3071cb0ef41Sopenharmony_ci 3081cb0ef41Sopenharmony_ciThis determines the policy for all file based resources. It would not be used 3091cb0ef41Sopenharmony_cifor `file:///C:/app/bin/main.js` unless `"file:///"` is set to cascade or is not 3101cb0ef41Sopenharmony_ciin the `"scopes"` of the policy. 3111cb0ef41Sopenharmony_ci 3121cb0ef41Sopenharmony_ci6. `""` 3131cb0ef41Sopenharmony_ci 3141cb0ef41Sopenharmony_ciThis determines the policy for all resources. It would not be used for 3151cb0ef41Sopenharmony_ci`file:///C:/app/bin/main.js` unless `"file:"` is set to cascade. 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_ci##### Integrity using scopes 3181cb0ef41Sopenharmony_ci 3191cb0ef41Sopenharmony_ciSetting an integrity to `true` on a scope will set the integrity for any 3201cb0ef41Sopenharmony_ciresource not found in the manifest to `true`. 3211cb0ef41Sopenharmony_ci 3221cb0ef41Sopenharmony_ciSetting an integrity to `null` on a scope will set the integrity for any 3231cb0ef41Sopenharmony_ciresource not found in the manifest to fail matching. 3241cb0ef41Sopenharmony_ci 3251cb0ef41Sopenharmony_ciNot including an integrity is the same as setting the integrity to `null`. 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_ci`"cascade"` for integrity checks will be ignored if `"integrity"` is explicitly 3281cb0ef41Sopenharmony_ciset. 3291cb0ef41Sopenharmony_ci 3301cb0ef41Sopenharmony_ciThe following example allows loading any file: 3311cb0ef41Sopenharmony_ci 3321cb0ef41Sopenharmony_ci```json 3331cb0ef41Sopenharmony_ci{ 3341cb0ef41Sopenharmony_ci "scopes": { 3351cb0ef41Sopenharmony_ci "file:": { 3361cb0ef41Sopenharmony_ci "integrity": true 3371cb0ef41Sopenharmony_ci } 3381cb0ef41Sopenharmony_ci } 3391cb0ef41Sopenharmony_ci} 3401cb0ef41Sopenharmony_ci``` 3411cb0ef41Sopenharmony_ci 3421cb0ef41Sopenharmony_ci##### Dependency redirection using scopes 3431cb0ef41Sopenharmony_ci 3441cb0ef41Sopenharmony_ciThe following example, would allow access to `fs` for all resources within 3451cb0ef41Sopenharmony_ci`./app/`: 3461cb0ef41Sopenharmony_ci 3471cb0ef41Sopenharmony_ci```json 3481cb0ef41Sopenharmony_ci{ 3491cb0ef41Sopenharmony_ci "resources": { 3501cb0ef41Sopenharmony_ci "./app/checked.js": { 3511cb0ef41Sopenharmony_ci "cascade": true, 3521cb0ef41Sopenharmony_ci "integrity": true 3531cb0ef41Sopenharmony_ci } 3541cb0ef41Sopenharmony_ci }, 3551cb0ef41Sopenharmony_ci "scopes": { 3561cb0ef41Sopenharmony_ci "./app/": { 3571cb0ef41Sopenharmony_ci "dependencies": { 3581cb0ef41Sopenharmony_ci "fs": true 3591cb0ef41Sopenharmony_ci } 3601cb0ef41Sopenharmony_ci } 3611cb0ef41Sopenharmony_ci } 3621cb0ef41Sopenharmony_ci} 3631cb0ef41Sopenharmony_ci``` 3641cb0ef41Sopenharmony_ci 3651cb0ef41Sopenharmony_ciThe following example, would allow access to `fs` for all `data:` resources: 3661cb0ef41Sopenharmony_ci 3671cb0ef41Sopenharmony_ci```json 3681cb0ef41Sopenharmony_ci{ 3691cb0ef41Sopenharmony_ci "resources": { 3701cb0ef41Sopenharmony_ci "data:text/javascript,import('node:fs');": { 3711cb0ef41Sopenharmony_ci "cascade": true, 3721cb0ef41Sopenharmony_ci "integrity": true 3731cb0ef41Sopenharmony_ci } 3741cb0ef41Sopenharmony_ci }, 3751cb0ef41Sopenharmony_ci "scopes": { 3761cb0ef41Sopenharmony_ci "data:": { 3771cb0ef41Sopenharmony_ci "dependencies": { 3781cb0ef41Sopenharmony_ci "fs": true 3791cb0ef41Sopenharmony_ci } 3801cb0ef41Sopenharmony_ci } 3811cb0ef41Sopenharmony_ci } 3821cb0ef41Sopenharmony_ci} 3831cb0ef41Sopenharmony_ci``` 3841cb0ef41Sopenharmony_ci 3851cb0ef41Sopenharmony_ci##### Example: import maps emulation 3861cb0ef41Sopenharmony_ci 3871cb0ef41Sopenharmony_ciGiven an import map: 3881cb0ef41Sopenharmony_ci 3891cb0ef41Sopenharmony_ci```json 3901cb0ef41Sopenharmony_ci{ 3911cb0ef41Sopenharmony_ci "imports": { 3921cb0ef41Sopenharmony_ci "react": "./app/node_modules/react/index.js" 3931cb0ef41Sopenharmony_ci }, 3941cb0ef41Sopenharmony_ci "scopes": { 3951cb0ef41Sopenharmony_ci "./ssr/": { 3961cb0ef41Sopenharmony_ci "react": "./app/node_modules/server-side-react/index.js" 3971cb0ef41Sopenharmony_ci } 3981cb0ef41Sopenharmony_ci } 3991cb0ef41Sopenharmony_ci} 4001cb0ef41Sopenharmony_ci``` 4011cb0ef41Sopenharmony_ci 4021cb0ef41Sopenharmony_ci```json 4031cb0ef41Sopenharmony_ci{ 4041cb0ef41Sopenharmony_ci "dependencies": true, 4051cb0ef41Sopenharmony_ci "scopes": { 4061cb0ef41Sopenharmony_ci "": { 4071cb0ef41Sopenharmony_ci "cascade": true, 4081cb0ef41Sopenharmony_ci "dependencies": { 4091cb0ef41Sopenharmony_ci "react": "./app/node_modules/react/index.js" 4101cb0ef41Sopenharmony_ci } 4111cb0ef41Sopenharmony_ci }, 4121cb0ef41Sopenharmony_ci "./ssr/": { 4131cb0ef41Sopenharmony_ci "cascade": true, 4141cb0ef41Sopenharmony_ci "dependencies": { 4151cb0ef41Sopenharmony_ci "react": "./app/node_modules/server-side-react/index.js" 4161cb0ef41Sopenharmony_ci } 4171cb0ef41Sopenharmony_ci } 4181cb0ef41Sopenharmony_ci } 4191cb0ef41Sopenharmony_ci} 4201cb0ef41Sopenharmony_ci``` 4211cb0ef41Sopenharmony_ci 4221cb0ef41Sopenharmony_ci[Import maps][] assume you can get any resource by default. This means 4231cb0ef41Sopenharmony_ci`"dependencies"` at the top level of the policy should be set to `true`. 4241cb0ef41Sopenharmony_ciPolicies require this to be opt-in since it enables all resources of the 4251cb0ef41Sopenharmony_ciapplication cross linkage which doesn't make sense for many scenarios. They also 4261cb0ef41Sopenharmony_ciassume any given scope has access to any scope above its allowed dependencies; 4271cb0ef41Sopenharmony_ciall scopes emulating import maps must set `"cascade": true`. 4281cb0ef41Sopenharmony_ci 4291cb0ef41Sopenharmony_ciImport maps only have a single top level scope for their "imports". So for 4301cb0ef41Sopenharmony_ciemulating `"imports"` use the `""` scope. For emulating `"scopes"` use the 4311cb0ef41Sopenharmony_ci`"scopes"` in a similar manner to how `"scopes"` works in import maps. 4321cb0ef41Sopenharmony_ci 4331cb0ef41Sopenharmony_ciCaveats: Policies do not use string matching for various finding of scope. They 4341cb0ef41Sopenharmony_cido URL traversals. This means things like `blob:` and `data:` URLs might not be 4351cb0ef41Sopenharmony_cientirely interoperable between the two systems. For example import maps can 4361cb0ef41Sopenharmony_cipartially match a `data:` or `blob:` URL by partitioning the URL on a `/` 4371cb0ef41Sopenharmony_cicharacter, policies intentionally cannot. For `blob:` URLs import map scopes do 4381cb0ef41Sopenharmony_cinot adopt the origin of the `blob:` URL. 4391cb0ef41Sopenharmony_ci 4401cb0ef41Sopenharmony_ciAdditionally, import maps only work on `import` so it may be desirable to add a 4411cb0ef41Sopenharmony_ci`"import"` condition to all dependency mappings. 4421cb0ef41Sopenharmony_ci 4431cb0ef41Sopenharmony_ci[Security Policy]: https://github.com/nodejs/node/blob/main/SECURITY.md 4441cb0ef41Sopenharmony_ci[import maps]: https://url.spec.whatwg.org/#relative-url-with-fragment-string 4451cb0ef41Sopenharmony_ci[relative-url string]: https://url.spec.whatwg.org/#relative-url-with-fragment-string 4461cb0ef41Sopenharmony_ci[special schemes]: https://url.spec.whatwg.org/#special-scheme 447