How to build "magic wormhole"-style authorization?

Hey, dear libp2p community!

A friend and I are working on an open-source tool for real-time collaborative text editing called Ethersync. We’re considering to use libp2p as our network layer, to benefit from its many built-in features like transport encryption, being able to connect two peers directly, and discovery.

Our main question currently: We will need to add some form of authorization. We’re thinking of a magic wormhole-style authorization, where people who want to collaborate all can specify the same passphrase (randomly picked from English words, like “tired-yellow-butterfly”.

How would you approach building a system like that? We had a brief look at libp2p’s rendezvous protocol and it’s “namespaces”, but it seems that it freely shares available namespaces with anyone who asks. Do you see built-in alternatives? Are the pub/sub protocols designed with security considerations in mind, or are they also “open by default”?

Do you think libp2p is a suitable library for our use case? (We don’t want big peer-to-peer swarms, but rather allow small groups of people to connect.) We’re doing the project in Rust.

Thanks!

Hi,

I have only one year of experience with libp2p, but I believe you can use libp2p as your core without any issues. One question I have is about the authorization you mentioned. In this case, you could have the following approaches:

1 - The person who creates the documet can add new peers to collaborate, allowing changes only from trusted peers. To update the document, you can implement a voting rule among the trusted peers so that only validated changes are allowed.

2 - Trusted peers can invite other peers, following the same validations as in the first option.

3 - All peers in the network can make changes to the document.

Options 1 and 2 would be more centralized, while option 3 would be more decentralized. However, in all cases, you need to implement some algorithm to choose who can validate the document.

Based on the information you provided, I believe this covers it.

1 Like

Ah, thanks – what we’re imagining sounds a bit like #2! But if possible, we’d like to avoid dealing with Peer IDs.

From a users’ perspective, we’d like it if peers can access a document if they know a common, secret passphrase. So that the knowledge of the “tired-yellow-butterfly” is enough to join the document.

Should we implement that as part of our custom stream protocol? As a sort of “proof-of-knowledge handshake” that’s performed before anything else is transmitted?

So we were curious if there’s a more idiomatic way of doing something like this in libp2p! :slight_smile: Or if there’s an example application which does a similar thing, which we could refer to.

By now, we have two rough ideas for how to do what we want:

  • Use libp2p’s “Private Network” functionality, which seems to have a Rust implementation in the “libp2p-pnet” crate. It seems that this functionality is not supported. Here’s a code snippet for how to set it up. It seems that pnets are currently not supported on QUIC, however (which means that we’d have to use TCP connections). And it’s not clear to us yet which NAT traversal techniques we’d be able to use.
  • Negotiate a “mutual proof of knowledge” ourselves, maybe by using a password-authenticated key exchange library like the “pake-cpace” crate. This seems to be the approach that pcp uses.

If anyone has thoughts on the better route, or sees an alternative, let us know! :slight_smile:

Hi, I wrote something similar in the past to facilitate basic p2p file transfers. Haven’t touched in a while and it’s probably not working anymore:

It’s written in Go though but still could give some inspiration :+1:

Best
Dennis

@blinry the authorization discussion would be an interesting one to have at the next rust-libp2p meeting. It will happen next Tuesday, August 13: rust-libp2p Open Maintainers Call · Luma