-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Discussion: how to distribute native plugins gracefully #4222
Comments
I do like the idea of the manifest, because it is very clear what is happening - there is very little magical resolution going on there. I think though that just being able to (dynamically) import The manifest has the upside that it can be statically analyzed and can be displayed in I am personally for the (dynamic) import of Ref #3448 |
It's not that it's not getting enough attention - @afinch7 has been working quite hard on it. It's more that I am purposely slowing down plugin API until we have some refactoring complete in core. The form for the plugin system as it is now is incomplete. Before addressing (valid) ergonomic issues as you outline above, we need to first address the issues of resource table in plugins and figuring out how "op crates" work. |
I'm keen to see where this goes. I'm currently developing a wrapper to allow Deno programs to use rusqlite. I don't like the idea of making It sort of begs the question: how are people deploying Deno code to production? If it's e.g. via Docker container than this is probably a moot point, as the correct plugin can be baked into the image. What's the deployment case that's being solved for with an idea like importing a I'm not sure if this is a separate discussion, but the security model seems to mean that
|
We haven't discussed it - but in general I would shy away from such magic...
I'd rather make this explicit by requiring |
Ref #3378, the argument against is the implications of being able to whitelist plugins. |
With regards to security, it might also make sense to consider using something like WASI as the primary way to distribute 'native'-like modules. This has benefits with regards to security and portability. Although it might come with a performance penalty in some cases. (Although one might argue that in these cases using a JS run-time is not necessarily the best choice for the problem anyways). |
I would consider plugin as an extension of Deno itself (rather than another module to be import), and as such, should have the same privilege as Deno. Decision the use plugin should be end-users' responsibility, not library makers'. Plugins should have their own I have no idea what plugin should do in the mind of everyone here. But I can imagine a database plugin that allow JavaScript code to access SQL tables, this plugin would have its own permission flag correlate to database permissions (such as |
@KSXGitHub We can't enforce permissions for native code. Once you load a .so file, all security promises are gone. |
@ry Indeed, that's why I said
What I meant is that plugins should have their own security flags the same way Deno has. |
@KSXGitHub but what use are security flags if the code is untrusted? |
@ry Security flags not because I don't trust the plugin, but because I don't trust third party code using said plugin. Just like I trust Deno, but not the random code I wish Deno to execute. |
@KSXGitHub you're saying untrusted code could use a trusted plugin if the plugin promised to obey certain security features? That does make a lot of sense. For my use-case, I am trusting my sqlite plugin to only be able to perform operations on Sqlite databases - and I could even lock that down to only in-memory databases. So I'd be fine passing that plugin to any random piece of code from the net, knowing it couldn't use it to do anything other than create in-memory databases. I think that's an important thing to know, but it is still meaningless in the context of Deno's permissions API. Unless we had per-module permissions where I could write trusted code that opened a trusted plugin, then passed the trusted plugin instance to untrusted code. EDIT: or, if the plugin API was not a runtime thing? Like if I could say "run Deno with this plugin with this configuration" (e.g. "the sqlite plugin with permission to open databases in-memory only"), then at runtime that plugin is simply available to all (untrusted) code. Here's a hypothetical: deno --plugin ./libsqlite.so:sqlite --plugin-config '{"sqlite": {"only_memory": true}}' untrusted.js
// Untrusted code cannot open an arbitrary .so file, only the plugins I've loaded on the CLI
let sqlite = Deno.openPlugin("sqlite");
// fake plugin API because I can't remember how to use it off the top of my head
sqlite.ops.openConnection({
"path": ":memory:"
});
// this throws an error because of the way the sqlite plugin is configured:
sqlite.ops.openConnection({
"path": "../haxors.db"
}); This seems like it would work well for well-known, trusted plugins, and allow end-users to maintain a tighter security profile. It'd also be great if plugins could hook into Deno's security configuration so that e.g. my Sqlite plugin could check the program's I'm not sure if this gives too much of a false sense of security :/... it is distributing increased trust to the ecosystem rather than Deno core itself. Using the |
- Removes unnecessary RwLock and Rc around the op registry table - Preparation to move resource_table to deno_core::Isolate. - Towards denoland#3453, denoland#4222
Maybe a dumb question @manyuanrong, but why are you building a mondodb driver as a native plugin instead of in TypeScript / JavaScript so that it would just work cross platform without worrying about native code portability? |
- Removes unnecessary RwLock and Rc around the op registry table - Preparation to move resource_table to deno_core::Isolate. - Towards denoland#3453, denoland#4222
Tell me, why bother with distributing dynamic libraries? They are present in large numbers in any distributions and operating systems. All you need to interact with them is the built-in FFI and a text description of the library functions on the Deno side |
Not bother with distributing dynamic libraries, just bother with distributing native Deno plugins like in this discussion (source: https://deno.land/x/mongo). Use more native plugins means:
My opinions:
BTW:
Compare with FFI solution, LLVM bitcode plugins can:
@afinch7 any ideas? After a few tests, llvm ORC JIT engine seems too big and heavy for Deno (about ≥20MB on macOS), not profitable. And llvm bitcode is not portable cross platforms (macOS, linux and Windows), seems just portable cross arch (x86_64, arm, arm64). Maybe just a |
I think the best would be to make Current behavior of Right now there is some unofficial .deno_plugins directory provided by the plugin_prepare, and if the plugin authors start to assume that directory is the canonical location, then changing to centrally cached location will be difficult. Edit Centrally located native library cache, out of sight, is the best user experience. Right now if you want to run e.g. sass compilation quickly in some directory you get also directory of |
I'm confused about the safety arguments people are using against native plugins.. (especially related to these arguments that people should 'just use WebAssembly').. why should I trust the authors of Deno any more or less than the authors of a native plugin I may choose to use with Deno? Surely using native plugins is an opt-in decision that I'm able to make and the security implications of that are on me? |
I haven't mentioned it here yet -- this issue would be solved by https://github.com/tc39/proposal-asset-references. It's the general problem of "consuming non-code resources which are relative to a remote dependency". |
@pomke I agree with you that ultimately a user of Deno has to understand the risks and make decisions themselves. But Deno can still make design decisions that are better or worse given that basic fact. For example, the situation when Deno launched was "if you load a plugin, it can do anything and you can't control it". This means that your security options are binary: either don't enable plugins and don't get the benefits, or enable plugins and all the security risks that may entail. There are a variety of ways that Deno could provide more options to its users to get some security, even if Deno obviously can't guarantee complete security. That was the spirit of my suggestion above. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Should probably not be closed? |
I'd say dupe of #3448. |
IMO this falls under distribution of non-code assets in general. So #5987, https://github.com/tc39/proposal-asset-references, etc. #3448 seems to be about |
Instead of tc39/proposal-asset-reference wouldn't proposal-import-assertions which is already stage 3 provide a possible path to a solution? |
I think the native plugin is very important and urgent for deno, but it doesn't seem to pay much attention.
I'm using rust to develop a mongodb driver for deno, but I have a headache about how to distribute my binaries. Because native plugins cannot run well across platforms, they need to be compiled into binary targets for different platforms. These files are very large. We need to come up with some mechanism to distribute these files gracefully.
So I wrote https://github.com/manyuanrong/deno-plugin-prepare to simplify the work, but I don't want to go in this direction, that seems to lead back to
package.json
I think the following aspects need to be considered:
Avoid loading binary versions of all platforms, they should be selectively loaded according to the operating environment.
Considering the cost of regular developers, all native plugin dependencies of an application should have some mechanism for preloading, which facilitates application deployment and speeds up running time. Similar to
deno fetch
, achieve the effect ofnpm install
.Because the native plugin is not a first-class citizen, it cannot be loaded directly through import like
ts/js/json
. Currently, it can only be downloaded through thefetch api
at runtime. These binary files are very large. Downloading them takes a lot of time This is difficult to use for production.npm
tool solves these problems in engineering practice, but this is not consistent with deno's idea.For all these reasons, I think the better way is to make the native plugin a first-class citizen.
Develop a manifest file format, such as
.dnm
(deno native manifest), mimeapplication/x-deno-native-manifest
Structure is similar:
Use
import
directly in the programPrefetching with
deno fetch
The text was updated successfully, but these errors were encountered: