Expand description
Pairing posture: the data-plane auth primitives shared by the agent’s native surfaces.
The agent is paired-or-unpaired. Physical presence on the LAN is the gate for an UNPAIRED agent (the claim window); once paired, a data-plane caller reaching the agent from off-box must present the stored pairing key. The local operator (a loopback peer that was not relayed by a proxy or tunnel) already holds shell-level privilege that exceeds API auth and is trusted past the gate.
Who the caller is gets decided ONCE per request, at the transport edge, by
classify_caller: the peer address plus the request’s forwarding headers
give one CallerClass. Every gate (the HTTP unpaired-node gate, the
dashboard-PIN first set, the pairing claim, the direct MAVLink proxies) is a
function of that value and the pairing state, so no two gates can read the
same caller differently.
These primitives are protocol-level on purpose: more than one native surface enforces the same posture (the HTTP control surface and the direct MAVLink proxies), and a single implementation keeps them from drifting. Surface-specific concerns (request-rate limiting, the HTTP public-path exempt set, the short-TTL caching wrapper) live with each surface, not here.
The pairing state is the agent’s pairing.json ({ "paired": bool, "api_key": "..." }). Read it with load_pairing: an absent file, or one
that is not paired:true, reads as Pairing::Unpaired (open). A file that
exists but cannot be read or parsed, or claims paired:true with no key, is
Pairing::Unreadable and fails closed: it may be a paired node’s record on
a failing card, and reading it as unpaired would open the claim to anyone.
Enums§
- Access
- A data-plane access decision for a paired-or-unpaired agent.
- Caller
Class - Who is on the other end of a request, derived once at the transport edge by
classify_caller. - Pairing
- The resolved pairing posture read from
pairing.json.
Constants§
- FORWARDED_
HEADERS - Proxy / tunnel relay headers. Their presence means the request was forwarded by a reverse proxy or tunnel (e.g. a Cloudflare Tunnel terminating on 127.0.0.1) rather than originating on this host, so it must NOT qualify for on-box loopback trust.
- LIFELINE_
LOCAL_ ADDRS - The agent-owned first-boot addresses: the AP hotspot gateway and the USB gadget address. A private-LAN peer is a lifeline only when it reached one of these.
- RELAY_
FORBIDDEN_ CONFIG_ KEYS - Config subtrees no radio lane may write: the node’s trust roots.
Functions§
- classify_
caller - Classify a caller from its peer address, the local address it reached, and its request headers.
- constant_
time_ eq - Compare two byte slices in time independent of where they first differ, so
the bearer-secret check leaks no timing signal about a partial match. A
length mismatch is rejected up front (the length of the stored key is not
itself a secret); equal-length slices are then folded together with a running
difference accumulator that always visits every byte. The compiler is told
via
std::hint::black_boxnot to short-circuit the loop once a difference is seen. - data_
plane_ access - Decide whether a data-plane connection may be admitted, independent of any transport:
- load_
pairing - Load the pairing posture from a
pairing.json. An absent file, or a state that is notpaired:true, isPairing::Unpaired(open). A file that exists but cannot be read or parsed as a JSON object, or that sayspaired:truewithout a key, isPairing::Unreadable(closed). - local_
addr_ toward - The local address this host would use to reach
peer: the kernel’s route choice, read by connecting an unbound UDP socket (no packet is sent). For a transport that has no per-connection local address (a UDP listener bound to the wildcard), this is the address a reply to the peer leaves from, which is the interface the peer sits on.Nonewhen no route exists. - relay_
config_ key_ forbidden - Whether a config write arriving over a radio lane may not touch
key(a dotted path): the key is one ofRELAY_FORBIDDEN_CONFIG_KEYSor lies beneath one.