Skip to content

A self-asserted revision can permanently block a peer's certificate updates #82

Description

@hexfusion

What would you like to be added:

Bound the revision a peer may assert in a SWIM state broadcast, or key the monotonic guard on something the sender cannot choose.

Why is this needed:

store_site_cert_pem drops an incoming certificate when the retained revision for that origin is greater than the broadcast's. Both the origin and the revision are self-asserted fields in the payload.

Honest revisions are wall-clock nanoseconds (grid_network.rs), so they sit near 1.79e18 today. A broadcast claiming u64::MAX is 1.84e19 and wins permanently: every later broadcast from the real site fails the guard and is dropped.

The victim cannot recover by re-announcing, because its revision is always lower. The retained entry is only cleared by remove, reached through eviction after dead_member_ttl, so a healthy site that stays alive never qualifies. Clearing it otherwise means restarting each receiving operator.

The same guard shape is used for gateway addresses (latest_gateway_revision_by_origin).

For context, hashicorp/memberlist documents the same class as inherent to a shared-key gossip layer: an authenticated-but-malicious peer can "reclaim or impersonate a node's name (by broadcasting a higher incarnation number)" (SECURITY.md). The difference here is that the retained entry is not self-healing, so a live peer cannot recover by re-announcing.

memberlist excludes malicious key holders from its threat model, but only because it requires gossip encryption to be enabled and assumes one administrative domain. Grid meets neither: swimKeyRef is optional and ships null in the example, and peers are independently managed clusters. Without a key the trust boundary is UDP reach to the port.

Separately, memberlist supports a keyring so the primary key rotates while older keys still decrypt, giving zero-downtime rotation. Grid holds a single key and rotates by coordinated restart.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions