Skip to content

Latest commit

 

History

History
180 lines (140 loc) · 7.82 KB

running.md

File metadata and controls

180 lines (140 loc) · 7.82 KB

Running Ensemble

The daemon is one binary that runs in several shapes. Pick the one that matches where you're sitting. For every flag, see commands.md; for the build, setup.md.

Identity & recovery

Your node identity is a post-quantum keypair: a Dilithium (ML-DSA-65) identity key anchors your E… address, and a Dilithium-bound Ed25519 operational key handles fast per-message signing and the QUIC/TLS transport. Both derive deterministically from one 32-byte master seed.

On first run the daemon generates a seed automatically. To provision (and see) it up front:

ensemble init                  # generate a fresh identity, print the seed
ensemble init --seed <base64>  # recover an existing identity from its seed

Back up the printed master seed offline — it regenerates your full identity (same address, same keys) on any machine. Anyone holding it can impersonate you. It is separate from the web UI's admin seed (ensemble keygen), which only authenticates a browser to the daemon.

The four ways to run

# 1. Daemon + interactive TUI (the default).
ensemble

# 2. Headless daemon (no TUI) — servers, k8s, or when the web UI is the only frontend.
ensemble --headless

# 3. Attach a TUI to an already-running daemon (local socket by default).
ensemble attach

# 4. Attach over a remote TLS-fronted gRPC endpoint (reverse proxy with a real cert).
#    --auth-key is the seed file from `ensemble keygen`.
ensemble attach --addr ensemble.example.lan:443 --tls --auth-key admin.key

ensemble debug (same connection flags as attach) is the scriptable counterpart: it prints onion address, routing table, and live connections to stdout and exits.

Signaling backends

The signaling layer — the rendezvous channel two peers use to complete a contact handshake before swapping IPs and switching to direct QUIC — is pluggable. Choose at startup with --signaling=<name>. Default is tor.

--signaling=tor (default)

The headline configuration: every signaling connection rides a Tor hidden service, so peers' real IPs stay hidden from the network until they mutually agree to swap them.

  • Pick it for: any WAN / internet-facing deployment, anything where peer IPs are sensitive. It's the only backend with the privacy properties the project was built for.
  • Needs: a tor binary in $PATH or via --tor-path (Fedora: sudo dnf install tor). The daemon can also download the Tor Expert Bundle on first run, but that path is flaky today — package-manager Tor is the reliable route (setup.md → Tor bundle).
  • Costs: ~6–60s Tor bootstrap on every start (circuit setup, HSDir publish); hidden-service descriptors take their own time to propagate.

--signaling=loopback

Same-host rendezvous via Unix domain sockets in a shared directory. No Tor, no DHT — each registered service binds <dir>/<E-address>.sock and peers connect by name.

  • Pick it for: same-host dev/test. Iterating on the SDK examples, a a sample matchmaker/game demo, or the multi-daemon integration suite, where the ~60s Tor bootstrap tax per restart gets in the way.
  • Needs: Unix domain sockets (Unix-only — fails fast on Windows). Optional --loopback-dir <path>; default ${XDG_RUNTIME_DIR:-/tmp}/ensemble-loopback/. Tor is not started; --tor-path is warn-and-ignored.
  • Costs: no anonymity (sockets visible to other host processes; 0700 dir
    • 0600 socket give single-user isolation, no more), same-host only, and the built-in ui HTTP service is unsupported (chat + RPC work normally).
  • Boot time: ~60ms process-start to signaling-ready — three orders of magnitude faster than Tor.
# Two terminals, two daemons, same rendezvous dir.
ensemble --headless --signaling=loopback --data-dir /tmp/dev1 --api-addr 127.0.0.1:9090
ensemble --headless --signaling=loopback --data-dir /tmp/dev2 --api-addr 127.0.0.1:9091

--signaling=mdns

LAN-only rendezvous via mDNS / DNS-SD. Each service binds an ephemeral TCP port and advertises <E-address>._ensemble-svc._tcp.local. with a TXT record carrying eaddr=<E-address>. Peers on the same broadcast domain query the same record and dial the resolved host:port. No DHT, no Tor, no static peer config.

  • Pick it for: homelab / LAN where you control every device and want peers to find each other without Tor or a central rendezvous.
  • Needs: a multicast-capable network. The mDNS code is pure Go and does its own packet handling, so a system responder isn't strictly required. Cross-platform. Optional --mdns-iface <name> to pin one interface.
  • Security caveat — read this: the cryptographic trust model is unchanged (the handshake still authenticates by signature; an mDNS record is at best an untrusted routing hint, and an impostor can't complete a handshake without the target's private key), but the rendezvous is no longer anonymous — anyone on the broadcast domain can see which Ensemble addresses are present and which ports they listen on. Do not use --signaling=mdns on a network you don't trust. It's a different deployment shape, not a drop-in Tor replacement.
  • Costs: same-broadcast-domain only (does not cross routers), no anonymity, ui HTTP service unsupported, IPv4-first.

Verify advertisements with standard tools:

avahi-browse -prt _ensemble-svc._tcp     # Linux (avahi-utils)
dns-sd -B _ensemble-svc._tcp             # macOS

Web UI

The daemon ships an embedded Solid.js SPA. Three ways to reach it — pick by where the user is sitting:

Where URL Setup
Same machine https://127.0.0.1:9102 --ui-local-https, then make trust-local-ca once
Same LAN, dev http://<host>:9101 --ui-addr 0.0.0.0:9101 --unsafe-plaintext-ui (plain HTTP — trusted LAN only)
Phone / remote https://<ui-onion> in Tor Browser nothing extra — the ui service publishes its own onion at daemon start

The SPA signs each gRPC-Web request with your Ed25519 admin seed (the same seed ensemble keygen produces and --admin-key validates), so the same auth that protects the gRPC endpoints protects the browser. Full SPA story — enrolment, mobile/Tor Browser, local-HTTPS cert lifecycle, CSP, hot-reload — in ../ui/README.md.

Raspberry Pi / ARM

ARM cross-builds are pure Go (no cgo) and run an external system Tor — the in-process embedded Tor needs cgo and a native build (build natively on the Pi if you want it; cgo just works there).

# On Raspberry Pi OS / Debian / Ubuntu
sudo apt install tor
./ensemble --headless --tor-path /usr/bin/tor \
    --api-addr 127.0.0.1:9099 --admin-key <hex>

Forget --tor-path and you get a tailored error pointing here, not a generic "unsupported platform". LAN-only Pi setups can skip Tor entirely with --signaling=mdns — a natural fit for a home network that sidesteps the Tor bootstrap latency.

Metrics

Metrics are off by default — they're traffic metadata on a privacy app, so nothing is collected at the source until you opt in.

ensemble --metrics                              # enable the subsystem (UI diagnostics light up)
ensemble --metrics --metrics-listen 127.0.0.1:9100   # also expose Prometheus text at /metrics

The --metrics-listen endpoint has no auth or TLS, so a non-loopback bind is refused unless --trust-proxy-tls asserts a terminator/allowlist in front — and verify that gating from an off-LAN vantage; ingress allowlists are easy to get wrong. Rationale in ADR-0005.

Hosting services

A running daemon can install, supervise, and host other services (chat bots, game matchmakers, group-room hosts, registries). That whole story — the platform model, the SDKs, and the flagship services — is in services.md.