- Rust 92.5%
- JavaScript 4.8%
- Shell 1.5%
- HTML 0.6%
- CSS 0.6%
|
|
||
|---|---|---|
| bin | ||
| crates | ||
| docs | ||
| plans | ||
| server-data/ferripfs | ||
| test-data | ||
| waggle_data/ferripfs | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| README.md | ||
| rustfmt.toml | ||
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_idare unauthenticated (see06-security-and-future.mdSection 12.6) - In-memory nonce cache: Nonce replay protection resets on server restart; no cross-instance synchronization
- In-memory known_recipients: Anti-enumeration
known_recipientsLRU 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