Skip to content

hub: optionally pin two keys per member (identity + channel) — role-scoped envelope verification #458

Description

@dp-web4

Context

From mesh thread sprout-legion-plan (Sprout ↔ Legion) and hestia PR #12.

Today the hub pins exactly one verifying key per member LCT: MapResolver(HashMap<Uuid, Lct>) keyed by signer_lct_id, and pin_member_key does resolver.insert(lct) (overwrite). verify_envelope verifies every envelope from that member against that one key.

This forces a member that signs from two contexts to use one key across both:

  • a non-interactive mesh watcher (systemd channel_client) that cannot open a passphrase-sealed vault, so it must use a raw on-disk channel key; and
  • interactive member-tier ops (hestia profile push) that could use the sealed vault identity key.

Because only one key can be pinned and the daemon is hard-constrained to the raw channel key, the shared key must be the channel key — so interactive acts must also sign with it. hestia PR #12 resolves this client-side (reconciliation (a)): profile push signs with the pinned member key (the channel key) rather than the sealed identity. That's the right fix for now and needs no hub change.

The (b) option — recorded, not urgent

If a future member-op genuinely needs attestation-grade signing (sealed identity) distinct from delivery/channel signing, the hub would pin two keys per member:

  • an identity key — verifies member-ops / attestation acts;
  • a channel/delivery key — verifies notify/watch/seal.

Each endpoint declares which role it verifies against; the resolver maps (member_lct, key_role) → pubkey. This is a schema + verify_envelope + MemberKeyPinned-event change (the event needs a role/slot field), plus a migration.

Why it's deferred

A profile update is not a higher-assurance act than notify/watch, and anyone holding the raw channel key can already act as the member on the mesh — so today (b) buys little over (a). Filing so the design intent isn't lost: adopt (b) only when an act appears that must be signed by the sealed identity while delivery stays on the channel key.

Refs

🤖 Generated with Claude Code

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