Show HN: Osgood – A secure, fast, and simple JavaScript server platform
github.com
github.com
Today we build web applications with general purpose language runtimes. Osgood is an experiment that asks the question: "What if we built a runtime specifically for web apps? What kind of benefits can we get from being at a higher level of abstraction?"
Since the Osgood runtime has intimate knowledge of the routing table we get the ability to isolate controllers for free (we refer to these as Workers). The I/O performed by the application, as well as policy enforcement, happens in Rust-land. Each worker has its own set of permissions.
Consider the situation where Controller A has permission to send a message to evil.ru, and Controller B has access to user credentials. Within a properly configured Osgood application this means it's not possible to transmit user credentials to evil.ru.
(Incidentally our main product transparently provides similar isolation for Node.js apps. The architecture ends up looking quite different because Node.js wasn't created with this concept in mind)
Edit: well one difference is that this isn't TypeScript. This is only the subset that is JavaScript.
--allow-write
--allow-net
--allow-env
--allow-run
Today these policies are all-or-nothing and they are global to the entire Deno process. Consider and application which _only_ needs to make a GET request to a single GitHub API endpoint. This application will then use the `--allow-net` flag and will be able to communicate with arbitrary sites like evil.ru.However, with Osgood, the permissions are much more granular. One can specify a policy to only get access to _exactly_ what is needed. The permissions are also granular enough to only apply to a subset of the overall application:
app.route('GET', '/gh/:username', 'gh.js', policy => {
policy.outboundHttp.allowGet('https://api.github.com/users/*/gists');
});
We will add further policies where it makes sense, such as with filesystem access. However, Osgood doesn't aim to be a _general_ platform for running code, so we will likely expose filesystem access in a manner akin to this:https://thomashunter.name/presentations/introducing-osgood/#...
Maybe you guys should work together with deno team on exchanging these ideas? Anyway, great work!
No, Deno supports whitelists for net and file access:
Isn’t this also the PHP, Allaire ColdFusion, and ASP/ASP.net experiment, each making a very different set of tradeoffs? Or successors such as OpenRESTY with built in LuaJIT?
It’s true a lot of “we” think web apps are built in general purpose runtimes, but plenty who think that’s lower ROI, so there’s a body of prior art here.
Excited to see experiments continuing this direction. Also consider looking back over past 25 years to when that question was first experimented with — which concepts stuck the landing, which concepts were left behind, and why.
One thing that would make this even more interesting to me is to see how close you could make the interface for each route handler to amazon lambda/api gateway. I would love to be able develop something locally using osgood, and then deploy to either hosted osgood or aws lambda/api gateway with minimal fuss, potentially even with a single config file that maps routes/permissions.
Is this the future goal for the project or is it more of a PoC?
However, as this is a JS server runtime and Node is the reigning champ, it would be great to get a section in the README early on about Node compatibility. How much is it going to hurt to move my Node services over?
If there's no package management capability, then do people have to manage dependencies themselves?
Or if there is one, how is it more secure/trust-worthy than npm?
Since Osgood requires I/O to be whitelisted this removes multiple categories of attacks which would affect Node.js apps loading a malicious module.
To clarify a few things:
1. Any tool that reduces the privileges of your application code, such as Osgood or Deno, is doing so because application code cannot necessarily be trusted, since you're pulling in external dependencies that can have vulnerabilities or malicious code, and even one's own code may have unknown vulnerabilities that may cause unexpected IO behaviour to happen.
2. The policies you can set with Osgood are defined in a JavaScript file that is run separately from your application code (i.e. the worker files), and it only runs once to build up the policy data structures in native code. This V8 Isolate is then discarded. This means that application code cannot modify its own policies.
Same problem, though.