94 lines
3.8 KiB
Markdown
94 lines
3.8 KiB
Markdown
|
|
# redoal integration sketch
|
||
|
|
|
||
|
|
How a gesture-derived discovery provider plugs into varde without
|
||
|
|
touching the daemon. Nothing here is implemented; this documents the
|
||
|
|
contract the v1 seam already enforces.
|
||
|
|
|
||
|
|
## The seam
|
||
|
|
|
||
|
|
`varde_daemon::discovery` defines:
|
||
|
|
|
||
|
|
```rust
|
||
|
|
pub trait DiscoveryProvider: Send + Sync {
|
||
|
|
fn subscribe(&self, topic: TopicKey) -> BoxStream<SignedAnnouncement>;
|
||
|
|
fn announce(&self, topic: TopicKey, ann: SignedAnnouncement) -> Result<()>;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
- `TopicKey` is an opaque 32-byte channel id.
|
||
|
|
- `Announcement { root, author, meta, providers }` is signed (ed25519,
|
||
|
|
the same key type as iroh NodeIds) over a deterministic postcard
|
||
|
|
encoding that *includes the topic*, so announcements can't be replayed
|
||
|
|
across channels. Provider socket addresses are excluded from the
|
||
|
|
signature (relays may refresh them); provider *identities* are covered.
|
||
|
|
|
||
|
|
The daemon consumes any provider identically (`Daemon::on_announcement`):
|
||
|
|
|
||
|
|
1. verify the signature — drop on failure;
|
||
|
|
2. index the announcement (all of them — discovery is the open tier);
|
||
|
|
3. auto-fetch only when **all** of these hold:
|
||
|
|
- the author key is trusted (or is the local daemon),
|
||
|
|
- the root is already pinned locally and incomplete,
|
||
|
|
- at least one announced provider is on the peer allowlist.
|
||
|
|
|
||
|
|
v1 ships one implementation, `LanDiscovery`: mDNS sightings are turned
|
||
|
|
into locally-authored announcements ("peer N may hold pinned root R").
|
||
|
|
It proves the seam because the daemon's entire auto-sync path runs
|
||
|
|
through `subscribe()` — swap the provider and nothing above changes.
|
||
|
|
|
||
|
|
## The redoal provider (future)
|
||
|
|
|
||
|
|
redoal turns a shared physical gesture (two phones shaken together, a
|
||
|
|
tap pattern, ...) into a high-entropy shared secret between the people
|
||
|
|
present. That secret derives a gossip topic:
|
||
|
|
|
||
|
|
```
|
||
|
|
TopicKey = BLAKE3-derive_key("redoal/v1/topic", gesture_secret)
|
||
|
|
```
|
||
|
|
|
||
|
|
`RedoalDiscovery` would:
|
||
|
|
|
||
|
|
- join the iroh-gossip swarm for that TopicId (iroh-gossip rides the
|
||
|
|
same iroh endpoint varde already has — no new transport);
|
||
|
|
- `subscribe(topic)`: yield gossip messages decoded as
|
||
|
|
`SignedAnnouncement`s. Verification and consent stay in the daemon —
|
||
|
|
the provider is a dumb pipe by design;
|
||
|
|
- `announce(topic, ann)`: broadcast to the swarm. Unlike the LAN
|
||
|
|
provider (where announce is a no-op because mDNS already advertises
|
||
|
|
presence), gossip announce actively publishes — the daemon must only
|
||
|
|
call it for content the user shared to that topic.
|
||
|
|
|
||
|
|
### Trust bootstrap
|
||
|
|
|
||
|
|
The gesture is the consent ceremony. Deriving from the same secret:
|
||
|
|
|
||
|
|
```
|
||
|
|
author trust: the gesture exchange includes both parties' public keys
|
||
|
|
(signed with the gesture key), so each side adds the
|
||
|
|
other to the *author* allowlist for that topic.
|
||
|
|
peer trust: announcements carry provider NodeIds; on a gestured
|
||
|
|
topic, providers named by a trusted author get scoped
|
||
|
|
peer trust (serve/fetch for that topic's roots only).
|
||
|
|
```
|
||
|
|
|
||
|
|
That last point needs one extension to the v1 model: today peer trust
|
||
|
|
is global (`meta.json` allowlist). Topic-scoped trust would add
|
||
|
|
`trusted_for: {topic → keys}`, checked in the same two places the
|
||
|
|
global list is checked now (provider accept gate, fetch candidate
|
||
|
|
filter). The seam anticipates this: both checks already live in the
|
||
|
|
daemon, not in the provider.
|
||
|
|
|
||
|
|
### What stays true regardless of provider
|
||
|
|
|
||
|
|
- Discovery open, replication explicit: indexing an announcement never
|
||
|
|
moves bytes; only the trust checks above do.
|
||
|
|
- All fetched data is BLAKE3-verified by iroh-blobs.
|
||
|
|
- Metered/rate-limit posture applies unchanged — providers sit above
|
||
|
|
the transport, the limiters below it.
|
||
|
|
|
||
|
|
## Sizing
|
||
|
|
|
||
|
|
`RedoalDiscovery` is roughly: iroh-gossip dependency, ~200 lines of
|
||
|
|
provider glue, the topic-scoped trust extension in `meta.json`, and a
|
||
|
|
`varde-ctl topic join <secret>` command. No daemon architecture changes.
|