Peering card: show the outbound key as its own row with a fingerprint (symmetric with inbound) #241
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found dogfooding v0.6.24 (the #236 "Replace key" affordance).
The problem
The relationship card renders the two key sides asymmetrically:
INBOUND KEY 3fd2ac2451e1… [Revoke]. The fingerprint gives the operator a stable, recognizable identity for the credential.Peer.Key) has no display at all — #236 landed only a bare[Replace key]button floating in the actions row next to[Remove].The functional gap #236 closed is real (you can replace the key), but from a UX standpoint it's a dead end: pressing it, pasting, and saving produces no visible change. The operator has no "before" to compare against and no "after" to confirm the swap took. A destructive-ish action with no state feedback reads as "did that do anything?".
The fix
Give the outbound key a row that mirrors the inbound one, directly below it:
Replacing the key then visibly changes the fingerprint — the confirmation the action currently lacks. The
[Replace key]button moves out of the actions row into this row (superseding the bare button from #236).Why this is clean (grounded in the code)
The outbound key is a live credential and
listPeersdeliberately never echoes it ("The peer's key is never echoed back"). But we don't need the key — we need a non-secret fingerprint, and one already exists:peering.KeyIDOf(secret string)(internal/peering/auth.go) parses the storedCAIRN-PEER1.secret, derives the Ed25519 public half, and returnssha256(pub)[:8]hex — documented as leaking nothing about the private key.keyIDFromPublic) used for the inboundkey.idalready exposed bylistKeys(#136). So exposing the outbound fingerprint is exactly as safe as the inbound id we already show.Bonus property: because both sides derive the id from the same public key, the outbound fingerprint shown here equals the inbound key id the peer shows for us. Two admins can read the two fingerprints to each other out of band and confirm they hold the matching pair — a real verification nicety, not just cosmetics.
Shape
listPeersadds"keyFingerprint": KeyIDOf(pr.Key)per peer (non-secret; raw key still never returned).OUTBOUND KEYrow inpeerCardElbelow the inbound row, showingkeyFingerprint.slice(0,12)+"…"+ the relocated[Replace key]. Remove the bare button from the actions row.peeringOutbound.Refs: #150, #236, #136.
Shipped in v0.6.25 (PR #242, merged). The card now renders:
listPeersreturnskeyFingerprint = peering.KeyIDOf(pr.Key)(sha256 of the public half — the same value the peer shows as its inbound key id; raw key still never echoed). Replace moved from the actions row into this row, so a key swap now visibly changes the fingerprint.Live on both dogfood instances on
192.168.10.245/cordy/cairn:v0.6.25@sha256:7d8ec426…, both pods 1/1. Closing.