Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Gossip Configuration

hoike uses the SWIM protocol (implemented via the foca crate) for lightweight, decentralized coordination across edge nodes. Gossip is a notification channel — it never carries OCSP response data and is never authoritative.

What Gossip Provides

Gossip serves three purposes in a hoike deployment:

FunctionDescription
MembershipAutomatic discovery and failure detection of edge nodes in the fleet
Generation announcementsSigner broadcasts when a new bundle generation is available; edges pull the bundle on receipt
Urgent revocation noticesImmediate notification when an off-cycle delta bundle is produced due to a revocation event
sequenceDiagram
    participant S as Signer
    participant E1 as Edge-01
    participant E2 as Edge-02
    participant E3 as Edge-03

    S->>E1: Generation announcement (epoch 42)
    E1->>S: Pull bundle (epoch 42)
    E1-->>E2: Gossip: new generation 42
    E1-->>E3: Gossip: new generation 42
    E2->>S: Pull bundle (epoch 42)
    E3->>S: Pull bundle (epoch 42)

Configuration

[gossip]
enabled      = true
bind         = "0.0.0.0:7946"
seeds        = ["edge-a.pki.example:7946", "edge-b.pki.example:7946"]
identity_key = "/etc/hoike/gossip.key"
node_name    = "edge-01"
KeyTypeDefaultDescription
enabledbooltrueEnable or disable gossip. Set to false for air-gap deployments.
bindstring"0.0.0.0:7946"Address and port to bind the gossip listener.
seedsarray of strings[]Initial contact points for joining the gossip mesh.
identity_keypath—Path to the Ed25519 key used to sign gossip messages.
peer_identitiestable{}Map of node names to Ed25519 public key paths for broadcast verification.
node_namestringhostnameHuman-readable, unique identifier for this node in the mesh.

Seed Configuration

Seeds are the initial contact points a node uses to join the gossip mesh. They are not special — any existing mesh member can serve as a seed.

Recommendations:

  • Configure at least two seeds for redundancy. If the single seed is down when a new node starts, it cannot join the mesh.
  • Seeds do not need to be dedicated infrastructure. Point new nodes at two or three stable, long-lived edge nodes.
  • A node does not need to list every member — once it contacts one seed, SWIM propagates the full membership.
[gossip]
seeds = [
    "edge-a.pki.example:7946",
    "edge-b.pki.example:7946",
    "edge-c.pki.example:7946",
]

Identity Key

Every gossip participant signs its messages with an Ed25519 key. This prevents spoofed announcements from unauthorized nodes.

Generate a key:

hoike keygen --gossip -o /etc/hoike/gossip.key
chmod 600 /etc/hoike/gossip.key

The key file contains the Ed25519 private key. Protect it with appropriate file permissions.

Peer Identities

The peer_identities table maps each peer’s node_name to the path of its Ed25519 public key file:

[gossip.peer_identities]
"edge-02"  = "/etc/hoike/gossip/edge-02.pub"
"signer-1" = "/etc/hoike/gossip/signer-1.pub"

Enforcement modes:

  • Enforcing mode (non-empty peer_identities): Unsigned, forged, or misattributed generation announcements and urgent-revocation broadcasts are dropped before re-propagation.
  • Permissive mode (empty peer_identities): Unsigned broadcasts are accepted for backward compatibility with a mixed or unconfigured fleet.

Note: A non-empty legacy peer_keys array will now cause startup to fail with an error directing you to migrate to peer_identities.

The corresponding public keys must be distributed to all nodes that will verify broadcasts from that peer.

Node Name

node_name is a human-readable identifier for the node, used in logs and diagnostics. It must be unique across the mesh.

If omitted, hoike defaults to the system hostname. In containerized environments where hostnames may collide, set node_name explicitly.

Failure Detection

SWIM detects failed nodes through a three-phase protocol:

  1. Ping: A random member is pinged each protocol period.
  2. Ping-req: If the ping times out, k other members are asked to ping the suspect on behalf of the requester (indirect probe).
  3. Suspect → Confirm: If indirect probes also fail, the node is marked suspect. After a timeout, it is declared failed and removed from the membership list.

Failed nodes stop receiving generation announcements and urgent revocation notices. When they recover, they rejoin via their configured seeds and pull the current bundle.

Security Model

Gossip is never authoritative. It is a hint channel that triggers bundle pulls. All trust decisions are made by verifying the bundle itself.

The security boundaries are:

  • Generation announcements and urgent-revocation broadcasts are signed with the sender’s identity_key. In enforcing mode (non-empty peer_identities), unsigned or incorrectly signed broadcasts are dropped before re-propagation. SWIM liveness traffic (pings/acks) is not authenticated.
  • Bundle validity is verified independently via CMS seal and epoch chain — not via gossip trust. A gossip announcement only says “a new generation exists”; the edge independently verifies every bundle it loads.
  • A compromised gossip node cannot inject bad responses. The worst it can do is trigger unnecessary pull attempts. The pulled bundle must still pass CMS seal verification and anti-rollback checks.
  • Gossip cannot suppress bundles. Edges also poll on a schedule, so even if gossip is disrupted, bundles are eventually loaded.

Network Requirements

Gossip uses UDP on the configured bind port (default 7946).

Firewall rules must allow:

  • Inbound UDP on the gossip port from all mesh members
  • Outbound UDP to all mesh members on their gossip port

In environments with strict firewall policies, you may need to allowlist the gossip port between all edge nodes and the signer. If UDP is blocked entirely, disable gossip and use air-gap mode or scheduled bundle fetching.

Disabling Gossip

For air-gap deployments or environments where gossip is not feasible:

[gossip]
enabled = false

See Air-Gap Deployments for the full air-gap configuration guide.