pds-message-poc#
interactive browser demo of PDS-to-PDS message passing.
demonstrates jacob.gold's proposal: PDSes have incoming message queues for DMs, like email servers.
run#
git submodule update --init
bun install
bun dev
usage#
- type a message, select sender โ recipient
- send - initiates message (first message creates a request)
- accept - recipient accepts pending request, messages flow freely
- reject - recipient rejects request and blocks sender
- spam - labeler marks sender as spam (rejected by all PDSes)
what's happening#
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ Bob's PDS โ โ Alice's PDS โ
โโโโโโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโโโโโค
โ โ 1. getServiceAuth(aud=alice)โ โ
โ send_message() โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ>โ โ
โ โ 2. JWT: iss=bob aud=alice โ inbox queue โ
โ โ <โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ
โ โ 3. POST /inbox + JWT โ โ
โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ>โ evaluate(): โ
โ โ โ - token valid? โ
โ โ โ - spam label? โ
โ โ โ - blocked? โ
โ โ โ - accepted? โ
โ โ โ - rate limit? โ
โ โ 4. {status: ...} โ โ
โ โ <โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ deliver/queueโ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโ
โ Labeler โ
โ (reputation) โ
โ spam labels โ
โโโโโโโโโโโโโโโโโ
invitation flow#
first contact requires acceptance (like DM requests):
- bob sends message to alice โ creates request (message held)
- alice sees request in her "requests" section
- alice clicks accept โ original message delivered, bob now accepted
- subsequent messages from bob deliver immediately (subject to rate limits)
alternatively:
- alice clicks reject โ request deleted, bob blocked permanently
what's demonstrated#
| feature | implementation | ATProto pattern |
|---|---|---|
| service auth | JWT with iss/aud/exp/lxm | com.atproto.server.getServiceAuth |
| invitation flow | pending/accepted sets | similar to chat.bsky.convo request status |
| reputation | labeler with spam labels | com.atproto.label |
| block list | per-user set | existing pattern |
| rate limiting | per-sender, time-windowed | existing pattern |
what's real#
uses pds.js crypto primitives via git submodule:
- P-256 key pairs - each simulated PDS generates real keys on startup
- ES256 JWT signatures - service auth tokens are cryptographically signed
- signature verification - recipient verifies JWT against sender's public key via WebCrypto
- proper JWT structure - iss, aud, lxm, exp, iat, jti fields
what's mocked#
| component | current | path to real |
|---|---|---|
| DID resolution | public key passed directly | resolve sender DID doc to get public key |
| DIDs | fake strings | PLC resolution |
| labeler | in-memory map | ozone |
| network | in-memory objects | actual HTTP between PDSes |
prior art#
- AT Protocol and SMTP - ngerakines on PDS as crypto service, SMTP as transport
- bourbon protocol - invitation-based messaging, combating spam
references#
- jacob.gold's thread
- pds.js - cloudflare workers PDS (crypto primitives used here)
- official PDS
- service auth
- AT Protocol specs