A server that works well with Automerge and KeyHive
  • Rust 92.5%
  • JavaScript 4.8%
  • Shell 1.5%
  • HTML 0.6%
  • CSS 0.6%
Find a file
David Pollak f09131c679
WIP phase 5 complete
Signed-off-by: David Pollak <feeder.of.the.bears@gmail.com>
2026-05-09 17:43:23 -04:00
bin WIP phase 5 complete 2026-05-09 17:43:23 -04:00
crates WIP phase 5 complete 2026-05-09 17:43:23 -04:00
docs WIP phase 5 complete 2026-05-09 17:43:23 -04:00
plans WIP phase 5 complete 2026-05-09 17:43:23 -04:00
server-data/ferripfs WIP Phase 2 2026-05-03 12:35:59 -04:00
test-data WIP Phase 2 2026-05-03 12:35:59 -04:00
waggle_data/ferripfs WIP Phase 2 2026-05-03 12:35:59 -04:00
.gitignore WIP Phase 2 2026-05-03 12:35:59 -04:00
Cargo.lock WIP Phase 2 2026-05-03 12:35:59 -04:00
Cargo.toml WIP in only using KeyHive for cryptography 2026-05-01 15:33:48 -04:00
README.md WIP in only using KeyHive for cryptography 2026-05-01 15:33:48 -04:00
rustfmt.toml mailbox 2026-02-28 16:22:40 -05:00

Waggle

Blind proxy relay for local-first collaborative applications using Beelay encrypted envelopes. Waggle provides store-and-forward mailbox delivery, content-addressed blob storage, and real-time WebSocket notifications — all without the ability to read, forge, or tamper with the encrypted payloads it relays.

Project Status

Phase 2 complete — v0.2.0, 179 tests passing, clippy clean.

Phase 1 delivered the proxy server foundation: Ed25519 request authentication, SQLite mailbox, ferripfs-backed blob storage, WebSocket notifications, CORS, and per-sender rate limiting.

Phase 2 adds IPFS networking: DHT content discovery, Bitswap block exchange between ferripfs nodes, network-aware cat() with timeout fallback, remote pinning via HTTP API, and garbage collection.

Workspace Crates

Crate Purpose Tests
waggle-auth Ed25519 request signing, verification, nonce replay, Axum middleware 39
waggle-mailbox SQLite store-and-forward mailbox with FIFO drain and TTL purge 44
waggle-blob Content-addressed blob storage via ferripfs (CIDv1/SHA2-256) 32
waggle-proxy Axum HTTP handlers, CORS, rate limiting, WebSocket notifications 64

Quick Start

git clone <repo-url>
cd waggle
cargo test
# Expect: 179 tests passing across 4 crates

Requires Rust 1.75+ (see rust-version in Cargo.toml).

Key Capabilities (with test evidence)

Capability Verified By
Ed25519 request signing and verification test_sign_verify_round_trip (waggle-auth)
SQLite mailbox stores and retrieves messages in FIFO order test_enqueue_returns_id, test_drain_returns_fifo_order (waggle-mailbox)
CIDv1/SHA2-256 content-addressed blob storage test_cid_is_v1_sha256 (waggle-blob)
Real-time WebSocket notifications on mailbox enqueue test_ws_connect_and_receive_heartbeat, test_ws_notification_on_mailbox_enqueue (waggle-proxy)
CORS enforcement with explicit origin allowlist test_cors_preflight_returns_allowed_headers (waggle-proxy)
Per-sender sliding-window rate limiting test_rate_limit_per_sender (waggle-proxy)
Network fetch timeout returns 504 Gateway Timeout test_get_blob_timeout_returns_504 (waggle-proxy)
Remote pinning via IPFS Pinning Service API test_pin_remote_returns_202_when_configured (waggle-proxy)

Documentation

Document Audience
Architecture Contributors, reviewers
API Reference Client developers, integrators
Security Model Security reviewers, operators
Getting Started New developers

Each crate also has its own README in crates/<name>/README.md.

Cryptographic Architecture

All Automerge document, diff, and fragment encryption and decryption is handled EXCLUSIVELY by KeyHive. Waggle uses PQC algorithms for digitally signing items, AES for encrypting blobs stored in IPFS (the AES key is stored in the Automerge document), but ALL OTHER encryption, decryption, key exchange, invitations, etc. is handled EXCLUSIVELY by KeyHive.

Design Specifications

The specification documents describing what should be built live at the repository root:

File Covers
README.md Project overview and vision
01-proxy-server.md Blind proxy server design
02-ferripfs.md ferripfs embedded library API
03-browser-client.md WASM + native browser client
04-testing.md Testing specification
05-build-and-phasing.md Build system and implementation phases
06-security-and-future.md Security model and future directions

These are design specs, not implementation docs. For what was actually built and verified by tests, see the docs/ directory.

v0.2 Capabilities (Phase 2)

  • Network-aware cat(): Blob GET attempts local blockstore first, then fetches from IPFS network via Bitswap with configurable timeout
  • Remote pinning: POST /v1/blob/:cid/pin/remote returns 202 when configured (connects to IPFS Pinning Service API)
  • Fetch timeout: Network fetch failures return 504 Gateway Timeout instead of hanging

Current Limitations

  • No streaming: Blobs are buffered in memory (not streamed to/from ferripfs)
  • No WebSocket authentication: WS connections at /v1/notify/:identity_id are unauthenticated (see 06-security-and-future.md Section 12.6)
  • In-memory nonce cache: Nonce replay protection resets on server restart; no cross-instance synchronization
  • In-memory known_recipients: Anti-enumeration known_recipients LRU cache (bounded, default 100,000 entries) resets on server restart, temporarily allowing mailbox existence probing until the first message is sent to each recipient. Evicted recipients temporarily get 403 until their next message. — test_known_recipients_evicts_oldest, test_known_recipients_anti_enumeration_preserved

License

MIT OR Apache-2.0