docs(roadmap): §8a done (mandatory pairing); split §8b into host+web / peer layers
ci / rust (push) Has been cancelled
ci / rust (push) Has been cancelled
§8a (require native pairing by default, serve --open) shipped + deployed. §8b (delegated approval) refined into §8b-1 (host pending-requests + mgmt endpoints + web Approve/Deny — achievable now) and §8b-2 (peer push to a paired Device A — needs the native/Apple client UI). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+22
-17
@@ -139,23 +139,28 @@ it's unbuildable on the Linux dev box; the trait boundaries are already in the r
|
||||
The unified host + web-console pairing (arm a window → display the host PIN → user enters it on the
|
||||
client) is built and live. Two changes harden it from "works" to "secure by default":
|
||||
|
||||
- **Mandatory PIN pairing by default.** Today the punktfunk/1 host can run open (trust-on-first-use)
|
||||
— *not* acceptable on a shared LAN, where any reachable device could connect. The unified host
|
||||
should `require_pairing` out of the box: a client must complete the SPAKE2 PIN ceremony (one online
|
||||
guess, no offline attack) before any session. The operator arms a window and reads the PIN from the
|
||||
web console (already built); an explicit `--open` escape hatch covers trusted single-user setups.
|
||||
The wire is already in place (`M3Options.require_pairing` + the `serve_session` gate); this flips
|
||||
the default and threads it through `serve --native` and the mgmt arm endpoint.
|
||||
- **Delegated pairing approval** — the ergonomic enabler for "mandatory" (pair a new device without
|
||||
fetching the host PIN out of band):
|
||||
- ✅ **Mandatory PIN pairing by default — done & live** (`§8a`, `serve --native` now requires
|
||||
pairing; `serve --open` disables it). An unpaired client is rejected at the session gate; pairing
|
||||
is via the SPAKE2 PIN ceremony (one online guess, no offline attack) armed from the web console.
|
||||
Validated live: unpaired → "this host requires pairing", then web-armed PIN → "client trusted".
|
||||
Deployed to the dev box + Bazzite.
|
||||
- **Delegated pairing approval** *(next — the ergonomic enabler for "mandatory": pair a device
|
||||
without fetching the host PIN out of band).* Target flow:
|
||||
1. Device A is already paired (authenticated) to Host X.
|
||||
2. The user tries to connect Device B to Host X.
|
||||
3. Host X pushes a request to the authenticated Device A: *"Allow Device B to pair with Host X?"*
|
||||
4. The user approves/denies on Device A; on approve, Host X admits Device B — binding B's
|
||||
certificate fingerprint — with no PIN typed.
|
||||
3. Host X surfaces a request: *"Allow Device B to pair with Host X?"*
|
||||
4. The user approves/denies; on approve, Host X admits Device B — binding B's certificate
|
||||
fingerprint — with no PIN typed.
|
||||
|
||||
Needs: a host→client *pairing-approval-request* (B's fingerprint + a human label) delivered to A's
|
||||
live connection (a QUIC side-plane message) or polled via the mgmt API; an approve/deny round-trip
|
||||
carrying an approval token; the host gating B's admission on it. The web console **and** the Apple
|
||||
client render the approval prompt. PIN pairing stays the bootstrap (the first device, or when no
|
||||
paired device is online to approve).
|
||||
Two buildable layers:
|
||||
- **§8b-1 (host + web — achievable now):** an unpaired B that connects to an approval-enabled host
|
||||
is held as a **pending request** `{id, name, fingerprint, requested_at}` in `NativePairing`
|
||||
instead of a flat reject; mgmt gains `GET /native/pending` + `POST /native/pending/{id}/{approve,
|
||||
deny}`; the web console lists pending requests with Approve/Deny. The **operator approves from
|
||||
the console** — delegated approval via the management surface.
|
||||
- **§8b-2 (peer push — needs the client):** the host also pushes the pending request over a paired
|
||||
**Device A**'s live QUIC connection (a new control-plane message); A's app renders the prompt and
|
||||
replies approve/deny — the user's exact "Device A gets a notification" flow. The native/Apple UI
|
||||
is a client-agent task.
|
||||
|
||||
PIN pairing (§8a) stays the bootstrap — the first device, or when no approver is online.
|
||||
|
||||
Reference in New Issue
Block a user