Closes #16
drop-federation
Friends Federation and Instance Peering plugin for the Drop game distribution platform.
Maintained by Heretek Games.
Overview
drop-federation brings Syncthing-style decentralized instance peering to Drop:
- Cryptographic identity: Ed25519 keypair, self-certifying instance ID, and Ed25519-signed
GET /descriptorrecords (docs/identity.md). - Cross-instance social: persisted friend requests with a
pending -> accepted | rejectedlifecycle (POST /friends/request,POST /friends/accept,POST /friends/reject,GET /friends). - Presence: presence records over the
federation:presenceWebSocket channel and persisted, freshness-filtered peer heartbeats (GET /peers). - Open Depot Protocol: signed catalog syndication (
GET /odp/catalog,POST /odp/subscribe) with signature verification, cross-instance discovery search (GET /odp/search), subscription provenance (GET /odp/subscriptions), and revocation (DELETE /odp/subscriptions/:instanceId). - Moderation & abuse controls: peer block list (
POST /friends/block,/unblock,GET /friends/blocked), immediate revocation (POST /friends/remove), and per-instance friend-request rate limiting. - Peer transport (direct + relay): descriptors advertise
endpoints(DROP_FEDERATION_ENDPOINTS);POST /peers/dialfetches and cryptographically verifies a peer's signed descriptor before recording it. When direct dialing fails andDROP_FEDERATION_RELAY_URLis set, a relay retransmits the descriptor (GET <relay>/relay/descriptor?target=...) — the relay can only censor, never forge, because the descriptor is verified end to end. - Key rotation:
POST /identity/rotate(operator-only viaDROP_FEDERATION_ADMIN_TOKEN) mints a new keypair and publishes a signed rotation certificate;GET /identity/rotationsexposes the verifiable old→new chain so pinned peers can follow the transition. - Opt-in library sharing:
POST /sharing(operator-only) sets a sharing scope (none/library/games);GET /shared/libraryreturns the currently-shared games and is empty by default or immediately after revocation. - WebRTC signaling relay:
POST/GET/DELETE /signaling/:instanceIdprovide a bounded, per-target mailbox for SDP offers/answers and ICE candidates (the relay never inspects the payload; peers connect via their own WebRTC stack).
Status
Implemented: the routes above, signed and tamper-checked descriptors (v2, with advertised endpoints), friend persistence, presence/peer tracking, optional encrypted-at-rest key storage, ODP catalog subscription + provenance-aware discovery search, moderation/rate limiting, direct peer dialing with descriptor verification, operator-driven key rotation with a verifiable chain, and opt-in library sharing scopes with immediate revocation. The threat model is documented in docs/security.md.
Not implemented yet: NAT traversal (the direct and relay transport paths exist, but hole-punching does not) (#4), direct or group messaging (#5), and remote save sharing / streaming a shared game (the sharing scopes and shared-library endpoint exist, but content transfer is not wired). There is no peer-to-peer messaging today.
Security
- Set
DROP_FEDERATION_KEY_PASSPHRASEto encrypt the instance private key at rest (AES-256-GCM keyed by scrypt). Without it the key is stored in plaintext and a warning is logged on every boot. See docs/security.md. - Descriptors use Ed25519 rather than the P-384 roadmap spec; rationale and migration path are in docs/identity.md.
Built on the @droposs/plugin-sdk.
Development
npm ci
npm run build
npm test
npm run typecheck