diff --git a/doc/api/cli.md b/doc/api/cli.md index ae0f81b5ec53..61ac216a5e3f 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -2130,6 +2130,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 * Child Process - manageable through [`--allow-child-process`][] flag @@ -2137,6 +2140,29 @@ following permissions are restricted: * WASI - manageable through [`--allow-wasi`][] flag * Addons - manageable through [`--allow-addons`][] flag +### `--permission-audit` + + + +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` + +> Stability: 1.1 - Active Development + +* `scope` {string} +* `reference` {string} + +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. + +When a reference is provided, only the permission for that specific resource +is dropped. For example, `process.permission.drop('fs.read', '/etc/myapp')` +will revoke read access to that directory while keeping other read +permissions intact. + +**Important:** You can only drop the exact resource that was explicitly +granted. The reference passed to `drop()` must match the original grant: + +* If a permission was granted using a wildcard (`*`), such as + `--allow-fs-read=*`, individual paths cannot be dropped - only the entire + scope can be dropped (by calling `drop()` without a reference). +* If a directory was granted (e.g. `--allow-fs-read=/my/folder`), you cannot + drop access to individual files inside it. You must drop the same directory + that was granted. Any remaining grants continue to apply. + +The available scopes are the same as [`process.permission.has()`][]: + +* `fs` - All File System (drops both read and write) +* `fs.read` - File System read operations +* `fs.write` - File System write operations +* `child` - Child process spawning operations +* `worker` - Worker thread spawning operation +* `inspector` - Inspector operations +* `wasi` - WASI operations +* `addon` - Native addon operations + +```js +const fs = require('node:fs'); + +// Read configuration during startup +const config = fs.readFileSync('/etc/myapp/config.json', 'utf8'); + +// Drop read access to the config directory after initialization +process.permission.drop('fs.read', '/etc/myapp'); + +// This will now throw ERR_ACCESS_DENIED +fs.readFileSync('/etc/myapp/config.json'); +``` + ## `process.pid`