ssbc / ssb2-discussion-forum

not quite tiny, also not quite large
17 stars 1 forks source link

Network topology and invites #25

Open staltz opened 1 year ago

staltz commented 1 year ago

Here's my full thoughts about what to do with network topology, bootstrapping, servers, and invites, in PPPPP

Hubs

Hubs are NAT-privileged servers that help users to connect with each other. Largely inspired by SSB Rooms 2.0, with some similarities and some differences:

Similar to Rooms 2.0:

Different to Rooms 2.0:

Invites

Participants: invite creator, invite claimer

An invite is a token held by a PPPPP user ("invite creator") that allows another user to join the network. Any stranger who presents the invite in the "extra" payload in SHSe will be recognized as the invited claimer.

Permissions are powers attached to an invite. Once the invite is consumed, the permission is executed. There are currently two types of permissions:

The permission is an attribute known only by the invite creator, and is not shared.

Encoding

An invite can be encoded as either a URL or a URI.

URI

The URI is the more pure form, which is:

ppppp://invite/$HUB_ADDRESS/$HUB_SHSE/$USER_SHSE

For example

ppppp://invite/dns4/hermies.club/tcp/8008/shse/16Uiu2HAm1Q5Z1Y5.9R7XmBhHF5ooPg34j9TQcz/shse/cEu6TksRG3uXAiKF.G9d1BqPJDjSJaw6xX6s5ab

The whole sequence $HUB_ADDRESS/$HUB_SHSE/$USER_SHSE combined should be multiaddr formatted or "inspired" (shse is not yet supported by multiaddr).

The Hub SHSe has two portions separated by a dot ., the first portion is the public key of the hub used to establish Secret Handshake, and the second portion is an authentication token used by the Hub as an invite code that authorizes the invite claimer to become a hub member.

The user SHSe similarly has two portions, but the Secret Handshake this time is established "nested" within the Hub Secret Handshake, to create a "tunneled connection". The token portion of the user SHSe is the "user invite" and is used to claim permissions granted by the invite creator.

How would LAN connections work? Well, not a big priority at the moment, but it seems like the URI system already supports it, e.g. ppppp://invite/ip4/192.168.1.123/tcp/8008/shse/16Uiu2HAm1Q5Z1Y5.9R7XmBhHF5ooPg34j9TQcz, note only one SHSe is needed, for the invite creator. The URI itself can be shared by copy-pasting or QR code, UPnP, or some fancy LAN UDP broadcast method.

URL

The URL form of the invite code is an HTTP address with the URI embedded in the fragment portion of the URL, pointing to a page that then renders the URI as a link or QR code. For example:

https://hermies.club/invite#%2Fdns4%2Fhermies.club%2Ftcp%2F8008%2Fshse%2F16Uiu2HAm1Q5Z1Y5.9R7XmBhHF5ooPg34j9TQcz%2Fshse%2FcEu6TksRG3uXAiKF.G9d1BqPJDjSJaw6xX6s5ab

There are no guidelines for what the URL should be before the #, but after the # it MUST be the URI.

Inviting a new user to the network

sequenceDiagram

participant A as Alice
participant H as Hub
participant B as Bob

note over A: creates aliceToken<br />with followback perm
A->>H: ask for hub token
activate H
H->>H: create hubToken
H-->>A: hubToken
deactivate H
A->>B: Externally: send invite URL
B->>H: HTTP: open URL
activate H
H-->>B: HTML with PPPPP invite URI
deactivate H
B->>B: open PPPPP app,<br />follow Alice
B->>H: muxrpc: connect with hubToken in SHSe
activate H
H->>H: add Bob as member
H-->>B: OK
deactivate H
B->>H: muxrpc: connect to anyone online<br />and try to replicate Alice
H-->>B: OK
alt If Alice is online
  B->>A: muxrpc: connect with aliceToken in SHSe
  activate A
  A->>A: detect aliceToken,<br />apply followback on Bob,<br />delete aliceToken
  A-->>B: OK
  deactivate A
end

Inviting a new device to my account

sequenceDiagram

participant O as Old device
participant H as Hub
participant N as New device

note over N: instruct user to create<br />an invite on the old
note over O: creates oToken<br />with identity-add perm
O->>H: ask for hub token
activate H
H->>H: create hubToken
H-->>O: hubToken
deactivate H
O->>N: Externally: send invite URL or URI
N->>N: input URL or URI
N->>H: muxrpc: connect with hubToken in SHSe
activate H
H->>H: add New as member
H-->>N: OK
deactivate H
alt If Old is online
  N->>O: muxrpc: connect with oToken in SHSe
  activate O
  O->>O: detect oToken,<br />apply identity-add on New,<br />delete oToken
  O-->>N: OK
  deactivate O
else If Old is offline
  N->>O: muxrpc: connect with oToken in SHSe
  O-->>N: Failure
end

Viral hubs

Discovering hubs

staltz commented 1 year ago

As I implement this, I stumbled upon one important need:

The old device needs to include their Identity Tangle ID alongside their pubkey. Perhaps:

-ppppp://invite/$HUB_ADDRESS/$HUB_SHSE/$USER_SHSE
+ppppp://invite/$HUB_ADDRESS/$HUB_SHSE/$USER_SHSE/$USER_ID
staltz commented 1 year ago

Another suggestion from Mix: during tanglesync, replicate only metadata+sig+pubkey and then later fill in all those new msgs with their data. This is to allow first checking if the uploader is spamming us with too much data (based on dataSize fields accumulated).

staltz commented 1 year ago

I'm updating the diagrams because the SHSe token-based authorization is unnecessary given that there are no firewall between hub members. Also, the peer's identity (identity tangle ID) makes more sense to be exchanged outside of the invite.

Also, I need the URI structure to be more flexible, so now it follows a pattern where ppppp://invite URIs are followed by any number of "commands", where each command has a name plus a fixed-length list of arguments.

Inviting a new user to the network

Invite URL:

ppppp://invite/join/HOST/PORT/PUBKEY/TOKEN/follow/ALICE_ID/promise.follow/identity.ALICE_ID/ALICE_TOKEN

made of 3 "commands":

sequenceDiagram

participant A as Alice
participant H as Hub
participant B as Bob

note over A: creates aliceToken<br />for follow promise
A->>A: publishes self-encrypted<br/>msg about aliceToken 
A->>H: ask for hub token
activate H
H->>H: create hubToken
H-->>A: hubToken
deactivate H
A->>B: Externally: send invite URL
B->>H: HTTP: open URL
activate H
H-->>B: HTML with PPPPP invite URI
deactivate H
B->>B: open PPPPP app
note over B: parse URI and detect 3 commands
note over B: execute command "join"
B->>H: connect with hubToken in SHSe
activate H
H->>H: add Bob as member
H-->>B: OK
deactivate H
note over B: execute command "follow"
B->>B: follow aliceID
B->>H: muxrpc: connect to anyone online<br />and try to replicate aliceID
H-->>B: OK
note over B: execute command "promise.follow"
alt If some pubkey of aliceID is online
  B->>A: connect with SHS
  activate A
  B->>A: muxrpc: promise.follow(aliceToken, bobID)
  A->>A: detect aliceToken,<br />apply followback on bobID,<br />delete aliceToken
  A-->>B: OK
  deactivate A
end

Inviting a new device to my account

Invite URL:

ppppp://invite/join/HOST/PORT/PUBKEY/TOKEN/tunnel-connect/HUB_PUBKEY/OLD_PUBKEY/promise.identity-add/identity.IDENTITY_ID/OLD_TOKEN

made of 3 "commands":

sequenceDiagram

participant O as Old device
participant H as Hub
participant N as New device

note over N: instruct user to create<br />an invite on the old
note over O: creates oToken<br />with identity-add perm
O->>H: ask for hub token
activate H
H->>H: create hubToken
H-->>O: hubToken
deactivate H
O->>N: Externally: send invite URL or URI
N->>N: input URL or URI
note over N: parse URI and detect 3 commands
note over N: execute command "join"
N->>H: connect with hubToken in SHSe
activate H
H->>H: add New as member
H-->>N: OK
deactivate H
note over N: execute command "tunnel-connect"
alt If old pubkey is online
  N->>O: connect with SHS
  activate O
  note over N: execute command "promise.identity-add"
  N->>N: consent = sign(":identity-add:IDENTITY_ID", new privkey)
  N->>O: muxrpc: promise.identityAdd(oToken, new pubkey, consent)
  O->>O: detect oToken,<br />apply identity-add on New,<br />delete oToken
  O-->>N: OK
  deactivate O
else If Old is offline
  N->>O: connect with SHS
  O-->>N: Failure
end