@@ -48,6 +48,17 @@ will restrict access to all available permissions. |
48 | 48 | The available permissions are documented by the [`--permission`][] |
49 | 49 | flag. |
50 | 50 |
|
| 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 | + |
51 | 62 | When starting Node.js with `--permission`, |
52 | 63 | the ability to access the file system through the `fs` module, access the network, |
53 | 64 | 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 |
77 | 88 | #### Runtime API |
78 | 89 |
|
79 | 90 | 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: |
82 | 93 |
|
83 | 94 | ##### `permission.has(scope[, reference])` |
84 | 95 |
|
@@ -127,6 +138,56 @@ process.permission.has('fs.read', '/etc/myapp/config.json'); // false |
127 | 138 | process.permission.drop('child'); |
128 | 139 | ``` |
129 | 140 |
|
| 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 | + |
130 | 191 | #### File System Permissions |
131 | 192 |
|
132 | 193 | 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 |
324 | 385 | [`--allow-net`]: cli.md#--allow-net |
325 | 386 | [`--allow-wasi`]: cli.md#--allow-wasi |
326 | 387 | [`--allow-worker`]: cli.md#--allow-worker |
| 388 | +[`--permission-audit`]: cli.md#--permission-audit |
327 | 389 | [`--permission`]: cli.md#--permission |
328 | 390 | [`npx`]: https://docs.npmjs.com/cli/commands/npx |
329 | 391 | [`permission.has()`]: process.md#processpermissionhasscope-reference |