diff --git a/doc/api/cli.md b/doc/api/cli.md index 5d59844d4cbc72..9771bb3013dbe1 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -2322,6 +2322,9 @@ changes: Enable the Permission Model for current process. When enabled, the following permissions are restricted: +> See also [`--permission-audit`](#--permission-audit) for an audit-only mode +> that logs violations without denying access. + * File System - manageable through [`--allow-fs-read`][], [`--allow-fs-write`][] flags * Network - manageable through [`--allow-net`][] flag @@ -2337,9 +2340,22 @@ following permissions are restricted: added: v25.8.0 --> -Enable audit only for the permission model. When enabled, permission checks -are performed but access is not denied. Instead, a warning is emitted for -each permission violation via diagnostics channel. +Enable audit mode for the permission model. When enabled, permission checks +are performed but access is **not** denied — no `ERR_ACCESS_DENIED` error is +thrown. Instead, each permission violation is published through the +`node:diagnostics_channel` module, and execution continues normally. + +This flag does not require [`--permission`](#--permission) to be specified. The +`--allow-*` flags are not needed in audit mode, since no +access is denied. + +Audit mode is useful for discovering what permissions your application +requires before deploying with [`--permission`](#--permission). See the +[Permission Model][] documentation for the list of diagnostics channel names +and the message format. + +If both [`--permission`](#--permission) and `--permission-audit` are specified, +`--permission` takes precedence and the Permission Model runs in enforce mode. ### `--preserve-symlinks` diff --git a/doc/api/permissions.md b/doc/api/permissions.md index 3f2a6411d3f678..05a18db0457d28 100644 --- a/doc/api/permissions.md +++ b/doc/api/permissions.md @@ -48,6 +48,17 @@ will restrict access to all available permissions. The available permissions are documented by the [`--permission`][] flag. +The Permission Model has two operational modes: + +* **Enforce mode** (default when using [`--permission`][]): Access is denied and + an `ERR_ACCESS_DENIED` error is thrown for any operation the process has not + been granted permission to perform. +* **Audit mode** (when using [`--permission-audit`][]): Permission checks are + performed and violations are published through the diagnostics channel, but + access is **not** denied. Execution continues normally. This mode is useful + for discovering what permissions your application requires before deploying + with enforce mode. + When starting Node.js with `--permission`, the ability to access the file system through the `fs` module, access the network, spawn processes, use `node:worker_threads`, use native addons, use WASI, use @@ -77,8 +88,8 @@ flag. For WASI, use the [`--allow-wasi`][] flag. For FFI, use the #### Runtime API When enabling the Permission Model through the [`--permission`][] -flag a new property `permission` is added to the `process` object. -This property contains the following functions: +or [`--permission-audit`][] flags, a new property `permission` is added to the +`process` object. This property contains the following functions: ##### `permission.has(scope[, reference])` @@ -127,6 +138,56 @@ process.permission.has('fs.read', '/etc/myapp/config.json'); // false process.permission.drop('child'); ``` +#### Audit Mode + +The [`--permission-audit`][] flag enables audit mode for the Permission Model. +In audit mode, permission checks are performed but access is **not** denied — +no `ERR_ACCESS_DENIED` error is thrown. Instead, each permission violation is +published through the `node:diagnostics_channel` module, allowing the +application to observe and log which operations would be denied under enforce +mode. Execution continues normally. + +Audit mode is useful for discovering what permissions your application +requires before deploying with [`--permission`][]. It can also be combined +with the [`--allow-fs-read`][], [`--allow-fs-write`][], [`--allow-net`][], +[`--allow-child-process`][], [`--allow-worker`][], [`--allow-addons`][], +[`--allow-wasi`][], and [`--allow-ffi`][] flags to audit a subset of +permissions while granting others. + +When a permission check fails in audit mode, a message is published to the +diagnostics channel corresponding to the denied scope. The channel names are: + +* `node:permission-model:fs` — File System (read and write) +* `node:permission-model:net` — Network +* `node:permission-model:child` — Child Process +* `node:permission-model:worker` — Worker Threads +* `node:permission-model:inspector` — Inspector +* `node:permission-model:wasi` — WASI +* `node:permission-model:addon` — Native Addons +* `node:permission-model:ffi` — FFI + +Each message is an object with the following properties: + +* `permission` {string} The name of the denied permission scope. +* `resource` {string} The resource that access was denied to (e.g. a file path + or host). + +```js +const diagnostics_channel = require('node:diagnostics_channel'); + +diagnostics_channel.channel('node:permission-model:fs').subscribe((msg) => { + console.log(`Permission denied: ${msg.permission} on ${msg.resource}`); +}); + +// Running with --permission-audit, this publishes a diagnostics channel +// message but does not throw +const fs = require('node:fs'); +fs.readFileSync('/etc/passwd'); +``` + +If both [`--permission`][] and [`--permission-audit`][] are specified, +`--permission` takes precedence and the Permission Model runs in enforce mode. + #### File System Permissions The Permission Model, by default, restricts access to the file system through the `node:fs` module. @@ -324,6 +385,7 @@ Developers relying on --permission to sandbox untrusted code should be aware tha [`--allow-net`]: cli.md#--allow-net [`--allow-wasi`]: cli.md#--allow-wasi [`--allow-worker`]: cli.md#--allow-worker +[`--permission-audit`]: cli.md#--permission-audit [`--permission`]: cli.md#--permission [`npx`]: https://docs.npmjs.com/cli/commands/npx [`permission.has()`]: process.md#processpermissionhasscope-reference diff --git a/doc/api/process.md b/doc/api/process.md index 0a7f85700ae85a..48c7e868ae8fe1 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -3128,7 +3128,8 @@ added: v20.0.0 * Type: {Object} -This API is available through the [`--permission`][] flag. +This API is available through the [`--permission`][] or +[`--permission-audit`][] flags. `process.permission` is an object whose methods are used to manage permissions for the current process. Additional documentation is available in the @@ -3149,6 +3150,9 @@ If no reference is provided, a global scope is assumed, for instance, `process.permission.has('fs.read')` will check if the process has ALL file system read permissions. +In audit mode ([`--permission-audit`][]), this method still returns the actual +permission status, but denied operations will not throw `ERR_ACCESS_DENIED`. + The reference has a meaning based on the provided scope. For example, the reference when the scope is File System means files and folders. @@ -3183,6 +3187,10 @@ Drops the specified permission from the current process. This operation is **irreversible** — once a permission is dropped, it cannot be restored through any Node.js API. +In audit mode ([`--permission-audit`][]), dropping a permission takes effect, +but since denied operations do not throw, the impact is limited to changing the +return value of `permission.has()`. + If no reference is provided, the entire scope is dropped. For example, `process.permission.drop('fs.read')` will revoke ALL file system read permissions. @@ -4614,6 +4622,7 @@ cases: [`'message'`]: child_process.md#event-message [`'uncaughtException'`]: #event-uncaughtexception [`--no-deprecation`]: cli.md#--no-deprecation +[`--permission-audit`]: cli.md#--permission-audit [`--permission`]: cli.md#--permission [`--unhandled-rejections`]: cli.md#--unhandled-rejectionsmode [`Buffer`]: buffer.md diff --git a/doc/node.1 b/doc/node.1 index cc51fde7661ac3..498e10137abf1b 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -1166,6 +1166,7 @@ developers may leverage to detect deprecated API usage. .It Fl -permission Enable the Permission Model for current process. When enabled, the following permissions are restricted: + .Bl -bullet .It File System - manageable through @@ -1185,9 +1186,19 @@ FFI - manageable through \fB--allow-ffi\fR flag .El . .It Fl -permission-audit -Enable audit only for the permission model. When enabled, permission checks -are performed but access is not denied. Instead, a warning is emitted for -each permission violation via diagnostics channel. +Enable audit mode for the permission model. When enabled, permission checks +are performed but access is \fBnot\fR denied — no \fBERR_ACCESS_DENIED\fR error is +thrown. Instead, each permission violation is published through the +\fBnode:diagnostics_channel\fR module, and execution continues normally. +This flag does not require \fB--permission\fR to be specified. The +\fB--allow-*\fR flags are not needed in audit mode, since no +access is denied. +Audit mode is useful for discovering what permissions your application +requires before deploying with \fB--permission\fR. See the +Permission Model documentation for the list of diagnostics channel names +and the message format. +If both \fB--permission\fR and \fB--permission-audit\fR are specified, +\fB--permission\fR takes precedence and the Permission Model runs in enforce mode. . .It Fl -preserve-symlinks Instructs the module loader to preserve symbolic links when resolving and