How to Set Up Peer Mesh Communication in Apache Maka

Maka’s Peer Mesh enables cryptographically secured, decentralized host discovery through an authority node that signs rosters and reachability leases, allowing members to join via consumable invitations and maintain synchronized state through periodic reconciliation.

Setting up Peer Mesh communication in Apache Maka establishes a secure, distributed topology where runtime-host instances discover each other and exchange signed advertisements. This guide walks through the complete implementation using the source code from the apache/maka repository, referencing the exact APIs and file paths used in production.

Core Concepts of Peer Mesh

Maka’s Peer Mesh operates on three fundamental primitives defined in packages/runtime-host/src/peer-mesh/model.js and packages/runtime-host/src/peer-reachability/index.js.

Authority Node

The authority node acts as the cryptographic owner of the mesh. It generates the mesh ID, signs the roster, and issues reachability leases. The authorityPrivateKey never leaves the authority node and is exclusively used to sign new rosters and authorize members.

Member Nodes

Member nodes are hosts or clients that join the mesh by consuming signed invitations. Once admitted, they hold reachability leases describing network paths (e.g., via relays) and synchronize state with the authority through reconciliation.

Reachability Leases

These are signed tokens with automatic refresh logic enforced in packages/runtime-host/src/peer-reachability/index.js. Each lease includes TTL, clock skew validation, and refresh lead times. Members must maintain valid leases to remain reachable in the mesh.

Step-by-Step Implementation Guide

Follow these steps derived from packages/runtime-host/src/__tests__/peer-mesh.test.ts to configure your nodes.

1. Create a Transport Implementation

Instantiate a transport satisfying the PeerMeshTransport interface. For testing, use MemoryPeerNetwork from the testing utilities. Production deployments require a custom transport implementation handling control messages and lease exchanges.

import { MemoryPeerNetwork } from '@maka/runtime-host/testing';

const network = new MemoryPeerNetwork();
const authorityPeer = network.create('peer-a');
const memberPeerB = network.create('peer-b');
const memberPeerC = network.create('peer-c');

2. Open Peer Mesh Nodes

Use openPeerMeshNode from packages/runtime-host/src/peer-mesh/node.js to initialize each participant. The function requires a persistent dataRoot, a transport client exposing useClock, and an endpointKind ('client' for authority, 'host' for members).

import { openPeerMeshNode } from '@maka/runtime-host/peer-mesh/node';
import { mkdtemp, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';

const root = await mkdtemp(join(tmpdir(), 'maka-peer-mesh-'));

const authority = await openPeerMeshNode({
  dataRoot: join(root, 'authority'),
  peer: authorityPeer,
  endpointKind: 'client',
});

const memberB = await openPeerMeshNode({
  dataRoot: join(root, 'member-b'),
  peer: memberPeerB,
  endpointKind: 'host',
});

const memberC = await openPeerMeshNode({
  dataRoot: join(root, 'member-c'),
  peer: memberPeerC,
  endpointKind: 'host',
});

3. Create the Mesh

The authority generates a unique mesh ID and signed roster by calling authority.create(). This utilizes generatePeerMeshAuthorityKeyPair and signPeerMeshRoster from packages/runtime-host/src/peer-mesh/model.js.

await authority.setDisplayName('Alice Desktop');
const mesh = await authority.create();
const meshId = mesh.roster.roster.meshId;
console.log('Mesh ID:', meshId);

4. Serve and Invite Members

Start the authority service with authority.serve() to accept control connections. Issue consumable invitations via authority.invite(meshId). Each invitation is single-use; the first successful member.join(invitation) consumes it, requiring fresh invitations for subsequent members.

const serving = authority.serve();

// First member
const invitation = await authority.invite(meshId);
await memberB.join(invitation);

// Second member requires new invitation
const secondInvite = await authority.invite(meshId);
await memberC.join(secondInvite);

5. Synchronize State

Call node.reconcile() to pull the latest signed roster and verify reachability leases. This enforces cryptographic signature validation and TTL checks defined in packages/runtime-host/src/peer-reachability/index.js.

await memberB.reconcile();
await memberC.reconcile();

Complete Runnable Example

The following implementation combines all steps using the in-memory transport, matching the validation logic in the official test suite:

import { mkdtemp, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { MemoryPeerNetwork } from '@maka/runtime-host/testing';
import { openPeerMeshNode } from '@maka/runtime-host/peer-mesh/node';

// Setup workspace and network
const root = await mkdtemp(join(tmpdir(), 'maka-peer-mesh-'));
const network = new MemoryPeerNetwork();
const [authorityPeer, memberPeerB, memberPeerC] = 
  ['peer-a', 'peer-b', 'peer-c'].map(id => network.create(id));

// Initialize nodes
const authority = await openPeerMeshNode({
  dataRoot: join(root, 'authority'),
  peer: authorityPeer,
  endpointKind: 'client',
});

const memberB = await openPeerMeshNode({
  dataRoot: join(root, 'member-b'),
  peer: memberPeerB,
  endpointKind: 'host',
});

const memberC = await openPeerMeshNode({
  dataRoot: join(root, 'member-c'),
  peer: memberPeerC,
  endpointKind: 'host',
});

// Create mesh
await authority.setDisplayName('Alice Desktop');
const mesh = await authority.create();
console.log('Mesh ID:', mesh.roster.roster.meshId);

// Serve and invite
const serving = authority.serve();
const invitation = await authority.invite(mesh.roster.roster.meshId);
await memberB.join(invitation);

const secondInvite = await authority.invite(mesh.roster.roster.meshId);
await memberC.join(secondInvite);

// Synchronize
await memberB.reconcile();
await memberC.reconcile();

// Cleanup
await Promise.all([
  authority.close(),
  memberB.close(),
  memberC.close(),
  serving,
  rm(root, { recursive: true, force: true })
]);

Managing the Mesh Lifecycle

After you set up Peer Mesh communication in Maka, use authority-only methods from packages/runtime-host/src/server/peer-mesh-authority.js to manage the deployment.

Rename the Mesh

Update the display name and propagate changes through reconciliation:

await authority.setMeshDisplayName(mesh.roster.roster.meshId, 'Release Team');
await memberB.reconcile();  // Member now sees updated name

Remove Members

Evict a specific peer by ID:

await authority.remove(mesh.roster.roster.meshId, 'peer-b');
await memberC.reconcile();  // Remaining members see updated roster

Close the Mesh

Permanently terminate the mesh, signaling all members:

await authority.closeMesh(mesh.roster.roster.meshId);
await authority.reconcile();
await memberC.reconcile();  // Member observes closed flag and exits

Security Architecture

The Peer Mesh security model relies on cryptographic signatures implemented in packages/runtime-host/src/peer-mesh/model.js. All roster updates and reachability leases are signed by the authority; members verify these signatures during reconcile(). The authority’s private key never appears on member nodes, ensuring a compromised member cannot forge mesh updates or impersonate the authority.

Persistence is handled by packages/runtime-host/src/peer-mesh/store.js, which detects corruption via PeerMeshPersistenceError and handles commit outcomes through PeerMeshPostCommitError.

Key Source Files Reference

Summary

  • Transport Layer: Implement PeerMeshTransport or use MemoryPeerNetwork for testing to enable inter-node communication.
  • Node Initialization: Call openPeerMeshNode() with dataRoot, transport client, and endpointKind to instantiate authority or member nodes.
  • Mesh Creation: Authority calls create() to generate cryptographically signed rosters and unique mesh IDs.
  • Member Onboarding: Issue single-use invitations via invite() and confirm with join(); each invitation supports exactly one member.
  • State Synchronization: Use reconcile() to enforce signed roster consistency and reachability lease validity across all nodes.
  • Lifecycle Management: Authority exclusively controls renaming, member removal, and mesh closure, with all changes signed and propagated through reconciliation.

Frequently Asked Questions

What transport implementation should I use for production Maka deployments?

For production, implement the PeerMeshTransport interface with a real network layer instead of MemoryPeerNetwork. The transport must support control messages and reachability lease exchanges as consumed by openPeerMeshNode. The in-memory implementation serves exclusively for unit testing in packages/runtime-host/src/__tests__/peer-mesh.test.ts.

Why do I need a new invitation for each member joining the mesh?

Invitations are consumable single-use tokens. When authority.invite() generates an invitation, it creates a signed reachability lease consumed by the first successful member.join() call. This design prevents replay attacks and ensures the authority maintains strict cryptographic control over mesh membership. Subsequent joins require fresh invitations.

How does Maka handle clock skew between authority and member nodes?

Clock skew is enforced in packages/runtime-host/src/peer-reachability/index.js during lease validation. Reachability leases include TTL and refresh lead times; reconcile() verifies these timestamps against the peer's clock. Significant clock divergence causes lease rejection, preventing stale or premature reachability claims.

Can I recover a mesh if the authority node loses its data?

No. The authority's private key (authorityPrivateKey) and mesh state are stored exclusively in the authority's dataRoot directory managed by packages/runtime-host/src/peer-mesh/store.js. Loss of this persistent storage without backup results in irrecoverable loss of mesh control, as the cryptographic keys required to sign new rosters cannot be regenerated.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →