Deno running a script without file permissions[/caption]
Node.js, on the other hand, has gone for 10+ years with the ability to read from the file system enabled by default for all Node.js applications. Changing that to reject file system access by default would quite literally break the workflow for tens of millions, if not hundreds of millions, of users globally. To be clear, the Node.js project absolutely could decide to follow deno's lead here and lockdown file system, network and other resources by default, but doing so would likely be the largest breaking change in Node.js history. It's possible but extremely unlikely to ever happen.
Any permission system added to Node.js must be backwards compatible with the existing ecosystem in order to succeed. Simply put, that means it will always be opt-in as opposed to deno's explicit opt-out approach.
For the sake of this conversation, then, let's start by defining command-line arguments for the node binary that explicitly list which permissions are granted and which are denied:
$ node --policy-deny=net --policy-grant=net.dns We'll worry about the actual permissions a bit later. In a Node.js permission model, to remain backwards compatible with the existing ecosystem and not break the planet, we have to assume that all permissions are granted by default. In this example then, only the
net permission is denied. The
--policy-grant does not need to explicitly list file system access (for instance) because file system access is already granted. What we do have to list in
--policy-grant are any adjustments to the denied permissions. In the example, we assume that permissions are hierarchical and that
--policy-deny=net denies all access to network -related APIs, but we want to allow the application to go ahead and access Node's built-in
To determine the active permissions, we start with an assumption that all permissions are granted, remove those that are explicitly and implicitly denied, then add back in those that are explicitly granted.
The immediate next question should be: What permissions are implicitly denied if we're assuming that all permissions are granted by default?
A core part of Node.js is the ability to spawn child processes and load native addons. It does no good for Node.js to restrict a process's ability to access the filesystem if the script can just turn around and spawn a separate process that does not have that same restriction! Likewise, given that native addons can directly link to system libraries and execute system calls, they can be used to completely bypass any permissions that have been denied.
The assumption, then, is that explicitly denying any permission should also implicitly deny other permissions that could be used to bypass those restrictions. In the above example, invoking the node binary with
--policy-deny=net would also restrict access to loading native addons and spawning child processes. The
--policy-grant would be used to explicitly re-enable those implicitly denied permissions if necessary.