Skip to content

Share key-resolution admission with main's worker-relay verification

  • Status: accepted
  • Date: 2026-10-11

Context and Problem Statement

Main independently verifies every PDU, membership event and invite relayed by a federation worker (ADR-0071). Its direct call to the complete remote-key resolver bypassed the federation runtime's source quota, in-flight slots and server/key negative cache. A fresh persistent signing key does not make complete peer discovery network-free (ADR-0132).

The relay frames do not carry a main-validated client address. Trusting an address supplied by the worker would let the least-trusted process select new buckets. The cryptographic verification must remain independent of the worker, including during overload.

Considered Options

  • Continue using the raw resolver, relying on IPC and handler-pool limits.
  • Charge a client address or shard identifier supplied in a worker frame.
  • Reuse core key-only resolution and admission with a shared unknown-source bucket for main relay misses.
  • Change the IPC protocol now to bind relays to main's pending HTTP request and validated client address.

Decision Outcome

Chosen option: "Reuse core key-only resolution and admission with a shared unknown-source bucket for main relay misses". The additive resolve_verification_key entry point delegates to the existing core sender helper. Matching cached verification material bypasses discovery and spends no outbound reservation. A miss uses main's configured source quota, in-flight cap and bounded server/key negative cache. The existing guard owns and releases only its own slot, including when the resolver throws.

Main supplies an empty source; it never accepts a source override from the worker. All main relay misses therefore share the existing <unknown> bucket, across the main runtime's handlers and worker channels. This is stricter than separate client-address quotas and can defer legitimate cold-key traffic across otherwise unrelated clients. It is not an aggregate budget for every process.

The result separately identifies local denial. PDU relays return the existing main_overloaded status; membership and invite relays return unaccepted 503 responses, before acceptance hooks or persistent mutations. No denial enters the negative cache. Genuine resolution failure remains a verification refusal. Main still checks the sender signature, event-time key validity and signed-event identity, and rebuilds the envelope from verified JSON. A cache read also works when the complete resolver is not wired.

No persisted format or IPC schema changes are required. Trusted request-context binding is a separate decision, not a worker-provided hint or an assumption that this boundary already implements FED-12.

Positive Consequences

  • IPC and handler-pool bounds no longer substitute for configured key budgets.
  • The same admission and exception-safe ownership rules apply at both boundaries.
  • Local exhaustion defers work rather than accepting it or treating it as a bad signature; an unchanged relay can succeed after admission recovers.
  • Network-free cached verification remains useful under quota/capacity pressure.

Negative Consequences

  • Main's shared unknown-source quota can reduce fairness for cold-key traffic.
  • Other raw-resolver callers, including backfilled-event verification, still require their own reachability/accounting review before whole-FED-10 closure.
  • In-process encrypted IPC tests do not establish separate-process or BSD behavior.