Skip to content

Meshtastic: disambiguate feeder WebSocket when multiple ManagedNodes share one API key #383

@pskillen

Description

@pskillen

Summary

MeshCore feeders sharing a NodeAPIKey are supported end-to-end: HTTP ingest uses /api/meshcore/feeders/{feeder_pubkey_prefix}/…, and WebSocket commands use ws/nodes/?api_key=…&feeder_pubkey_prefix=… (#295, phase-2 docs).

Meshtastic feeders sharing one key work for HTTP ingest (POST /api/packets/{node_id}/ingest/ + NodeAuthorizationPermission) but not for /ws/nodes/ commands (traceroute, etc.). NodeConsumer resolves the managed node from the API key alone and returns auths[0].node when multiple NodeAuth rows exist — both bots join the same Channels group node_{meshtastic_node_id}.

This is documented as a limitation in docs/API_KEYS.md (“WebSocket Limitation with Shared Keys”) but not tracked as a fix. Operators (including pre-prod) run two MT feeders on one key; ingest appears fine while command routing can be wrong.

Not the same as meshflow-api#382 (Redis/Channels timeouts). Shared MT keys may amplify reconnect load when Redis is unhealthy; this ticket is correctness for multi-feeder WS identity.

Current behaviour

Meshflow/ws/consumers.pyNodeConsumer._validate_api_key:

  • With feeder_pubkey_prefixresolve_meshcore_feeder() (MC only).
  • With multiple MC auths and no prefix → connect rejected (good).
  • With multiple auths and no prefix (typical Meshtastic bot) → warning API key linked to N nodes; use feeder_pubkey_prefix for MC then return auths[0].node (bad for MT).

Meshtastic bot connects with feeder_pubkey_prefix=none (meshflow-bot MeshflowWSClient).

Expected behaviour

Parity with MeshCore and with MT ingest:

Path Disambiguation
MT ingest {node_id} in URL (already works)
MT WebSocket Query param, e.g. feeder_node_id (decimal) and/or feeder_node_id_str (!hex8)
MC ingest {feeder_pubkey_prefix} in URL (works)
MC WebSocket feeder_pubkey_prefix query param (works)

When multiple MT feeders share a key:

  • Each bot connects with its own identity in the WS URL.
  • Each joins node_{meshtastic_node_id} for its ManagedNode.
  • group_send from traceroute dispatch reaches the correct feeder only.

When identity is missing/ambiguous: reject connect (like multiple MC without prefix), do not silently pick auths[0].

Repo ownership

Repo Work
meshflow-api (primary) NodeConsumer + tests; optional openapi.yaml note on WS query params; update docs/API_KEYS.md
meshflow-bot (follow-up) Append local nodenum or !hex to ws/nodes/ URL for RADIO_PROTOCOL=meshtastic (mirror MC feeder_pubkey_prefix_provider)

Suggested API design

ws/nodes/?api_key=…&feeder_node_id=1127973616
# or
ws/nodes/?api_key=…&feeder_node_id_str=!433b82f0

Resolve via NodeAuth.objects.get(api_key=…, node__meshtastic_node_id=…) (same rule as ingest permission).

Keep existing feeder_pubkey_prefix for MC unchanged.

Edge case: one MC + one MT on the same key — MT bot must not hit the len(mc_auths)==1 early return that assigns the MC node to a Meshtastic connection.

Acceptance criteria

  • Two Meshtastic ManagedNodes on one NodeAPIKey: each can hold a stable /ws/nodes/ connection on different group=node_* (verify in API logs).
  • Traceroute group_send to feeder A is received only by A’s socket (integration or manual test).
  • Connect without disambiguator when len(auths) > 1 (MT-only or MT+MC) is rejected with a clear log/warning.
  • MC shared-key WS behaviour unchanged.
  • docs/API_KEYS.md updated: shared keys supported for MT WS when query param present.
  • meshflow-bot follow-up tracked (child issue or linked PR in bot repo).

Related (no duplicate)

Issue Relationship
#295 Closed — MC ingest disambiguation (not MT WS)
#382 Redis/Channels stability (orthogonal)
meshflow-ui#315 UI /ws/messages/ reconnect on route change (orthogonal)
#142 WS presence for traceroute eligibility (separate)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions