lume
lume copied to clipboard
Use minimum system permissions necessary
I noticed that the default dev script invokes itself with full permissions over the entire system. Ideally, Lume should function fine if invoked with the following minimum permissions.
$ deno run --allow-net=localhost:3000 --allow-read=./ --allow-write=./_site lume/task.ts
It's not so easy, for several reasons:
- This depends on the site configuration. For example, if the site is configured to use a different
dest
folder or if the server port is different (like8080
instead of3000
), the command should change also the permissions configuration. -
deno run lume/task.ts
doesn't work, because thelume/task.ts
file is not resolved with the import map, so you have to include the full file url:deno run https://deno.land/x/[email protected]/task.ts
. But this introduce another url to maintain and keep up to date on update Lume, in addition to the Lume url in the import_map.json file. This is why the lume task isdeno eval "import 'lume/task.ts'"
becausedeno eval
takes the import_map.json file into account to resolve the imports, making this file a single source of truth. More info aboutdeno run
anddeno eval
here: https://github.com/denoland/deno/issues/14760 -
deno eval
has implicit all permissions (it's like--allow-all
). -
lume/task.ts
file just run https://github.com/lumeland/lume/blob/master/ci.ts and this file run the real deno command to run Lume with all required parameters. More info: https://github.com/lumeland/lume/blob/master/ci.ts#L107-L115
I'd like to simplify this in the near future, when this proposal is implemented: https://github.com/denoland/deno/issues/12763 so you can configure the permissions in the Deno config file.
This depends on the site configuration.
Point taken. Then the minimum permissions for most projects would be --allow-net=localhost --allow-read=./ --allow-write=./
. If some plugin needs to make other network requests, the user should need to explicitly allow that.
deno eval has implicit all permissions (it's like --allow-all).
After reading this issue, I can't help but feel the current behavior is a big mistake. If my understanding is correct, the lack of support for import maps in deno run
means the only ergonomic way to invoke "framework" CLIs is without any sandboxing. This erases a major benefit of Deno's security model.
And to preempt, I don't think this is bikeshedding. Given that Lume is plugin-based, it's plausible that there will be a long tail of unaudited, untrusted plugins. Why should plugins have exec permissions?
Potential (temporary) solution
I haven't thought about this too much... but this came across my mind as a potential solution. This way, only one line of code runs with global permissions, then the task.ts
process itself is sandboxed.
{
"importMap": "import_map.json",
"tasks": {
"lume": "deno run --allow-read=./ --allow-write=./ --allow-net=localhost $(deno eval \"console.log(JSON.parse(Deno.readTextFileSync('import_map.json')).imports['lume/'])\")task.ts",
"build": "deno task lume",
"serve": "deno task lume -s"
}
}
Of course this would also require changes to ci.ts
and task.ts
to remove the unnecessary self-invocation.
task.ts
and ci.ts
works as wrappers to execute the real CLI script (cli.ts
). This wrapper fixes different issues. So, restricting permissions to these files has no effect to cli.ts
(AFAIK, permissions are not propagated between childprocesses: a file with only --allow-run
could run a script passing the --allow-all
argument).
The use cases are so variable that this is the reason I've decided to run cli.ts
with --allow-all
, for example:
- Sites that fetch data from an external API, needs
allow-net
orallow-net=api-url
. - Sites that have different configurations depending on the environment variables (like
ENV=dev
) needs--allow-env
. - Sites that need to run some scripts during the build needs
--allow-run
- Sites that use some binary libraries connected with ffi needs
--allow-ffi
. - Sites that use WebAssembly libraries needs
--allow-read
to read the WebAssembly file.
Restricting the permissions right now can break many sites. I think it's better to let the users configure the permisisions once Deno team implements permission configuration in the deno.json file. In Lume 2.0 I'm planning to remove these wrapper files and depend only on deno.json that will be mandatory (unlike now, that both deno.json and import_map.json files are optional).
If you're concerned about that, the correct way to apply permissions is by running the cli.ts
file directly. You can create a task like this:
{
"importMap": "import_map.json",
"tasks": {
"lume": "deno run --unstable --allow-read=./ --allow-write=./ --allow-net=localhost https://lume.land/x/[email protected]/cli.ts",
"build": "deno task lume",
"serve": "deno task lume -s"
}
}
This conversation makes me think that a Permissions section in the documentation website would be really useful for users that want to restrict these permissions.
This conversation makes me think that a Permissions section in the documentation website would be really useful for users that want to restrict these permissions.
This sounds like a great idea! It will also be useful for raising awareness of permissions considerations among users who wouldn't otherwise be thinking about it.
I don't think I know enough about Deno's permissions API or Lume's requirements to write this myself, but I'd be very happy to help with writing this documentation if anyone feels like collaborating on it.
Permissions are explained here: https://lume.land/docs/advanced/permissions/ Closing this.