Elixir and Object Capabilities

Capability-based Security as a security model exists for a very long time, but recently there’s a lot of research for using Object Capabilities in distributed (actor-based) programming.

I am referring here to the work of Christine Lemmer-Webber (co-author of the Fediverse’s W3C ActivityPub specification) started in the Spritely Project and now continued with Randy Farmer in Spritely Institute.

Based on the Principle of Least Authority (PoLA) and applied to regular programming this research will explore new paradigms of distributed programming. A lot of work still needs to be done, but Spritely Institute envision emergence of an open-standards based Object Capabilities Network (OCapN):

The following whitepaper gives an overview of what Spritely Institute is working on: The Heart of Spritely: Distributed Objects and Capability Security and working prototypes exist implemented in Racket and Guile (a Scheme dialect).

How is this relevant?

I am creating this topic first of all to alert the Elixir community: This stuff is major!
Don’t take me on my word. I encourage anyone to check things out to find that out for yourself.

Also Erlang/Elixir seems a bit of a ‘dead zone’ wrt Object Capabilities implementations AFAICS. I wonder if anyone has knowledge on any projects implementing it. The Cap’n Proto protocol (used by Sandstorm) has an Erlang implementation, but it is unmaintained.

Finally… a lot of this stuff may seem abstract. Scott Wlaschin has a fabulous page on “Designing with Capabilities” equating good design == good security and “intention revealing interfaces”. Watch the video at:

(PS. I am only a beginner Elixir programmer myself. I really hope to see experts entering this field)

4 Likes

Here’s a recent blog post with some more impressions on the Spritely’s work and potential impact:

A Conceptual Introduction to Spritely Goblins

Goblins articulates a security paradigm of object capabilities which I find to be an apt name. In this paradigm, you construct objects that have capabilities, which are functions. If someone in the network can access a function in an object on your machine, it is only because you gave them permission. If a function runs, it is because it is authorized to do so.

That is the model Goblins hands down, not one of peers or users or identities, but of capabilities. You write object capabilities as stateless functions, and can call upon those capabilities that you can access. Applications can gather such capability-functions to create complex communal systems built upon consent.

And further on:

Are you beginning to see the possibilities? Not merely the shape of the applications one might write with Goblins, but the consequences of its paradigm: the transformed relations that emerge between programs, or the blurred distinctions of locality these abstractions confer? A function might be on your machine, or on another; it might make no network calls or a recursive mess of them, but it never does anything without having obtained the appropriate permissions – permissions that are as easy to grant as URLs are to share, or as parameters are to pass.

If you’re still reading, I suspect you’re thinking one of two things: “This doesn’t make any sense,” which I get a lot, or, “What’s the catch?” The catch is the former. Goblins synthesizes an enormous body of research, and it is only the beginning of an expansive vision for a new distributed web. The whitepaper, The Heart of Spritely: Distributed Objects and Capability Security, floors me with its rammifications. After reading it, I am left with a burning thought: this can change everything, so much so that I struggle to articulate the path a mind must walk from this world to that.

1 Like

There was a lot of work on this around the turn of the century :slight_smile:

3 Likes

While a topic I need to take more time to explore, object capabilities sure are something we’re very interested to use in Bonfire (an Elixir toolkit for building federated/ActivityPub apps). Would love to see more activity in this space!

2 Likes

Wow, that is a bunch of cool papers @jhogberg thank you! I’ll be sure to pass them on to the folks in the #spritely IRC channel. I have formatted them somewhat more readable:

Really excited about Bonfire @mayel the social foundation you are building is looking very promising and can’t wait for some of the modules you have planned to stack on top. Fediverse can really do with a good decentralized collaborated platform :smiley: :+1:

1 Like

There’s another video I forgot to post here that gives an overview and introduction to the technology:

Looking at the meeting notes for OCapN I’d like to mention that Diana Thayer ( @garbados ) of CouchDB erlang project was also present. From their intro:

I’m Diana, am a CouchDB maintainer, interested in distributed protocols, IPFS, etc, very interested in spritely, goblins, ocapn, because what I believe they can provide paradigmatically to distributed systems programming.

1 Like

Happy New Year, fine Elixir folks :fireworks:

Object Capabilities are gaining more traction. This very comprehensive article introduces Austral that has native support and offers intuitive way to write “capability-secure code”:

Though not related to Erlang/Elixir (language is written in OCaml) the Capability-based Security section gives a very clear explanation of the advantages of using capabilities in your codebase. (Apart from that Austral has some very intriguing Design Goals).

1 Like

A minor gripe: that’s the same thing everybody kept saying the last time this became a popular research topic twenty years ago. It’s probably the same thing everybody on the iAPX 432 team said to each other 40+ years ago - I wasn’t around for that one. There are interesting ideas in the space, but prematurely declaring them the Next Big Thing helps nobody.


IMO the biggest challenge with bringing something like capabilities to Erlang-land would be the mismatched execution model: capabilities assume that code has no access by default but the BEAM explicitly rejects even isolating nodes from each other, nevermind processes on a single node. There’s been some discussion about filtering/firewalling but it’s a tough problem, especially to retrofit onto an existing runtime.


Re: Austral specifically, a couple things jumped out reading through the examples + issues:

  • “no exceptions” is only technically true, as there are no user-observable exceptions and no mechanism for cleaning user-defined things up when something goes wrong. There’s still PLENTY of places that call abort and hard-exit from the OS process though, and even just writing a + b could lead to a runtime abort if the numbers are large…

  • the first place that users might reasonably expect to encounter capabilities is when they want to print to the terminal, but Austral works around that because it would be too verbose

  • another place to encounter capabilities might be when directly manipulating memory (for instance, type-punning with memmove) but that’s also side-stepped with a specific “are you importing the Memory module?” check

  • borrowing is powerful, but also brings plenty of edge-cases. For instance, in the example “capability-based file API”, what happens if a Path value is created using the borrowed result of Get_Filesystem but the Path is still in-scope after Release_Filesystem has been called? Should a call to Read_File succeed, or crash? Can/should the compiler catch this? It may not even be an error :thinking: - for instance, I could imagine a capabilities API where best-practice was to derive smaller capabilities at the beginning of a program and then discard the root capability, similar to how setuid programs “drop root” as soon as it’s no longer needed.

Based on the examples + the tutorial around capability-based security, my vibe is that Austral is a language where there could be interesting design possibilities; it seems like a reasonable foundation. But there’s a LOT of capital-H Hard design work still to come to make a usable API that avoids things like “pass your RootCapability to this random code, trust me bro” actually happen.

3 Likes

Thank you for your elaborate response, @al2o3cr.

Yes, that can be said. The Spritely project was explicitly inspired by CapTP, the Capability Transport Protocol, a work started by Mark S. Miller about 25 years ago. And bringing these concepts up to par with modern technologies of today. Mark Miller is also an advisor to the project and Spritely Institute.

I’ve mentioned this in the #spritely IRC channel. This topic goes over my head both Spritely (as well as Elixir language) levels, where research is at academic computer science levels. But apart from having a language-level support for capabilities, there’s many other levels where varying degrees of support might be available. This is described in Section 5 of the Spritely paper, elaborating the many layers of a trusted computing base.

I forwarded this feedback on an Austral Github issue I created before, and the maintainer has just given their response.