Files
ruvnet--RuView/api-docs/adr/ADR-296-sensor-data-plane-bind-hardening.md
T
2026-08-11 17:41:30 +00:00

60 lines
2.6 KiB
Markdown

# ADR-296: Sensor data-plane hardening — UDP bind control and source allowlist (step one)
- **Status**: Accepted — initial implementation (this PR)
- **Date**: 2026-08-11
- **Deciders**: ruv
- **Tags**: security, udp, sensor-ingest, sensing-server
## Context
The CSI UDP receiver binds `0.0.0.0:{udp_port}` unconditionally
(`main.rs:5706`), with no equivalent of the HTTP `--bind-addr` flag (which
correctly defaults to `127.0.0.1`), no source allowlist, no message
authentication, no device identity, and no replay defense. Any host that can
reach the UDP port can inject a valid-shaped frame, flip an auto-detecting
server into a live source state, and influence presence/vital/automation
outputs (issue 1394).
An IP allowlist does not stop LAN spoofing, but bind control plus an allowlist
is the correct, shippable first step; per-device keys + authenticated
encryption + monotonic sequence + freshness window + replay rejection is the
full fix and is larger.
## Decision
**This PR (step one):**
- Add `--udp-bind` (env `RUVIEW_UDP_BIND`), **defaulting to `127.0.0.1`**.
Binding to a routable address is now an explicit operator choice, mirroring
the HTTP path. Desktop/appliance defaults stay loopback.
- Add an optional source IP/CIDR allowlist (`--udp-allow`); when set, frames
from other sources are dropped and counted. Loopback is always allowed.
- Emit a startup security log line stating the bind scope and whether an
allowlist is active; refuse a routable bind without an allowlist unless an
explicit `--udp-insecure-lan` override is passed (parallel to the existing
Docker HTTP refusal).
- Publish a `SECURITY.md`/advisory note describing the threat model and safe
deployment.
**Explicitly deferred to a follow-up ADR (step two):** per-device provisioned
keys, MAC/AEAD, device identifiers, monotonic sequence numbers, freshness
window, and replay rejection. This ADR documents that gap rather than
implying the data plane is authenticated.
## Consequences
- Removes the default open-to-LAN exposure with a one-line-safe default.
- Not spoof-proof on a trusted LAN — the advisory says so plainly, and the
override name (`--udp-insecure-lan`) makes the residual risk legible.
- A behavior change for anyone relying on the old implicit `0.0.0.0` default;
called out in the changelog and the startup log.
## Validation
- Unit tests: default bind is loopback; routable bind without allowlist is
refused unless overridden; allowlist accept/drop with counting; loopback
always allowed.
- `cargo test -p wifi-densepose-sensing-server`.
- Real-silicon validation of the LAN path remains required before any
deployment claim.