···11#+PROPERTY: COOKIE_DATA recursive
22#+STARTUP: overview
3344-* concepts [0/4]
44+* concepts [0/5]
5566the skypod architecture is broken into pieces:
77···2727It acts mostly as a smart router; socket connection, authentication, and directed and
2828realm-wide broadcast.
29293030-***** TODO webrtc requirements
3030+**** realm client
31313232-- [ ] what needs to happen for webrtc? I think SDP messages will just flow like normal
3333- - checkout whatever simplepeer does
3232+The realm client manages a full-mesh p2p network with other connected peers in the realm,
3333+and exposes the combined set of incoming messages as a stream that the client can do
3434+whatever with.
34353535-**** realm client
3636+***** realm encryption
36373738In order to keep private data off of the server, the realm client takes on the additional
3838-task of maintaining a shared encyrption key for the realm, which can be used to encrypt
3939+task of maintaining a shared encryption key for the realm, which can be used to encrypt
3940data going over broadcasts.
40414141-***** TODO key exchange protocol
4242+****** TODO key exchange protocol
42434344*** identity
4445···64656566Could we use webauthn, or some way to use a yubikey to sign something?
66676767-*** sync
6868+*** connection flow
6969+7070+#+begin_src mermaid :file docs/readme/connection-flow.png
7171+ sequenceDiagram
7272+ participant Server as Server
7373+ participant Client as Client
7474+ participant PeerA as Existing Peer A
7575+ participant PeerB as Existing Peer B
7676+7777+ Client<<->>Server: WebSocket Connection
7878+7979+ Note over Client, Server: Authentication Phase (3 second timeout)
8080+ alt Registration (new realm)
8181+ Client->>Server: JWT: preauth.register {pubkey}
8282+ Server->>Server: validate JWT signature
8383+ Server->>Server: ensureRegisteredRealm(realmid, identid, pubkey)
8484+ else Authentication (existing realm)
8585+ Client->>Server: JWT: preauth.authn {}
8686+ Server->>Server: get publickey for issuer
8787+ Server->>Server: validate JWT signature
8888+ else Invitation Exchange
8989+ Client->>Server: JWT: preauth.exchange {inviteJwt, pubkey}
9090+ Server->>Server: get publickey for issuer
9191+ Server->>Server: validate invitation JWT signature & nonce
9292+ Server->>Server: admitToRealm(realmid, identid, pubkey)
9393+ Server->>Server: identity admitted
9494+ end
9595+9696+ Note over PeerB, Server: Authenticated! Exchange Peer Identities
9797+ par do
9898+ Server->>Client: preauth.authn response {peers[], identities{}}
9999+ and
100100+ Server--)PeerA: realm.rtc.peer-joined {identid, pubkey}
101101+ and
102102+ Server--)PeerB: realm.rtc.peer-joined {identid, pubkey}
103103+ end
104104+105105+ Note over Client, PeerB: WebRTC Connections (initiated by Client)
106106+ par do per connected peer
107107+ Client->>+Server: realm.rtc.signal {signed_jwt, localid, remoteid}
108108+ Server->>PeerA: realm.rtc.signal {signed_jwt, localid, remoteid}
109109+ PeerA->>PeerA: verify JWT signature (pubkey from `peer-joined`)
110110+ PeerA->>Server: realm.rtc.signal {signed_answer_jwt, localid, remoteid}
111111+ Server->>-Client: realm.rtc.signal {signed_answer_jwt, localid, remoteid}
112112+ Client->>Client: verify JWT signature (pubkey from `authn` response)
113113+114114+ Note over Client, PeerA: Direct P2P Connection Established
115115+ Client->>PeerA: Direct WebRTC Connection
116116+ loop every 30s
117117+ PeerA<<->>Client: realm.rtc.ping/pong
118118+ PeerA<<->>Client: application messages
119119+ end
120120+ end
121121+122122+ Note over PeerB, Server: Message Flow (Operational)
123123+ Client->>PeerA: Application Data (p2p)
124124+ Client->>PeerB: Application Data (p2p)
125125+ Client->>Server: realm.broadcast {payload, recipients}
126126+ Server->>PeerB: realm.broadcast {payload}
127127+128128+ Note over PeerB, Server: Connection Persistence & Error Handling
129129+ alt Socket Error/Close
130130+ Client->>Client: Connection destroyed
131131+ Server->>PeerA: realm.rtc.peer-left {identid}
132132+ Server->>PeerB: realm.rtc.peer-left {identid}
133133+ PeerA->>PeerA: Disconnect peer
134134+ PeerB->>PeerB: Disconnect peer
135135+ else Peer Leaves
136136+ PeerA->>Server: Connection closes
137137+ Server->>Client: realm.rtc.peer-left {peerA_identid}
138138+ Server->>PeerB: realm.rtc.peer-left {peerA_identid}
139139+ Client->>Client: Disconnect from PeerA
140140+ end
141141+#+end_src
142142+143143+#+RESULTS:
144144+[[file:docs/readme/connection-flow.png]]
145145+146146+*** message format
147147+148148+A message consists of:
149149+150150+- ~typ~ :: the message type, see below
151151+- ~msg~ :: a message key, used for discrimination on the payload
152152+- ~seq?~ :: an (optional) sequence number, which allows for request/reply semantics
153153+- ~dat?~ :: a payload, the schema for which depends on ~typ~ and ~msg~ (possibly omitted)
154154+155155+See ~#common/protocol~ for the messages that have been defined.
156156+157157+**** ~typ~
158158+159159+- ~evt~ :: events - one-way notifications
160160+- ~req~ :: requests - request-response pattern with sequence matching
161161+- ~res~ :: responses - correlated responses to requests by ~seq~
162162+- ~err~ :: errors - structured errors with HTTP-style status codes
163163+164164+**** examples
165165+166166+#+begin_example
167167+{
168168+ "typ": "req",
169169+ "msg": "preauth.register",
170170+ "seq": 1234,
171171+ "dat": {
172172+ "pubkey": { ... }
173173+ }
174174+}
175175+#+end_example
176176+177177+#+begin_example
178178+{
179179+ "typ": "req",
180180+ "msg": "preauth.authn",
181181+ "seq": 1234
182182+}
183183+#+end_example
184184+185185+#+begin_example
186186+{
187187+ "typ": "res",
188188+ "msg": "preauth.authn",
189189+ "seq": 1234,
190190+ "dat": {
191191+ "identities": { ... },
192192+ "peers": { ... }
193193+ }
194194+}
195195+#+end_example
196196+197197+*** message authentication
198198+199199+A client authenticates to the system and to peers by exchanging signed JWTs as the first
200200+messages in the messaging protocol; for authenticating to the realm, and for exchanging
201201+webrtc signaling messages.
682026969-Once a device has authenticated to the realm server over a websocket connection, it can
7070-send and broadcast any message it likes to the other online of the realm, via the websocket
7171-announcement channel.
203203+**** TODO webrtc encryption?
722047373-This sets it up to be used as a signaling server for WebRTC, allowing realm devices to
7474-communicate p2p without a dependency on the realm server outside of authentication and
7575-signaling.
205205+The websocket is encrypted by virtue of ~wss~ and the server's cert, but I'm not sure if
206206+the traffic over webrtc is encrypted; if it's not, we should figure that out.
7620777208** feed proxy server
78209