8.7 KiB
Network Security and Tokens
The genesis network has three orthogonal layers of cryptographic enforcement:
- Identity — every peer has a stable Ed25519 identity. Every message is signed.
- Authority — server-signed tokens grant a peer the right to do specific things in a specific mesh/session.
- Trust — cross-mesh interactions require a
MeshTrustTokenthat establishes one mesh's willingness to accept envelopes from another.
This document is the reference for all three.
Layer 1 — Message-level integrity (NET-27, NET-30)
network-plugin-crypto-messages is the layer.
Per-message Ed25519 signatures (NET-27)
Every outbound MessageEnvelope from a host (Tier 0 or Tier 1) carries an Ed25519 signature in its headers. Inbound signatures are verified using peer public keys from the registry. Invalid signatures cause the message to be dropped silently (and the sender's reputation in HostHistory to take a hit).
The key material is the same drive-identity key used by the chunks plugin — one Ed25519 keypair per peer, used at multiple layers. Generated and stored by @suaveplan/crypto-vault (BIP39 mnemonic + Argon2id KDF + zeroize on lock).
Peer identity challenge-response (NET-30)
When two peers handshake, they perform a challenge-response to verify identity:
A → B: peerA_pubkey, nonceA
B → A: peerB_pubkey, nonceB, sigB(peerA_pubkey ‖ nonceA)
A → B: sigA(peerB_pubkey ‖ nonceB)
Any peer claiming peerB_pubkey who can't produce sigB(...) is rejected. This catches spoofed peer-IDs at handshake before they make it into the registry.
Layer 2 — Authority tokens (NET-28, NET-29, NET-106..NET-109)
Three token shapes, all server-signed (in models with a server):
MeshToken (NET-29)
interface MeshToken {
meshId: string;
maxCapacity: number;
allowedTiers: ('tier-0' | 'tier-1' | 'tier-2')[];
hostingModel: 'PURE_CLIENT' | 'SERVER_BASED' | 'SERVER_TO_CLIENT_FAILOVER' | 'CLIENT_WITH_SERVER_BACKUP';
expiresAt: number;
serverSignature: Uint8Array; // Ed25519 over canonicalSerialize(this without the sig)
}
Required for mesh creation. The mesh's hosting model lives here. Long expiry (days/weeks).
SessionToken (NET-28)
interface SessionToken {
sessionId: string;
parentSessionId: string | null;
capacity: number;
rulesHash: string; // hash of the session's policy doc
expiresAt: number;
serverSignature: Uint8Array;
}
Required for session creation. Sessions can nest (NET-19) up to depth 4. The rulesHash pins the session's policy at issuance time so it can't be silently mutated.
CapabilityToken (NET-108, NET-109)
interface CapabilityToken {
peerId: string;
meshId: string;
tier: 'tier-0' | 'tier-1' | 'tier-2';
capabilities: string[]; // e.g. ['relay', 'vote', 'admit-peer']
issuedAt: number;
expiresAt: number;
serverSignature: Uint8Array;
}
Issued when a peer joins. The capabilities array constrains what the peer is authorised to do regardless of what the protocol allows it to attempt. A Tier-0 capability token includes admit-peer; a Tier-2 doesn't. Cross-tier escalation is blocked at the verifier (NET-48).
network-plugin-auth (NET-106..NET-109) is the enforcement plugin. MeshMembershipVerifier checks the authToken on join against @suaveplan/auth. CapabilityTokenIssuer mints them. CrossMeshTrustValidator (NET-110..NET-112) handles inter-mesh acceptance.
Tier-specific security policies (NET-48)
Tier 0 — full authority. Can issue tokens (when server isn't available, with grace-period restrictions).
Tier 1 — relay + voting authority. Cannot issue tokens.
Tier 2 — read-only for sensitive operations.
SecurityManager.processTierSecurity(tierId, operation, data) enforces this on every operation. Cross-tier delegation requires explicit credential transfer from the higher tier.
Layer 3 — Cross-mesh trust (NET-110..NET-112)
MeshTrustToken is what one mesh hands another mesh to say "I'll accept your relay traffic":
interface MeshTrustToken {
fromMeshId: string;
toMeshId: string;
allowedOperations: string[]; // e.g. ['relay-message', 'cd:request']
bandwidthQuotaPerHour?: number;
expiresAt: number;
bothServerSignatures: [Uint8Array, Uint8Array]; // signed by both meshes' Tier 0
}
CrossMeshTrustValidator rejects relay envelopes from untrusted mesh ids (NET-110). Tier 0 hosts verify trust tokens before accepting backbone connections (NET-112). Trust decisions are cached with configurable TTL (NET-111) so we don't re-verify on every envelope.
This means a phone-mesh and a corporate-mesh don't automatically interoperate. Two Tier 0 hosts must explicitly establish trust (out of band: typically via a co-signed token issued by both servers, or via a bilateral capability exchange in PURE_CLIENT mode).
Plugin security verifier (NET-47)
network-plugin-crypto-messages also validates plugins themselves:
class PluginSecurityVerifier {
verifyPlugin(pluginId: string, pluginData: Uint8Array): Promise<boolean>;
authorizePluginOperation(pluginId, operation, context?): Promise<boolean>;
monitorPluginActivity(pluginId): void;
setPluginSecurityPolicy(policy): void;
}
The intent is plugin-code signing: a deployment may want to allow only plugins signed by a known publisher key. Plugins requesting capabilities they didn't declare are rejected. Anomalous plugin activity (excessive broadcast, unauthorised operations) is detected and reported.
The old planning corpus admits (PHASE_6_README.md) that the resource-monitoring side of this is "currently simulated and would need real metrics in a production environment." Genesis treats it as a hardening backlog item — install the plugin, get signature verification today; resource accounting follows.
What about the model where the server is gone?
Tokens issued before the server vanished remain valid until their expiresAt. network-plugin-server-bridge (NET-32) extends grace periods so existing tokens don't expire mid-outage. New tokens cannot be issued — operations that require a fresh token (admit a brand-new peer, create a new session) are queued until the server returns. Existing peers, with valid CapabilityTokens, keep operating with full authority.
When the server returns:
- Buffered signed-log entries replay (NET-33).
- The server validates each entry's Ed25519 signature against the issuing peer's pubkey.
- Conflicts are detected (e.g., two peers both claimed Tier-0 in different partitions). Resolution depends on the partition merge strategy (NET-80).
- The server broadcasts the reconciled state.
- Queued token-issuance operations execute.
The cryptographic chain — every message signed, every token signed, every audit-log entry signed — is what makes this replay possible. There's no ambiguity about who did what; every action is provenance-stamped.
Audit log (NET-37..NET-39)
network-plugin-audit-mesh keeps an append-only log where each entry includes:
{ seq, prevHash, payload, hostSignature }
seqis monotonic.prevHashmakes the log a hash chain — break detection on any tampering.hostSignatureis the issuing host's Ed25519 over(seq, prevHash, payload).
Logs are replicated to at least R sibling hosts (NET-38). CRITICAL events replicate synchronously. Old logs are compacted into signed checkpoints (NET-39) — a snapshot at a given seq, signed by the host, that downstream replicas use to skip the prefix.
This is what gives you a verifiable audit trail across the entire mesh, surviving partitions and server outages.
Where keys live, end to end
| Key | Owner | Storage | Used for |
|---|---|---|---|
| Per-peer Ed25519 (drive identity) | The peer | @suaveplan/crypto-vault |
Signing every message, every chunk, every audit entry |
| Per-mesh server Ed25519 | Central server | Server HSM / @suaveplan/keys (when available) |
Signing MeshToken, SessionToken, CapabilityToken |
| Cross-mesh trust signing | Both meshes' servers | As above | Co-signing MeshTrustToken |
Per-file fileKey (AEAD) |
Drive | Wrapped by partition KEK; lives next to manifest | Encrypting chunks |
| Per-partition KEK | drive-sharing |
Wrapped per-grantee with X25519 sealed-box | Wrapping fileKeys |
Keys never cross trust boundaries unwrapped. Wrapping is the only mechanism for delegation.
Reading further
architecture.md—MessageEnvelopeandNetworkBus.topology-and-failover.md— when token issuance is paused.offline-and-reintegration.md— buffered log replay.../drive/encryption.md— the drive layer's use of the per-peer Ed25519 key.