savi-lang / savi

A fast language for programmers who are passionate about their craft.
BSD 3-Clause "New" or "Revised" License
156 stars 12 forks source link

Establish pattern for stateless authority tokens #81

Open jemc opened 3 years ago

jemc commented 3 years ago

Just like Pony, we want to limit access to things like I/O based on authority tokens (in Pony, often referred to as object capabilities, as distinct from reference capabilities, which is an almost entirely orthogonal concept).


We can already do stateful authority tokens in Mare by making a :class or :struct with only a private constructor, or whose public constructor requires having some other authority token given as one of its arguments, which gives it a basis of authority. This is the same convention as Pony.

By contrast, a static-allocation stateless authority tokens is implemented in Pony as a primitive with a constructor that has those same properties described above, so that one can only obtain the primitive instance by legitimately calling that constructor.

However, in Mare, every :primitive (that is, its singleton instance) is freely available to all potential callers with no need to invoke a constructor, because Mare primitives have the non capability, which gives callers the ability to access the type-associated singleton for any (public) type in the program.


So in Mare we need another approach.

It's possible that we could get away with just using :struct, and ensuring that the CodeGen for struct still works okay when it's a zero-length struct. Possibly making it a special case that uses a global/static singleton instance in CodeGen when a struct is zero-length.

Alternatively, we could consider adding a new kind of type declarator called :authority, which could have some extra static analysis to help justify its existence which has the compiler statically verify for you that any type declared as an :authority has no public constructors which can be invoked without accepting an :authority in at least one argument. This could prevent mistakes which could compromise security of a library. However, it's not totally clear without thinking through it more that this would be desirable to require in every case - there may be valid use cases that do not fit this expectation.


Once we've decided on an approach, we can introduce a root of authority into the Env type like Pony has, then add it into the net package as well (e.g. creating a TCP connection).

Before we copy exactly the same approach, we should first investigate a pattern like the one proposed in this ticket.

jemc commented 2 years ago

It doesn't directly solve what was discussed in the above issue, but PR #222 added a mechanism for the specific case of single-instance "tickets", issued by a central root authority, but agnostic of type.

Using such a ticket is intended to be the building block that can help guarantee that no more than one instance of a give type exists in a program, and that it is held by no more than one actor.