This week we look at the question of authority. Who can do what, and what credentials do they require to do so? The topic comes about as we are looking to simplify the code, removing message filtering patterns that we’re no longer using and ensuring the fundamentals are logical and easily understood.
@anselme has implemented a gossip layer to handle missed instances when the new DKG system fails to terminate and is now looking at cases where we have concurrent split DKGs that terminate together. DKG seems pretty stable otherwise though.
@qi.ma has been looking for potential bugs in
FilesContainers, as the comnets highlighted some suspect version clashes recently.
We’ve also been digging into some client connection issues from nodes, which appear to drop some responses. And removing unnecessary serialisation steps around
OperationId, lightening the load on nodes further.
If you think of authority in terms of power, you might think elders, the wily old greybeards, would have the most authority. After all, they are the ones that control everything that goes on in their section, including having the power of life and death of other nodes. You’d be wrong. When it comes to making changes on the network, individual nodes have no individual authority whatsoever. Adults have no say, whereas elders only have authority as a collective, by means of a threshold vote.
In fact, the most powerful actor is the client - the customer is king if you like. That’s because the client can do things like editing mutable data (containers) that it owns and signing the reissue of a DBC. The nodes are really just messengers, passing information about operations and judgements to and fro, and mostly doing what they’re told.
Why does this matter? Well, it matters because we want clear dividing lines over who can do what. As far as possible we want authority to be implicit in data types and operations and for that to be controlled by cryptography, not complex hierarchies, and we want the simplest possible authorisation structures.
Permissions are built into the data types.
When it comes to mutation, chunks are impervious to authority. There’s no authority on the planet that will let you change the data. Therefore we don’t need to worry about designing an authorisation logic for them.
However, to store a chunk we do need authority, in this case it’s provided by the Section in which it is to be stored and once granted this authority applies forever.
SectionAuth is a valid section key plus a signature.
Storing containers requires
SectionAuth, while mutating them requires
ClientAuth - only the owner should be able to change their data. So, implicit in this data type is that it requires a client signature before it can be changed.
ClientAuth is a valid client signature.
The other type of mutable data is the SectionTree, which is a tree branching out from Genesis. Here the situation is a little different as effectively there are multiple owners (all the sections), but each section can only add a leaf to its particular branch with its
DBCs are a little more complex in that they require a client to authorise a reissue (
ClientAuth) and a section to sign it off (
SectionAuth), but again until it has those two bits of authority attached, a DBC is effectively useless.
The important thing here is that for data operations, nodes are mere message carriers, and the message is independent of the carrier. We don’t care where the message comes from, and we don’t care who signed it. We only care that the data element carries the right sort of signature (client or section) plus a key.
In the simplest example a chunk of data with a valid section signature key attached can fly around the universe, and when it returns the network must accept it, because a section signature on data means it exists forever.
In REST API terms data operations look like this:
GET operations require no authorisation whatsoever.
PUT operations require
SectionAuth for storage and a combination of
SectionAuth for payment.
POST operations require
ClientAuth to mutate containers
SectionAuth to mutate the individual leaves of the SectionDAG
Token transfers require a combination of
Changes to the makeup of a section in terms of its elders and adults, splits, etc, all require
SectionAuth. But while individual nodes don’t have any authority in these processes, the elders at least are not merely passive message carriers as they are with data. For example, if an elder notices a node behaving dysfunctionally it can force a vote on whether it should be penalised.
For this to work, nodes need to be identifiable in certain instances, meaning they must sign messages with their public keys. So if a client sends a request for a chunk and that chunk arrives late or there is some corruption, the signature is irrefutable cryptographic evidence against that node and the client can inform the elders that it’s a bad 'un.
And for DKG it’s vital that the messages sent between elders with their vote shares are authorised. The authority of the message is that of the sender and checked against their signature on the message. This is called
By focusing on authority and removing unnecessary checks, particularly in messages, we are simplifying operations as far as possible and relying on cryptography and data types to do the hard work for us. We still have some unnecessary message signing hanging over from previous iterations of the network, and all of these have a performance cost as well as creating confusion. A clean, simple design is an efficient design.
Feel free to reply below with links to translations of this dev update and moderators will add them here:
As an open source project, we’re always looking for feedback, comments and community contributions - so don’t be shy, join in and let’s create the Safe Network together!