mirror of
https://github.com/ruvnet/RuView
synced 2026-08-05 19:41:44 +00:00
7d6d66941a
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
46 lines
1.5 KiB
Rust
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;
|