Skip to content

Architectural Redesign: Daemon-based P2P with WASM Protocol Plugins #6

@amitu

Description

@amitu
original prompt

our fastn-p2p currently is a crate, that rust programs that want to build p2p stuff want to use. but this has a few problems: keys are liberally shared: each client also need secret key, and clients have acceptbi etc features, which means clients can act like server, and if two cli instances are there, both calling acceptbi it wont work, so our design is all wrong. we also have performance issue, so each cli instance using our crate will have to create p2p connection, which takes a bit of time ~100s of ms, and so we can create a background daemon, which can open and keep the connections, and let client connect with the daemon over some sort of tcp or unix domain socket, so none of the clis need secret keys, only access to unix domain socket, and daemon can run as some other user, that has access to secret keys, making it hard to access secret keys.

now fastn-p2p users can be either clients or server, and for client the control server and IPC over unix socket makes sense, but for server, especially since each server in p2p kind of acts like a protocol, so like we have mail server, and ssh server, and soon file server and media server, but they also are full protocol implementations, like mail server handles email delivery, but also storage of email in some folder and sqlite file etc. similarly ssh etc, they are not just server, but protocol, as they expose well define apis, and any client following same protocol can access the same set of few protocol implementations, this allows us to have few protocols but many apps, like for any kind of email client you need mail protocol stuff.

so we want protocol handlers to be available to users, but we can not ship all protocol code as part of our binary, so we need plugin mechanism, so we will have some sort of global plugin repo, maybe just a folder containing wasm files, and all protocol handlers are written / shipped as wasm code, so end users can load untested protocol handlers, as they will each run in a security sandbox, so our main binary is small and yet end users get rich functionality without installing configuring as if I send a chat message to a peer who does not have chat related plugin installed, our system can auto install the chat protocol plugin, and when the peer comes online they can, be notified they have received some chat protocol data, and offer user to install of the compatible app registered against this protocol to start doing chat.

Problem Statement

The current fastn-p2p crate design has critical architectural issues:

Security Issues

  • Secret key exposure: Every client application needs direct access to secret keys
  • No privilege separation: CLI instances run with full cryptographic material access
  • Shared key vulnerability: Keys are liberally shared across multiple processes

Concurrency Issues

  • Port conflicts: Multiple CLI instances calling accept_bi fail due to port binding conflicts
  • Resource contention: Each client acts as both client and server, causing resource conflicts

Performance Issues

  • Connection overhead: Each CLI instance creates new P2P connections (~100ms overhead)
  • No connection pooling: Connections not reused across CLI invocations
  • Redundant handshakes: Every command performs full P2P handshake

Proposed Solution

1. Daemon Architecture

┌─────────────┐     Unix Socket    ┌─────────────┐      P2P      ┌─────────────┐
│  CLI/Apps   │◄──────────────────►│   Daemon    │◄─────────────►│   Peers     │
│ (No Keys)   │        IPC         │ (Has Keys)  │    Network    │             │
└─────────────┘                    └─────────────┘               └─────────────┘

Benefits:

  • Daemon runs as privileged user with key access
  • Clients connect via Unix domain socket (no keys needed)
  • Single daemon manages all P2P connections
  • Connection pooling and reuse
  • No port conflicts

2. Protocol Plugin System (WASM)

Instead of monolithic binary with all protocols:

fastn-daemon
    ├── core (small, secure)
    └── plugins/
        ├── mail.wasm    (email protocol)
        ├── ssh.wasm     (SSH protocol)  
        ├── chat.wasm    (chat protocol)
        └── files.wasm   (file sharing)

Protocol Handler Design:

  • Each protocol is a complete implementation (not just server)
  • Protocols handle both networking AND storage/business logic
  • Example: Mail protocol handles SMTP/IMAP + email storage in SQLite
  • Sandboxed WASM execution for security

3. Auto-Discovery & Installation

// When receiving unknown protocol data
if !protocol_installed("chat/v1") {
    // Auto-download and install chat.wasm
    daemon.install_protocol("chat/v1").await?;
    // Notify user about new protocol
    notify_user("Chat messages received. Install chat app?");
}

Architecture Details

Daemon Components

  1. Core Daemon

    • Key management (exclusive access)
    • P2P connection lifecycle
    • IPC server (Unix socket)
    • Plugin loader/manager
  2. IPC Protocol

    // Client never touches keys
    client.send_to_peer(peer_id, protocol_id, data)?;
    
    // Daemon handles all crypto
    daemon.sign_and_send(peer_id, data)?;
  3. Plugin API

    trait ProtocolHandler {
        fn handle_message(&self, from: PeerId, data: &[u8]);
        fn get_protocol_id(&self) -> &str;
        fn get_capabilities(&self) -> Vec<Capability>;
    }

Security Model

  • Daemon: Runs as fastn-daemon user, owns secret keys
  • Clients: Connect via Unix socket, no key access
  • Plugins: WASM sandbox, no filesystem/network access except via API
  • IPC: Unix socket permissions control access

Plugin Distribution

# Global plugin registry
~/.fastn/plugins/
  manifest.toml        # Plugin metadata
  mail-v1.0.0.wasm    # Email protocol
  chat-v2.1.0.wasm    # Chat protocol
  
# Auto-download from registry
https://plugins.fastn.io/
  /protocols/mail/latest.wasm
  /protocols/chat/latest.wasm

Implementation Phases

Phase 1: Daemon Foundation

  • Extract daemon from current crate
  • Implement Unix socket IPC
  • Move key management to daemon
  • Basic client library for IPC

Phase 2: Connection Management

  • Connection pooling in daemon
  • Persistent connections across CLI calls
  • Multi-tenant connection handling
  • Performance optimizations

Phase 3: Plugin System

  • WASM runtime integration (wasmtime/wasmer)
  • Plugin API definition
  • Plugin loader/manager
  • Sandbox security boundaries

Phase 4: Protocol Implementations

  • Port existing protocols to plugins
  • Mail protocol plugin
  • Chat protocol plugin
  • File sharing plugin

Phase 5: Auto-Discovery

  • Protocol negotiation
  • Auto-installation mechanism
  • User consent/notification system
  • Plugin registry/marketplace

Benefits

  1. Security: Keys never leave daemon, clients have no crypto access
  2. Performance: Connection reuse, no repeated handshakes
  3. Scalability: One daemon serves many clients
  4. Extensibility: New protocols via plugins without recompiling
  5. User Experience: Auto-discovery of protocols, seamless communication
  6. Small Binary: Core daemon is minimal, protocols are plugins

Technical Decisions Needed

  1. IPC Protocol: JSON-RPC, gRPC, or custom binary?
  2. WASM Runtime: wasmtime vs wasmer vs wasm3?
  3. Plugin Distribution: Centralized registry vs P2P distribution?
  4. Plugin Signing: How to verify plugin authenticity?
  5. Resource Limits: CPU/memory limits for plugins?

Migration Path

  1. Current crate users continue working (deprecated)
  2. New daemon runs alongside for testing
  3. Gradual migration of protocols to plugins
  4. Deprecation timeline for direct crate usage

Related Work

  • IPFS daemon architecture
  • Browser extension model (sandboxed plugins)
  • Docker daemon/client split
  • SystemD socket activation

This redesign fundamentally improves security, performance, and extensibility while enabling a rich ecosystem of P2P protocols without bloating the core binary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions