jFriedensreich
3 days ago
I was a fan of deno because at least they tried, its not that there was an alternative runtime that tries to do permissions right or that there is an operating system tool that allows async(!) permissions with user interaction. We really need a simple to use "productised" but true open source solution that allows halting any software and evaluating policies for run, fs and network etc and can reason on process and context level.
schlarpc
2 days ago
I built exactly this at work over the past few months, sadly not open source though. It uses Cedar policies for process lifecycle, network activity (at basically every layer), filesystem access, credential usage through brokers, and so on, with context injected into every evaluation, and cgroup freezer on Linux for stop-and-escalate-to-user. Maybe I should use this as evidence of demand for us to open source it...
ch4s3
3 days ago
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...
amluto
3 days ago
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.)
ch4s3
3 days ago
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.
kragen
3 days ago
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.
ch4s3
3 days ago
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/
kragen
2 days ago
It really sounds like you're describing an ambient-authority system, which separates designation from authority. Ocap systems don't separate designation from authority, and purely functional languages do have objects in the sense of "object" that the "o" in "ocap" stands for.
ch4s3
2 days ago
You’re splitting a weird hair here, every single ocap language I’m aware of has objects in the sense of OOP. And o ap isn’t the only kind of capability system, Pony for example has two separate systems. March works a lot like Austral and Roc. Modules and functions need capacities which can be granted at an app root, a program can have multiple app roots to segregate authority on a machine or a cluster.
Again I said capability system and never claimed ocap.
kragen
2 days ago
You are rapidly burning through the presumption of good faith. This is not a hairsplitting distinction, but a completely different approach to computer security, and claiming that the difference is insignificant is strongly suggestive of a grift. CHERI's ocaps are largely capabilities to assembly-language memory regions, and Jonathan Rees's seminal ocap work was at the Scheme language level, which also doesn't have OO. Pony's ocaps are also not generally to OO objects.
ch4s3
2 days ago
I honestly don't understand the confusion here. I never claimed it was an ocap system, I said it was inspired by Pony and Eiffel and similar to Austral's ambient authority which is often referred to as having a capability system. Though March allows caps to be narrowed at call sites. I also showed the implementation to a PLT and security researcher who called it a nice approach to capabilities. So someone who has published on the topic was not confused.
Accusing me of grifting is uncharitable, and unnecessary. I simply don't understand this level of incivility over the term capability.
kragen
a day ago
Imagine if someone was selling an aluminum bicycle lock and claiming that it was hardened steel, and when told that actually aluminum was not the same material as hardened steel, accused the poor guy of "splitting a weird hair", which to me is the point where incivility was introduced, by you, in order to attempt to discredit the information I was offering you.
ch4s3
a day ago
I’m not selling anything. I sad at the top “I’m working on”. You aren’t offering me any information I don’t know. I’ve read the 1966 paper that introduced the term.
Look at how you’re behaving in public and ask yourself if this is the kind of person you want to be.
amluto
3 days ago
You lost me. If I want to grant read to /etc/passwd, how do I do it without threading it through every call? Is it an implicit parameter system? Do you literally write “/etc/passwd” in the code?
ch4s3
2 days ago
Authority grants are ambient at an and the compiler makes distinctions at the module level, though you can annotate a function. It’s most like a language called Austral.
sieve
3 days ago
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.
ch4s3
3 days ago
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.
sieve
3 days ago
How will you allow permissions for a `ls` style tool? I want to be able to do `ls /etc`.
amluto
3 days ago
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.
sieve
3 days ago
My current design idea lets the runtime collect all the requests till the application locks its set of demands. This entire set is presented to the user who can then approve/reject/approve-always
The runtime maintains state in the config directory so that approve-always works for `(hash(ls), dir_read(/etc))` without producing that question during the next `ls /etc`
ch4s3
3 days ago
Probably on a directory read basis. I’d need to give it more thought.
Thanks for the thoughtful question!
thegagne
3 days ago
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”.
ch4s3
3 days ago
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...
thegagne
3 days ago
Cool!
I did look for “url” on that page and came up empty, then read it with my own eyes and didn’t see it, and even passed it to Claude and it also couldn’t find an answer for my query:
> Take a look at and see if there’s a way to limit fetching from a particular hostname over https. https://march-lang.org/docs/capabilities
What I would like to be able to do is to say “only let this imported function talk to https://example.com/*”, and deny any tcp connections other than the dns lookup and https calls to that domain.
ch4s3
2 days ago
I have a draft PR open to enable something like
mod A do
needs IO.NetConnect("example.com")
endmod B do
needs IO.NetConnect("foo.com", no_redirects)
endWhere A can call "example.com" but not "foo.com".
ch4s3
2 days ago
Sorry the docs aren’t 100% there yet, the language is still pre-1.0. You can do that but it’s not as well supported as file paths, but will be by 1.0.
szundi
3 days ago
[dead]