Blog

Development update, Feb 2019

This is our first development update since we started, in July 2013. For most of that period we've been working on Peergos for free in our spare time. Everything we do is open source and pro bono - If you would like to support our development then please make a recurring donation of less than 100 euros per week or a larger one off donation.

The browser's capabilities have come a long way since we started. Things that we can do now were not possible 5 years ago. The Inter-Planetary File system (IPFS) has come a long way in solving many of the peer-to-peer networking problems and laying a solid structural foundation to build on. That's why very early on after IPFS started we switched from our own networking and distributed hash table to IPFS, allowing us to focus on our core principles of privacy and security.

Thanks to some very generous support from Protocol Labs (the initial creators of IPFS) we have been able to accelerate development recently. We've released a bunch of cool new features and are much closer to our public alpha. Let's go through a few of the big ones. You can see the rest in more detail in our book.

Decentralization

The first new feature is proper decentralization. Now you can self host your own Peergos instance and transparently interact with users on other servers, whilst being independent of the domain name system (DNS) and the SSL certificate authorities (central points of failure outside our control). You can even log in to your Peergos account through someone else's Peergos server. The Peergos interface can actually be entirely self hosted from within IPFS itself (i.e. you can log in through a standard ipfs instance rather than a Peergos instance)! This was all achieved with IPFS p2p streams. p2p streams are a new feature in IPFS which let you create a tcp socket between any two IPFS instances. This stream is end-to-end encrypted with secio. Secio is basically TLS with a different handshake because the end points are not location addressed - instead the addresses are the hash of each node's public key. Like all other IPFS connections, this stream will tunnel through NATs and firewalls transparently.

We implemented a new http endpoint on the IPFS gateway which allows you to proxy a http request to any target IPFS instance (who is listening) using these p2p streams.

This new endpoint is accessed through the gateway (after enabling it - it's an experimental feature for now) at:

http://locahost:8080/p2p/$ipfs-node-id/http/$path

For each such request, IPFS will open a p2p stream to $ipfs-node-id and proxy the request to it with a path of $path. Note that the $ipfs-node-id is the hash of the IPFS node's public key. How this works is illustrated below. The beauty of this http endpoint is you don't need to manually open p2p streams for every different endpointdestination, IPFS handles that for you automatically.

Proxying requests

Using this key ingredient, we can separate out each user's data into their own server. Most of the data is already in IPFS, but a user's storage server is responsible for pinning it, and for storing the mutable pointers (our equivalent of IPNS), and pending follow requests. This means the only centralized component is the pki, which stores mappings from username to public identity key, and public storage server key. The job of the pki server is to ensure unique usernames and thus it is logically centralized, but we take various efforts to mitigate the effect of this. For example the pki is mirrored on every Peergos server. This has threefold benefits: first it allows users to do private lookups for friends' public keys without announcing to the network who they are looking up; second, it makes the whole system much more scalable - you only need to contact the real pki when you are signing up, or changing your identity or storage server; and third it improves resiliency, if the pki server were to permanently be taken down the network could move to a new one without any loss of data. The pki data itself is stored in IPFS as an append only data structure in a compressed hash array mapped trie (champ).

Granting write access

We've had the ability to grant read access for years, but only this year have we finally implemented granting write access to other users. Every write is signed by a signing keypair. Initially you only have one signing keypair for your entire filestystem, which means that to only grant write access to a subtree, it needs to be moved to a new signing keypair. To explain how this works we're going to take a few steps back. Every directory or 5 MiB section (chunk) of a file requires a unique capability to access it consisting of:

(owner, signer, label, read base key, write base key)

Here the owner and signer are (hashes of) public signing keys, label is a random 32 byte label, and the read and write base keys are symmetric keys. If someone has the first 4, which amount to a location and a key, then they can read the file or folder that it points to. If they also have the write base key, then they can also make modifications.

From a network visible point of view, every signing key pair points to a champ root (by signing the root). This champ is just a look up from the label to the value, which is a cryptree node. You can read more about cryptree in our book, or the original paper describing it. If the thing pointed to is a file, then the cryptree node itself will have merkle links to the encrypted fragments of the chunk. Remember that merkle links are just a hash that points to another ipfs object. This is illustrated below.

Champ

When you grant write access to a file or folder then you are just revealing the write base key to them. This enables them to extract the private signing key and thus make modifications. Initially your entire filesystem is under the same signing key pair. This means were we to naively grant write access by sharing this key then the recipient could delete (though not read) all your files. To avoid this we first move the file or directory to which we want to grant write access to a new signing key pair. This allows us to only grant the friend write access to the particular part of our filesystem we want to share. Voila!

If you grant write access to a folder, then that means that the recipient can upload new files or make new directories inside that folder, or delete all the contents. Granting write access to an individual file means the recipient can only modify that file.

Future work

We have lots of work in the pipeline, so stay tuned! These include an in Peergos text editor, for a google docs like experience with collaborative editing, a secure messaging system inside Peergos and a sandbox and API for third-party applications inside Peergos.

Back to Top