Skip to content

gdassori/micelio

Repository files navigation

Micelio

CI Coverage Status

A pure P2P system of standalone programs. No master, no slave, no coordinator. Nodes form a mesh, communicate via gossip, share an eventual-consistent distributed state, and are extensible through plugins. Every node exposes an SSH partyline for human interaction.

Named after fungal mycelium — a decentralized network where every hypha is equal, nutrients (messages/state) propagate organically, and the network grows and adapts.

Architecture

┌─────────────────────────────────────────────┐
│                  Node                       │
│                                             │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  │
│  │ SSH      │  │ Partyline│  │ State    │  │
│  │ Server   │──│ Hub      │──│ LWW Map  │  │
│  └──────────┘  └──────────┘  └──────────┘  │
│                      │                      │
│               ┌──────────┐                  │
│               │ Gossip   │                  │
│               └──────────┘                  │
│                    │                        │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  │
│  │ Transport│──│ Noise    │──│ Peer     │  │
│  │ Manager  │  │ Encrypt  │  │ Discovery│  │
│  └──────────┘  └──────────┘  └──────────┘  │
│                                             │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  │
│  │ Identity │  │ Store    │  │ Plugins  │  │
│  │ ED25519  │  │ bbolt    │  │ Registry │  │
│  └──────────┘  └──────────┘  └──────────┘  │
└─────────────────────────────────────────────┘

Stack

  • Language: Go
  • Serialization: Protocol Buffers
  • Transport: TCP + Noise Protocol Framework
  • Storage: bbolt (embedded B+ tree)
  • SSH: golang.org/x/crypto/ssh
  • Logging: log/slog (structured logging with text/json formats)
  • Build: Static binaries, zero external dependencies, CGO_ENABLED=0

Build

# Requires Go 1.26+
make build              # → bin/micelio

make release            # Cross-compile all targets:
                        #   bin/micelio-linux-amd64
                        #   bin/micelio-linux-arm64
                        #   bin/micelio-linux-386
                        #   bin/micelio-darwin-arm64

Run

# Start a node (generates identity on first run)
bin/micelio

# Override defaults via flags
bin/micelio -ssh-listen 127.0.0.1:2222 -name my-node -data-dir ~/.micelio

# Control log level
bin/micelio -log-level debug

# Connect two nodes
bin/micelio -name node-a -ssh-listen 127.0.0.1:2222 -config nodeA.toml
bin/micelio -name node-b -ssh-listen 127.0.0.1:2223 -config nodeB.toml

On first run, the node creates ~/.micelio/ with:

~/.micelio/
├── config.toml         # (optional) TOML configuration
├── identity/
│   ├── node.key        # ED25519 private key
│   └── node.pub        # ED25519 public key (OpenSSH format)
├── authorized_keys     # SSH public keys allowed to connect
└── data.db             # bbolt database

Connect

# Add your SSH key
cat ~/.ssh/id_ed25519.pub >> ~/.micelio/authorized_keys

# Connect to the partyline
ssh -p 2222 localhost

Configuration

[node]
name = "node-eu-1"
tags = ["EU", "prod"]
data_dir = "~/.micelio"

[ssh]
listen = "0.0.0.0:2222"

[network]
listen = "0.0.0.0:4000"
advertise_addr = "203.0.113.10:4000"  # explicit public address (optional)
bootstrap = [
    "seed1.example.com:4000",
    "seed2.example.com:4000"
]
max_peers = 15
exchange_interval = "30s"   # peer exchange period
discovery_interval = "10s"  # discovery scan period

[logging]
level = "info"    # debug, info, warn, warning, error (default: info)
format = "text"   # text or json (default: text)

# Connection health (hardcoded defaults, not yet configurable)
# idle_timeout = "60s"        # disconnect silent peers after this
# keepalive_interval = "20s"  # send keepalive when no real traffic

CLI flags take precedence over config file values. Available flags: -config, -name, -data-dir, -ssh-listen, -log-level.

Configuration Validation: All config values are validated at startup. Invalid addresses, negative numeric values, or unknown log levels will cause the node to exit with a clear error message identifying the problematic field.

Partyline Commands

Command Description
/who List connected users
/nick <name> Change nickname
/help Show available commands
/quit Disconnect

Project Structure

micelio/
├── cmd/micelio/           # Entry point
├── internal/
│   ├── config/            # TOML config + CLI flags
│   ├── crypto/            # ED25519→X25519 key conversion
│   ├── identity/          # ED25519 keypair, NodeID
│   ├── partyline/         # Chat hub (channel-based, zero mutexes)
│   ├── ssh/               # SSH server, terminal sessions
│   ├── store/             # Store interface + bbolt implementation
│   ├── gossip/            # Gossip engine (dedup, keyring, rate limiter, forwarding)
│   └── transport/         # Noise encryption, wire framing, peer management, discovery
├── pkg/proto/             # Generated protobuf Go code + sign/verify helpers
├── proto/                 # Protobuf definitions
├── docs/                  # Protocol documentation (MkDocs)
├── Makefile
└── go.mod

Roadmap

  • Phase 1 — Standalone node with SSH partyline
  • Phase 2 — Two nodes, direct connection (#1)
  • Phase 3 — Peer discovery and mesh formation (#2)
  • Phase 4 — Gossip protocol (#3)
  • Phase 5 — Distributed state map with LWW + Lamport clock (#4)
  • Phase 6 — Tagging and desired state (#5)
  • Phase 7 — Plugin system (#6)
  • Phase 8 — Access control: allowlist / denylist (#10)
  • Phase 9 — Web-of-trust (#11)
  • Phase 10 — Distributed hash table (#12)

Each phase produces a working, testable binary. Each phase adds a layer without rewriting the ones below.

License

MIT

About

A solid P2P network

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors