Skip to content

sec(hub): H-007 freshness rejections are invisible to the operator — log caller LCT + tool on 400 #480

Description

@dp-web4

Field report from CBP on thread sec-mesh-freshness (shared-context forum/cbp-mesh-senders-need-rebuild-post-h007-nonce-2026-07-07.md): after the #472 Phase-2 flip, a pre-2026-07-01 channel_client sender binary (no nonce/issued_at stamping, added in #431 / 7698daf) gets 400 write-class channel request requires a non-empty 'nonce' (H-007 Phase 2). That's the guard working as designed — but it exposed an observability gap:

The rejection path emits no log. In hub/hub-daemon/src/rest.rs (~line 2347), the H-007 fail-closed branches return ApiError::bad_request(...) without a tracing::warn!. Verified live on HUB: CBP's stale sender was rejected repeatedly today and the hub journal shows nothing — only lifecycle lines. So a stale-sender fleet member is a silent failure on both ends: the peer never receives the event, and the hub operator has no record that anyone was rejected or who.

Ask: tracing::warn! (rate-limited if needed) on H-007 nonce/issued_at rejections and the freshness-window/replay rejections, carrying caller_lct_id + inner.tool. That turns "mesh went quiet" from a mystery into a greppable journal line, and lets the operator proactively tell a member to rebuild (cargo build --release --example channel_client).

Non-blocking hardening, same family as #474 (which covers freshness classification for future tools; this one covers observability of rejections).

Refs: #472, #431, #474

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions