-
Notifications
You must be signed in to change notification settings - Fork 0
Description
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_bifail 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
-
Core Daemon
- Key management (exclusive access)
- P2P connection lifecycle
- IPC server (Unix socket)
- Plugin loader/manager
-
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)?;
-
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-daemonuser, 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.wasmImplementation 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
- Security: Keys never leave daemon, clients have no crypto access
- Performance: Connection reuse, no repeated handshakes
- Scalability: One daemon serves many clients
- Extensibility: New protocols via plugins without recompiling
- User Experience: Auto-discovery of protocols, seamless communication
- Small Binary: Core daemon is minimal, protocols are plugins
Technical Decisions Needed
- IPC Protocol: JSON-RPC, gRPC, or custom binary?
- WASM Runtime: wasmtime vs wasmer vs wasm3?
- Plugin Distribution: Centralized registry vs P2P distribution?
- Plugin Signing: How to verify plugin authenticity?
- Resource Limits: CPU/memory limits for plugins?
Migration Path
- Current crate users continue working (deprecated)
- New daemon runs alongside for testing
- Gradual migration of protocols to plugins
- 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.