Files
ruvnet--RuView/v2/crates/wifi-densepose-sensing-server/src/lib.rs
T
Dragan Spiridonov 7d6d66941a feat(ws): single-use WebSocket ticket store (ADR-272 groundwork)
Audit finding this exists to close — verified empirically, not inferred. With
RUVIEW_API_TOKEN set (operator believes auth is ON), a real WebSocket handshake
carrying NO credential:

  /ws/sensing         -> 101 Switching Protocols
  /ws/introspection   -> 101 Switching Protocols
  /api/v1/stream/pose -> 101 Switching Protocols
  /api/v1/models      -> 401   (control: REST is correctly gated)

The REST control plane is locked while the DATA plane — live presence, pose and
vitals — is open to anyone who can reach the port. Two of those paths sit
outside PROTECTED_PREFIX entirely; the third is the documented EXEMPT_PATHS
entry. The exemption was reasonable when added (a browser cannot set
Authorization on an upgrade) but its blast radius is larger than it looks, and
phase 3 sharpened the contrast by making REST genuinely strong.

(To be precise about what was proven: the handshake is accepted. A payload
frame was not captured in that window, so this is "the connection is
established without a credential", not "data was read".)

This commit adds only the store; wiring it into the middleware is a breaking
change for browser clients and lands with the UI update.

Design notes:
- Single use. `consume` REMOVES the entry, so a replay of the same URL fails
  even inside the TTL. This is what makes a credential-in-a-query tolerable:
  by the time it reaches an access log or a Referer header, it is spent.
- 30-second TTL. Long enough for a page to open a socket; too short to harvest.
- It is not the credential. It authorizes one WebSocket. It cannot be replayed
  against /api/v1/*, cannot be refreshed, and carries no reusable identity.
- The grant captures the ISSUING principal's scopes, so a WebSocket inherits
  exactly the authority of the credential that asked for it — a sensing:read
  session cannot mint a ticket that outranks itself.
- Capped at 512 outstanding, self-healing as tickets expire, so an
  authenticated but misbehaving caller cannot grow the map without bound.
- In-memory because that is correct, not merely convenient: a ticket surviving
  a restart would outlive the server that vouched for it.

Native clients (Python, Rust CLI, TS MCP) are NOT browsers and will send a
normal Authorization header on the upgrade instead — tickets would add a
round-trip and a second credential path for no benefit.

12 tests: single-use enforced, replay refused, expiry refused AND pruned,
unknown ticket refused, 256-bit unpredictability, grant carries issuer scopes,
cap enforced and self-healing, and query parsing including `?myticket=x` not
being read as `?ticket=x`.

Co-Authored-By: Ruflo & AQE
2026-07-22 18:41:34 +02:00

46 lines
1.5 KiB
Rust

//! WiFi-DensePose Sensing Server library.
//!
//! This crate provides:
//! - Vital sign detection from WiFi CSI amplitude data
//! - RVF (RuVector Format) binary container for model weights
//! - Opt-in bearer-token auth for the `/api/v1/*` HTTP surface (`bearer_auth`)
//! - Host-header allowlist / DNS-rebinding defense (`host_validation`)
//! - Generic, leak-free internal-error responses (`error_response`, ADR-080 #2)
//! - Real-time CSI introspection / low-latency tap (`introspection`, ADR-099)
pub mod bearer_auth;
pub mod ws_ticket;
pub mod cli;
pub mod dataset;
pub mod edge_registry;
#[allow(dead_code)]
pub mod embedding;
pub mod error_response;
pub mod graph_transformer;
pub mod host_validation;
pub mod introspection;
pub mod matter;
pub mod model_format;
pub mod mqtt;
pub mod path_safety;
pub mod semantic;
/// ADR-262 P3: the live RuField surface — turns the governed sensing cycle into
/// signed RuField `FieldEvent`s on the additive `/api/field` + `/ws/field`
/// endpoints, via the `wifi-densepose-rufield` anti-corruption bridge.
pub mod rufield_surface;
pub mod rvf_container;
pub mod rvf_pipeline;
pub mod sona;
pub mod sparse_inference;
#[allow(dead_code)]
pub mod trainer;
pub mod vital_signs;
/// ADR-270 Mist and NETGEAR telemetry providers.
pub mod vendor_mist_netgear;
/// ADR-270 Origin AI and Plume/OpenSync providers.
pub mod vendor_origin_plume;
/// ADR-270 scalar, network-only, and fail-closed vendor providers.
pub mod vendor_remaining;
/// ADR-270 provider registry and canonical event helpers.
pub mod vendor_rf;