In my introduction, I mentioned capability-based security, and I think it could be a great addition to Roc, especially since it doesn't start with the assumption of "ambient authority", meaning that things like opening files and doing network connections is implicitly always available.
If people want to read up on the subject, there are two very good introductory papers:
If you want to delve a bit deeper, there's Mark Miller's PhD thesis, Robust Composition: Towards a Unified Approach to Access Control and Concurrency Control. That one could of special interest to Roc because it describes the E programming language with its semantics that make concurrent programming more robust. Providing E's concurrency model as a Roc platform would be extremely nice, I think!
But without going that far, providing an API to do side-effects that doesn't rely on ambient authority and instead on capabilities, meaning that a function could only do those side-effects if passed the appropriate authority-giving value, would be a first great step. The Bytecode Alliance has started doing that for Rust with their cap-std.
I'd love to help!
I didn't mention it in the other thread but I read through those not too long after they were published.
Anything that's security interesting is entirely within the purview of the platform and there's nothing special about basic-cli over something you'd write yourself. The seahaven platform is my attempt on this topic. The platform provides the normal APIs which will simply not do stuff outside the configured boundary. The platform is using cap-std.
If anybody else is doing similar work, they haven't told us about it.
Karl said:
The seahaven platform is my attempt on this topic. The platform provides the normal APIs which will simply not do stuff outside the configured boundary. The platform is using
cap-std.
I'm surprised, with Roc's platform, I would expect that keeping the "old" API isn't needed, especially with Roc being still quite new.
I didn't find this seahaven project, could you link to it?
https://github.com/grayrest/seahaven
Strictly speaking, keeping the APIs isn't required but it makes migrating a project from basic-cli easier and I don't have a specific reason to change the APIs.
My intuition is usually that a paradigm change needs to be reflected in the way people think and work, but I know I've already been surprised a couple of times how far people can be transparently led into such a change…
Is it possible to build one application with several platforms? I would imagine that the best of both worlds would be a transparent wrapper like you did for legacy code, with the ability to give that wrapper explicit capabilities, and explicit capabilities as the default for new code… I don't know if that's possible.
Is it possible to build one application with several platforms?
Currently it is one application one platform, but if another platform has the exact same API for the functions you use, switching to it is trivial. There is also the pure app idea.
I'm very interested in general ideas around this. I've been definitely focussed elsewhere recently, but would love to see any ideas for hardening basic-cli or basic-webserver (or any platform I work on) using methods that fit naturally with Roc. I feel like there are lots of directions to go in any it's not yet clear which patterns will work the best.
I see at least a few different approaches to achieve this.
You could add cli flags that the host intercepts and controls e.g. --host-dirs ./ (or use some other method like adding a config file) and the app never sees those. The host could manage the capabilities under the hood completely transparently from the application, and simply return an error -- or do the pop-up box confirmation thing.
Shape or tailor the API's around capabilities like the Rust cap-std folks are doing
Luke Boswell said:
You could add cli flags that the host intercepts and controls e.g.
--host-dirs ./(or use some other method like adding a config file) and the app never sees those. The host could manage the capabilities under the hood completely transparently from the application, and simply return an error -- or do the pop-up box confirmation thing.
That appraoch leaves the possibility of confused deputy attacks, which we can bet will become more and more of a problem with AI. That legacy approach, though, is easier to write safely through explicit capabilities, so I wouldn't see the two as choices or competitors, more the "host managed" being a consumer of the capability API.
@Pierre Thierry would you propose any changes to basic-cli (for example) that move us towards the ideal? Or are you thinking more broadly in terms of language semantics, or maybe the roc cli itself?
Ok @Pierre Thierry and others here ... I've made an attempt at pulling this together into a concrete design proposal to change basic-cli.
https://gist.github.com/lukewilliamboswell/3ce9d0f209f2319ecfb5e91a4fae97c3
I think it looks worthwhile trying out. I'm interested to know what others think.
I'm also interested to know if anyone would like to work on this? ... making changes to basic-cli can be quite time consuming, and this isn't a minor change.
While I'm not an expert, I did bang on this for a few weeks for seahaven and I do not believe that this is providing any security. Holes that come to mind:
/etc/passwdI did the cap-std thing with patched bash+coreutils for a reason and I'm still reasonably sure something can get out. I just don't want to deal with Anthropic's security controls in attempting to break it.
I wonder if this reduces the attack surface area, and that means we might be able to find alternative methods to mitigate the remaining vulnerabilties?
Like if the only remaining vulnerability is just Cmd executing things ... then maybe it would be worth the investment to build some kind of sidecar that can flag suspicious commands? or we choose a different policy, like spawning commands requires a confirmation pop-up but nothing else does because those are lower risk.
Luke Boswell said:
Pierre Thierry would you propose any changes to basic-cli (for example) that move us towards the ideal? Or are you thinking more broadly in terms of language semantics, or maybe the roc cli itself?
I would love to see Roc have object-capability semantics, I don't know how much of a shift it would be from the current semantics… (FP can make it vastly less of a shift than coming from imperative programming, I suspect)
If Roc becomes an ocaps language, it opens up a lot of new possibilities, because it lays the foundations to close a whole new class of attacks, including supply-chain attacks.
Because it can be a big change, I would not have imagined pushing for that, though, just to have capability-secure platforms, in terms of the API to interact with the outside world.
Luke Boswell wrote:
Names are data. Constructing a
Path,Url, or command description grants no access. Operations combine those values with an appropriate capability.
Beware: one of the traps is when you interact with a non-capability system, like the filesystem or the Web.
The trap is to use input data to find capabilities you have somewhere. When you do that, you are vulnerable to confused deputy attacks. There's a horrible and an acceptable way to combine paths and capabilities:
.. entries or symlinksIt's crucial that a capability-based service expose every folder and file as a separate capability (I describe it in the attenuation section of my capability-URI RFC). I suspect you should also do that inside cap-cli. You get a Folder capability, you can list its entries, and each is itself a Folder or File capability (if they are different, of course), and in the simple version, the list doesn't contain .. and either doesn't contain symlinks or they are an inert capability, that signals an issue. (I guess a more advanced version might be able to safely use the capability of an upper-level to check that a symlink goes somewhere safe, not sure how easy it is to make that pattern completely safe)
@Karl and @Pierre Thierry I pushed an update to the proposal based on your changes.
The change for the file capabilities looks good. Why change some of the terminology from capability/delegate to grant/derivate?
I made another update -- hopefully it is clearer now with the terminology.
I'm definitely not an expert in this field, so using Agents to help do research and pull it together into a proposal.
This is a cool project :)
It could be its own platform to give us more freedom to experiment.
We could even leave out Cmd, it does not need to be a Swiss army knife, especially at the start.
I haven't followed this whole thread, but in general I think the following is a simple and effective way to do capabilities in platforms:
main! : Caps, Env, Args => {}Caps := { read_file : Caps.ReadFile, write_file : Caps.WriteFile }ReadFile and WriteFile are opaque so they can't be instantiated outside the platform (they are "unforgeable")read_file! : Caps.ReadFile, Path => ...Caps.ReadFile value, so you know which code pathways are doing which operationsI assume the project here is doing something similar (but I haven't looked at it)
I definitely don't think this should be basic-cli itself though - basic-cli's job is to be basic :smile:
if you want to get fancy with Cmd, you can do stuff like what AI agent harnesses are doing with sandboxing, although this works well on macOS, less well on Linux (you either need them to have bwrap installed or else you need to ship with all of bwrap), and basically doesn't work on Windows.
Luke Boswell said:
I'm definitely not an expert in this field, so using Agents to help do research and pull it together into a proposal.
A problem with AI agents is that they tend to go into too much detail.
Also, I think one of the best uses of such a document would be to build a common understanding. For that purpose, it's fine if it takes just a bit more time but goes through more brains that will later implement it or interact with it.
Richard Feldman said:
I definitely don't think this should be basic-cli itself though - basic-cli's job is to be basic :smile:
Also, this very discussion shows how designing and using a capability-based API goes against a lot of habits most devs have. It might be very educational if Roc were a capability-based language, but it would probably make it way less beginner-friendly.
Better to build a cap-cli.
@Pierre Thierry or anyone else interested, here is a PR where I spike out the changes for roc-ray to implement this capabilities based model completely
https://github.com/lukewilliamboswell/roc-ray/pull/201
It's currently restricted by default and then theres a flag ---host-caps-allow-all which enables everything.
Interested to know what people think about this ... is it a good direction? Any improvements etc?
I will probably need to sit on it a couple of days to explore it before I have an opinion or commit to this for roc-ray's next release etc
It looks good in the examples
Last updated: Sep 24 2026 at 15:59 UTC