Implement a Hub

The Hub is the trust broker: it owns sessions, pairing, turns, tool routing, confirms, and audit. Everything else (Surfaces, Companions, the Provider) talks through it and only through it.

npm install @schwaizer/ocp-protocol

The contract you are implementing

@schwaizer/ocp-protocol gives you the wire truth: parseMessage() (with the forward-compat rule built in — unknown types parse to null, never reject), every message schema, and the golden conformance vectors. Your Hub is conformant when the vector suite passes against it.

Minimum viable Hub, in order

  1. Discovery — serve /.well-known/ocp.json (issuer, jwks_uri, ws_endpoint, profiles) and your signing keys at the JWKS URL.
  2. Surface leg — authenticated WS; session.open → create a session, answer session.linked with the negotiated capabilities and a sid.
  3. PairingPOST /ocp/pair/start (mint the ≤90 s single-use QR JWS) → POST /ocp/pair/claim (verify, burn the nonce ATOMICALLY, hold a pending claim) → pair.approval_request to the Surface → on approval mint the companion token cnf-bound to the device key → pair/result hands it over. Every failure is PAIR_DENIED, identically shaped.
  4. Companion leg — verify token + fresh device-key PoP on connect; attach or resume (resume = key + PoP again); emit pair.linked / session.resumed to the Surface.
  5. Turns — one in-flight per session; barge-in aborts with turn.error{TURN_ABORTED}; stream your Provider's output as turn.delta / turn.citation; finish with turn.done{contextRev}. Mirror turn.input to the other peer.
  6. Tools + confirms — store tools.advertise as hints; re-authorize per call; gate write: true behind ui.request broadcast to both peers, first answer wins, EXPIRY IS DENY; dispatch action.request to the surface and feed action.result back into the turn.
  7. Lifecycle discipline — heartbeats both ways, 60 s companion grace, surface drop closes immediately, TTLs 30 min idle / 4 h absolute, token refresh (session.refreshsession.refreshed) never extends session TTLs, and session close resolves pending confirms to deny.

Hardening checklist (Core §14)

Rate-limit pair/claim per IP · uniform PAIR_DENIED on every pairing failure path · takeover of a live companion needs a SURFACE-ONLY confirm · audit pair/link/takeover/tool/confirm events · attestation hook if your deployment requires verified devices.

The reference implementation is the 0x00 platform's Hub; its integration suites (pairing, turns, tools+confirms, hardening) map 1:1 onto this list.