···1#+PROPERTY: COOKIE_DATA recursive
2#+STARTUP: overview
34-* concepts [0/4]
56the skypod architecture is broken into pieces:
7···27It acts mostly as a smart router; socket connection, authentication, and directed and
28realm-wide broadcast.
2930-***** TODO webrtc requirements
3132-- [ ] what needs to happen for webrtc? I think SDP messages will just flow like normal
33- - checkout whatever simplepeer does
03435-**** realm client
3637In order to keep private data off of the server, the realm client takes on the additional
38-task of maintaining a shared encyrption key for the realm, which can be used to encrypt
39data going over broadcasts.
4041-***** TODO key exchange protocol
4243*** identity
44···6465Could we use webauthn, or some way to use a yubikey to sign something?
6667-*** sync
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006869-Once a device has authenticated to the realm server over a websocket connection, it can
70-send and broadcast any message it likes to the other online of the realm, via the websocket
71-announcement channel.
7273-This sets it up to be used as a signaling server for WebRTC, allowing realm devices to
74-communicate p2p without a dependency on the realm server outside of authentication and
75-signaling.
7677** feed proxy server
78
···1#+PROPERTY: COOKIE_DATA recursive
2#+STARTUP: overview
34+* concepts [0/5]
56the skypod architecture is broken into pieces:
7···27It acts mostly as a smart router; socket connection, authentication, and directed and
28realm-wide broadcast.
2930+**** realm client
3132+The realm client manages a full-mesh p2p network with other connected peers in the realm,
33+and exposes the combined set of incoming messages as a stream that the client can do
34+whatever with.
3536+***** realm encryption
3738In order to keep private data off of the server, the realm client takes on the additional
39+task of maintaining a shared encryption key for the realm, which can be used to encrypt
40data going over broadcasts.
4142+****** TODO key exchange protocol
4344*** identity
45···6566Could we use webauthn, or some way to use a yubikey to sign something?
6768+*** connection flow
69+70+#+begin_src mermaid :file docs/readme/connection-flow.png
71+ sequenceDiagram
72+ participant Server as Server
73+ participant Client as Client
74+ participant PeerA as Existing Peer A
75+ participant PeerB as Existing Peer B
76+77+ Client<<->>Server: WebSocket Connection
78+79+ Note over Client, Server: Authentication Phase (3 second timeout)
80+ alt Registration (new realm)
81+ Client->>Server: JWT: preauth.register {pubkey}
82+ Server->>Server: validate JWT signature
83+ Server->>Server: ensureRegisteredRealm(realmid, identid, pubkey)
84+ else Authentication (existing realm)
85+ Client->>Server: JWT: preauth.authn {}
86+ Server->>Server: get publickey for issuer
87+ Server->>Server: validate JWT signature
88+ else Invitation Exchange
89+ Client->>Server: JWT: preauth.exchange {inviteJwt, pubkey}
90+ Server->>Server: get publickey for issuer
91+ Server->>Server: validate invitation JWT signature & nonce
92+ Server->>Server: admitToRealm(realmid, identid, pubkey)
93+ Server->>Server: identity admitted
94+ end
95+96+ Note over PeerB, Server: Authenticated! Exchange Peer Identities
97+ par do
98+ Server->>Client: preauth.authn response {peers[], identities{}}
99+ and
100+ Server--)PeerA: realm.rtc.peer-joined {identid, pubkey}
101+ and
102+ Server--)PeerB: realm.rtc.peer-joined {identid, pubkey}
103+ end
104+105+ Note over Client, PeerB: WebRTC Connections (initiated by Client)
106+ par do per connected peer
107+ Client->>+Server: realm.rtc.signal {signed_jwt, localid, remoteid}
108+ Server->>PeerA: realm.rtc.signal {signed_jwt, localid, remoteid}
109+ PeerA->>PeerA: verify JWT signature (pubkey from `peer-joined`)
110+ PeerA->>Server: realm.rtc.signal {signed_answer_jwt, localid, remoteid}
111+ Server->>-Client: realm.rtc.signal {signed_answer_jwt, localid, remoteid}
112+ Client->>Client: verify JWT signature (pubkey from `authn` response)
113+114+ Note over Client, PeerA: Direct P2P Connection Established
115+ Client->>PeerA: Direct WebRTC Connection
116+ loop every 30s
117+ PeerA<<->>Client: realm.rtc.ping/pong
118+ PeerA<<->>Client: application messages
119+ end
120+ end
121+122+ Note over PeerB, Server: Message Flow (Operational)
123+ Client->>PeerA: Application Data (p2p)
124+ Client->>PeerB: Application Data (p2p)
125+ Client->>Server: realm.broadcast {payload, recipients}
126+ Server->>PeerB: realm.broadcast {payload}
127+128+ Note over PeerB, Server: Connection Persistence & Error Handling
129+ alt Socket Error/Close
130+ Client->>Client: Connection destroyed
131+ Server->>PeerA: realm.rtc.peer-left {identid}
132+ Server->>PeerB: realm.rtc.peer-left {identid}
133+ PeerA->>PeerA: Disconnect peer
134+ PeerB->>PeerB: Disconnect peer
135+ else Peer Leaves
136+ PeerA->>Server: Connection closes
137+ Server->>Client: realm.rtc.peer-left {peerA_identid}
138+ Server->>PeerB: realm.rtc.peer-left {peerA_identid}
139+ Client->>Client: Disconnect from PeerA
140+ end
141+#+end_src
142+143+#+RESULTS:
144+[[file:docs/readme/connection-flow.png]]
145+146+*** message format
147+148+A message consists of:
149+150+- ~typ~ :: the message type, see below
151+- ~msg~ :: a message key, used for discrimination on the payload
152+- ~seq?~ :: an (optional) sequence number, which allows for request/reply semantics
153+- ~dat?~ :: a payload, the schema for which depends on ~typ~ and ~msg~ (possibly omitted)
154+155+See ~#common/protocol~ for the messages that have been defined.
156+157+**** ~typ~
158+159+- ~evt~ :: events - one-way notifications
160+- ~req~ :: requests - request-response pattern with sequence matching
161+- ~res~ :: responses - correlated responses to requests by ~seq~
162+- ~err~ :: errors - structured errors with HTTP-style status codes
163+164+**** examples
165+166+#+begin_example
167+{
168+ "typ": "req",
169+ "msg": "preauth.register",
170+ "seq": 1234,
171+ "dat": {
172+ "pubkey": { ... }
173+ }
174+}
175+#+end_example
176+177+#+begin_example
178+{
179+ "typ": "req",
180+ "msg": "preauth.authn",
181+ "seq": 1234
182+}
183+#+end_example
184+185+#+begin_example
186+{
187+ "typ": "res",
188+ "msg": "preauth.authn",
189+ "seq": 1234,
190+ "dat": {
191+ "identities": { ... },
192+ "peers": { ... }
193+ }
194+}
195+#+end_example
196+197+*** message authentication
198+199+A client authenticates to the system and to peers by exchanging signed JWTs as the first
200+messages in the messaging protocol; for authenticating to the realm, and for exchanging
201+webrtc signaling messages.
202203+**** TODO webrtc encryption?
00204205+The websocket is encrypted by virtue of ~wss~ and the server's cert, but I'm not sure if
206+the traffic over webrtc is encrypted; if it's not, we should figure that out.
0207208** feed proxy server
209