Updated
Published
The Node.js Permission Model
Learn the ins and outs of the new Node.js Permission Model.
The release of Node.js 20 includes a new Permission Model. Why is this important? It allows developers to restrict Node.js scripts from accessing the filesystem, child processes, and worker threads.
Table of Contents
- Getting Started
- Permissions
- Auditing Permissions Without Enforcement
- Checking for Filesystem Permissions
- Checking Permissions for Child Processes and Worker Threads
- Conclusion
- Further Reading
Getting Started
To use the new Permission model you will need to download version 20 or newer from nodejs.org or your favorite Node.js version manager. (Check out Volta!)
Enable the Permission Model by passing the
--permission
flag to the node command. For example: node --permission some-script.js.
Update! Node v23.5.0 marks the
permissions model as stable. If you are using an older version of Node, you will
need to use --experimental-permission instead.
Permissions
By itself, --experimental-permission will lock down the process and prevent access
to the filesystem, child processes, and worker threads. Use this flag in conjunction
with the following flags to granularly enable permissions on a per-process basis.
--allow-fs-read
This flag allows access to read from the filesystem (not write). To allow
full read access, use: --allow-fs-read=*. Or pass a comma-separated list
of paths to limit access: --allow-fs-read=/some/path,/some/other/file.json.
--allow-fs-write
This flag allows access to write to the filesystem (not read). To allow
full write access, use: --allow-fs-write=*. Or pass a comma-separated list
of paths to limit access: --allow-fs-write=/some/path,/some/other/file.json.
--allow-child-process
This flag allows access to running child processes. Currently, there is no way to
restrict while child processes can be spawned. This means that a script could use
a child process to gain write access to the system without specifically allowing
it via --allow-fs-write.
--allow-worker
This flag allows worker threads to be spawned. The worker thread will retain the same permissions as the process that spawned it.
--allow-addons
This flag allows native addons to be used. This is available in Node.js version 21.6.0.
--allow-wasi
This flag allows WASI instances using the web assembly system interface module. This is avaiable in Node.js version 22.3.0
--allow-net
This flag allows http requests to be made. This is available in Node.js version 25.0.0
Auditing Permissions Without Enforcement
When developing and testing your application’s permission requirements, it can be
helpful to see what permissions are being requested without actually denying access.
Node.js v25.8.0 introduces the
--permission-audit
flag for exactly this purpose.
When you use --permission-audit, permission checks are still performed, but
instead of denying access with an ERR_ACCESS_DENIED error, Node.js emits a
warning for each permission violation via the diagnostics channel. This allows
you to test your permissions or identify the permissions your application needs
Checking for Filesystem Permissions
Now that you can restrict permissions to a given script. How does the script see if it has the necessary permissions to proceed?
To check permissions, a script can use process.permission.has().
This new function returns true or false if the given process has permission to the
provided scope. The scope can be either fs, fs.read, or fs.write for filesystem access,
read access, and write access respectively.
The second, optional, argument to process.permission.has() is a path to test
for access. For example, to check for write access to a certain path, use:
process.permission.has('fs.write', '/some/path').
Checking Permissions for Child Processes and Worker Threads
The process.permission.has() function will only tell you if the script has
file system access. The only way to check for child process and worker thread access
is to handle the ERR_ACCESS_DENIED error that gets thrown if permission is denied.
Conclusion
It is important to note that the permission model is experimental in Node.js version 20. And also, at this time Node.js 20 is not the supported LTS. So the Permission Model may be subject to change in the future. That being said, it is exciting to see where Node.js will be in the coming releases!