upvote
I’m working on a capability system for a language that can compile to js[1], pardon the mess.

[1] https://march-lang.org/docs/capabilities/#the-problem-they-s...

reply
If I’ve understood this correctly, you’re using “capability” to mean something kind of like what Linux means: there is a collection of capability types, and each type is a singleton. (And at least the beginning of your page does not clarify whether the distinction between “needs IO” and “Cap(IO)”.)

This is genuinely useful in a language, but I suspect it’s also pretty weak. Serious capability systems have capabilities that are instances of types, and two instances are not necessarily the same. For example, the capability to read one file is not the capability to read another file. Singletons may still exist: the capability to read the system clock could reasonably be a singleton. (Or not: one may reasonably debate whether the cycle counter and the realtime clock are instances of the same type or not, and you’ll find that mainstream languages have what amount to very different answers to this sort of question.)

reply
These are types. Cap(Io) is a type, and used to grant IO, but you can narrow to reads or writes of single files/folders, network requests to single URLs, and so on. Needs is a declaration of the necessary Cap grant. The compiler will error on permissions that aren’t granted.

The Cap system is modeled on Eiffel and a series of papers I can link to later when I’m at my laptop.

It can audit dependencies for capability changes and can inspect binaries for undeclared IO. The run tool can analyze binaries and refuse to run a binary that tries to hide effects.

March’s capability system can be used to build binaries into a Linux sandbox so that you have multiple layers guarding prohibited actions.

reply
You probably shouldn't call it a "capability system" if you don't mean ocaps, because despite your best intentions, many people who are familiar with ocap systems will assume you are engaged in some sort of fraud.
reply
It literally is a capability system it just isn’t OCAP because it’s a purely functional language and there are no objects. You declare capabilities you need and grant them where they’re allowed. It differs in happening at compile time only and not being threaded through every method which I think is ergonomically awful.

It’s heavily inspired by Eiffel and Pony. It is also coincidentally a lot like Bluefin for Haskell[1], and in that spirit I use them beyond security. For example behavioral promises like no_alloc and no_panic.

I’ve shown to some compiler researchers who understood it to be a capability system. In your mind what makes it not a capability system?

[1] https://h2.jaguarpaw.co.uk/posts/bluefin-capability-system/

reply
I have been exploring something on the lines of capsicum for my language+runtime and you want to balance usability and security. Too much friction and people WILL use --all like I do with Deno.

My current thinking is to freeze all caps on startup. pid-0 within the runtime has the max caps the application will ever have and it can parcel out subsets to other processes that need it.

This can show up on the ux side as a single permission request listing all the caps the application claims it needs with a default negative response.

reply
This is what I do by setting caps at compile time, they aren’t a runtime feature. You either compile out code without a grant or it errors.
reply
How will you allow permissions for a `ls` style tool? I want to be able to do `ls /etc`.
reply
The tool parses its command line, claims the capabilities it needs, drops everything else, then runs.

Or the language it’s written in allows writing a function that takes a recursive enumerate capability on a directory plus a write capability to stdout.

A while back I sent a brain dump email to LKML about “path capabilities”. Maybe I’ll try to implement it.

reply
Probably on a directory read basis. I’d need to give it more thought.

Thanks for the thoughtful question!

reply
Really like this and think we need something like this in every major language, especially to address supply chain attack stuff.

A couple of thoughts:

- would really like to have the option to make things more granular… things like “which dns/tls will this have access to?”, “which file/folder?” - probably would be helpful to have permissions to be kinda two sided, like “this function needs tls”, and then on the import side “allow this function tls access to this host in particular”.

reply
Thanks! It can be file and url level granular, there’s a capabilities page that mentions that[1]. Caps and needs are the two sides. A module function needs File.write, and you can grant a narrower cap to a single folder or file.

[1] https://march-lang.org/docs/capabilities/#choosing-the-right...

reply
[dead]
reply