Skip to content

Commit 4be571d

Browse files
edsadraduh95
authored andcommitted
doc: document --permission-audit audit mode behavior
Expand the documentation for the --permission-audit flag, which was fixed in 51c09ea to no longer throw ERR_ACCESS_DENIED on denied operations. The previous docs only had a two-sentence description in cli.md and no mention in the permissions guide or process.permission API docs. - permissions.md: add enforce vs audit mode overview, a new "Audit Mode" subsection listing the diagnostics channel names (node:permission-model:*) and the { permission, resource } message shape, and a usage example. Update the Runtime API section to mention both --permission and --permission-audit. - cli.md: expand the --permission-audit section to clarify that --permission is not required, --allow-* flags are not needed, errors are not thrown, and --permission takes precedence when both are set. Add a cross-reference from --permission to --permission-audit. - process.md: note that process.permission is available under both flags, and clarify permission.has() and permission.drop() behavior in audit mode. - node.1: regenerated via `make node.1`. Refs: #64426 Signed-off-by: Adrian Estrada <edsadr@gmail.com> PR-URL: #64791 Reviewed-By: Aviv Keller <me@aviv.sh> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
1 parent e48b917 commit 4be571d

4 files changed

Lines changed: 107 additions & 9 deletions

File tree

doc/api/cli.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2316,6 +2316,9 @@ changes:
23162316
Enable the Permission Model for current process. When enabled, the
23172317
following permissions are restricted:
23182318

2319+
> See also [`--permission-audit`](#--permission-audit) for an audit-only mode
2320+
> that logs violations without denying access.
2321+
23192322
* File System - manageable through
23202323
[`--allow-fs-read`][], [`--allow-fs-write`][] flags
23212324
* Network - manageable through [`--allow-net`][] flag
@@ -2331,9 +2334,22 @@ following permissions are restricted:
23312334
added: v25.8.0
23322335
-->
23332336

2334-
Enable audit only for the permission model. When enabled, permission checks
2335-
are performed but access is not denied. Instead, a warning is emitted for
2336-
each permission violation via diagnostics channel.
2337+
Enable audit mode for the permission model. When enabled, permission checks
2338+
are performed but access is **not** denied — no `ERR_ACCESS_DENIED` error is
2339+
thrown. Instead, each permission violation is published through the
2340+
`node:diagnostics_channel` module, and execution continues normally.
2341+
2342+
This flag does not require [`--permission`](#--permission) to be specified. The
2343+
`--allow-*` flags are not needed in audit mode, since no
2344+
access is denied.
2345+
2346+
Audit mode is useful for discovering what permissions your application
2347+
requires before deploying with [`--permission`](#--permission). See the
2348+
[Permission Model][] documentation for the list of diagnostics channel names
2349+
and the message format.
2350+
2351+
If both [`--permission`](#--permission) and `--permission-audit` are specified,
2352+
`--permission` takes precedence and the Permission Model runs in enforce mode.
23372353

23382354
### `--preserve-symlinks`
23392355

doc/api/permissions.md

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ will restrict access to all available permissions.
4848
The available permissions are documented by the [`--permission`][]
4949
flag.
5050

51+
The Permission Model has two operational modes:
52+
53+
* **Enforce mode** (default when using [`--permission`][]): Access is denied and
54+
an `ERR_ACCESS_DENIED` error is thrown for any operation the process has not
55+
been granted permission to perform.
56+
* **Audit mode** (when using [`--permission-audit`][]): Permission checks are
57+
performed and violations are published through the diagnostics channel, but
58+
access is **not** denied. Execution continues normally. This mode is useful
59+
for discovering what permissions your application requires before deploying
60+
with enforce mode.
61+
5162
When starting Node.js with `--permission`,
5263
the ability to access the file system through the `fs` module, access the network,
5364
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
7788
#### Runtime API
7889

7990
When enabling the Permission Model through the [`--permission`][]
80-
flag a new property `permission` is added to the `process` object.
81-
This property contains the following functions:
91+
or [`--permission-audit`][] flags, a new property `permission` is added to the
92+
`process` object. This property contains the following functions:
8293

8394
##### `permission.has(scope[, reference])`
8495

@@ -127,6 +138,56 @@ process.permission.has('fs.read', '/etc/myapp/config.json'); // false
127138
process.permission.drop('child');
128139
```
129140

141+
#### Audit Mode
142+
143+
The [`--permission-audit`][] flag enables audit mode for the Permission Model.
144+
In audit mode, permission checks are performed but access is **not** denied —
145+
no `ERR_ACCESS_DENIED` error is thrown. Instead, each permission violation is
146+
published through the `node:diagnostics_channel` module, allowing the
147+
application to observe and log which operations would be denied under enforce
148+
mode. Execution continues normally.
149+
150+
Audit mode is useful for discovering what permissions your application
151+
requires before deploying with [`--permission`][]. It can also be combined
152+
with the [`--allow-fs-read`][], [`--allow-fs-write`][], [`--allow-net`][],
153+
[`--allow-child-process`][], [`--allow-worker`][], [`--allow-addons`][],
154+
[`--allow-wasi`][], and [`--allow-ffi`][] flags to audit a subset of
155+
permissions while granting others.
156+
157+
When a permission check fails in audit mode, a message is published to the
158+
diagnostics channel corresponding to the denied scope. The channel names are:
159+
160+
* `node:permission-model:fs` — File System (read and write)
161+
* `node:permission-model:net` — Network
162+
* `node:permission-model:child` — Child Process
163+
* `node:permission-model:worker` — Worker Threads
164+
* `node:permission-model:inspector` — Inspector
165+
* `node:permission-model:wasi` — WASI
166+
* `node:permission-model:addon` — Native Addons
167+
* `node:permission-model:ffi` — FFI
168+
169+
Each message is an object with the following properties:
170+
171+
* `permission` {string} The name of the denied permission scope.
172+
* `resource` {string} The resource that access was denied to (e.g. a file path
173+
or host).
174+
175+
```js
176+
const diagnostics_channel = require('node:diagnostics_channel');
177+
178+
diagnostics_channel.channel('node:permission-model:fs').subscribe((msg) => {
179+
console.log(`Permission denied: ${msg.permission} on ${msg.resource}`);
180+
});
181+
182+
// Running with --permission-audit, this publishes a diagnostics channel
183+
// message but does not throw
184+
const fs = require('node:fs');
185+
fs.readFileSync('/etc/passwd');
186+
```
187+
188+
If both [`--permission`][] and [`--permission-audit`][] are specified,
189+
`--permission` takes precedence and the Permission Model runs in enforce mode.
190+
130191
#### File System Permissions
131192

132193
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
324385
[`--allow-net`]: cli.md#--allow-net
325386
[`--allow-wasi`]: cli.md#--allow-wasi
326387
[`--allow-worker`]: cli.md#--allow-worker
388+
[`--permission-audit`]: cli.md#--permission-audit
327389
[`--permission`]: cli.md#--permission
328390
[`npx`]: https://docs.npmjs.com/cli/commands/npx
329391
[`permission.has()`]: process.md#processpermissionhasscope-reference

doc/api/process.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3127,7 +3127,8 @@ added: v20.0.0
31273127
31283128
* Type: {Object}
31293129
3130-
This API is available through the [`--permission`][] flag.
3130+
This API is available through the [`--permission`][] or
3131+
[`--permission-audit`][] flags.
31313132
31323133
`process.permission` is an object whose methods are used to manage permissions
31333134
for the current process. Additional documentation is available in the
@@ -3148,6 +3149,9 @@ If no reference is provided, a global scope is assumed, for instance,
31483149
`process.permission.has('fs.read')` will check if the process has ALL
31493150
file system read permissions.
31503151
3152+
In audit mode ([`--permission-audit`][]), this method still returns the actual
3153+
permission status, but denied operations will not throw `ERR_ACCESS_DENIED`.
3154+
31513155
The reference has a meaning based on the provided scope. For example,
31523156
the reference when the scope is File System means files and folders.
31533157
@@ -3182,6 +3186,10 @@ Drops the specified permission from the current process. This operation is
31823186
**irreversible** — once a permission is dropped, it cannot be restored through
31833187
any Node.js API.
31843188
3189+
In audit mode ([`--permission-audit`][]), dropping a permission takes effect,
3190+
but since denied operations do not throw, the impact is limited to changing the
3191+
return value of `permission.has()`.
3192+
31853193
If no reference is provided, the entire scope is dropped. For example,
31863194
`process.permission.drop('fs.read')` will revoke ALL file system read
31873195
permissions.
@@ -4612,6 +4620,7 @@ cases:
46124620
[`'message'`]: child_process.md#event-message
46134621
[`'uncaughtException'`]: #event-uncaughtexception
46144622
[`--no-deprecation`]: cli.md#--no-deprecation
4623+
[`--permission-audit`]: cli.md#--permission-audit
46154624
[`--permission`]: cli.md#--permission
46164625
[`--unhandled-rejections`]: cli.md#--unhandled-rejectionsmode
46174626
[`Buffer`]: buffer.md

doc/node.1

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,7 @@ developers may leverage to detect deprecated API usage.
11651165
.It Fl -permission
11661166
Enable the Permission Model for current process. When enabled, the
11671167
following permissions are restricted:
1168+
11681169
.Bl -bullet
11691170
.It
11701171
File System - manageable through
@@ -1184,9 +1185,19 @@ FFI - manageable through \fB--allow-ffi\fR flag
11841185
.El
11851186
.
11861187
.It Fl -permission-audit
1187-
Enable audit only for the permission model. When enabled, permission checks
1188-
are performed but access is not denied. Instead, a warning is emitted for
1189-
each permission violation via diagnostics channel.
1188+
Enable audit mode for the permission model. When enabled, permission checks
1189+
are performed but access is \fBnot\fR denied — no \fBERR_ACCESS_DENIED\fR error is
1190+
thrown. Instead, each permission violation is published through the
1191+
\fBnode:diagnostics_channel\fR module, and execution continues normally.
1192+
This flag does not require \fB--permission\fR to be specified. The
1193+
\fB--allow-*\fR flags are not needed in audit mode, since no
1194+
access is denied.
1195+
Audit mode is useful for discovering what permissions your application
1196+
requires before deploying with \fB--permission\fR. See the
1197+
Permission Model documentation for the list of diagnostics channel names
1198+
and the message format.
1199+
If both \fB--permission\fR and \fB--permission-audit\fR are specified,
1200+
\fB--permission\fR takes precedence and the Permission Model runs in enforce mode.
11901201
.
11911202
.It Fl -preserve-symlinks
11921203
Instructs the module loader to preserve symbolic links when resolving and

0 commit comments

Comments
 (0)