An easy-to-host PDS on the ATProtocol, iPhone and MacOS. Maintain control of your keys and data, always.
1# Desktop PDS — System Architecture
2
3**v8 — Mobile-First Reconciliation · Four-Phase Milestones**
4
5Sovereign AT Protocol PDS on macOS via Tauri + Repo Engine + Iroh
6
7## Milestone Legend
8
9**v0.1** — Mobile-Only PDS · relay is full PDS
10
11**v0.2** — Desktop Enrollment · relay as proxy+signer
12
13**v1.0** — Public Launch · product-ready
14
15**LATER** — Designed, built post-launch
16
17---
18
19## Changelog
20
21### v8 Changes — Mobile-First Reconciliation
22
23Architecture reconciled with mobile architecture spec v1.2 (canonical). The relay is no longer just a tunnel+proxy — in the mobile-only phase, it IS the PDS.
24
25- **NEW** Four-phase milestone model (v0.1 / v0.2 / v1.0 / v2.0+)
26- **NEW** Phase 0: Mobile-Only lifecycle (relay as full PDS)
27- **FIX** Signing model: relay always signs, device constructs unsigned commits
28- **FIX** Tier model: Free/Pro/Business + BYO as deployment model
29- **FIX** Firehose: native emission (mobile-only) vs proxy (desktop-enrolled)
30- **FIX** Shamir: basic share generation moves to v0.1 (required at onboarding)
31- **FIX** DID keystore: Shamir split required at account creation, not v1.0
32- **REF** See unified-milestone-map.md for phase details
33
34### Previous Versions
35
36v2: Corrected relay model (outbound only). v3: Shamir key recovery + repo snapshots. v4: Conformance strategy. v5: Custom PDS shell + atrium/rsky deps. v6: GeoDNS + BYO relay. v7: Milestone scoping + runtime threats.
37
38---
39
40## Device Lifecycle Phases
41
42The product launches mobile-first. The relay is a full PDS before any desktop is involved.
43
44**Phase: Mobile-Only (v0.1)**
45- Relay behavior: Full PDS — hosts repo, serves XRPC, signs commits, emits firehose
46- Repo location: Relay (primary and only copy)
47- Phone role: Identity wallet (key management, device admin)
48- Desktop: Does not exist yet
49
50**Phase: Desktop-Enrolled (v0.2)**
51- Relay behavior: XRPC proxy + signer — forwards writes to desktop, signs commits, serves reads from cache
52- Repo location: Desktop (primary), relay (cache)
53- Phone role: Identity wallet + device manager
54- Desktop: Runs repo engine, constructs unsigned commits
55
56**Phase: Desktop-Offline (v0.2+)**
57- Relay behavior: Serves reads from cache, 503 on writes
58- Repo location: Desktop (authoritative but unreachable)
59- Phone role: Same as desktop-enrolled
60- Desktop: Sleeping / powered off
61
62---
63
64## Layer 01 — Device Layer (Desktop, v0.2+)
65
66*In v0.1 (Mobile-Only), there is no device layer. All operations run on the relay.*
67
68### Tauri Shell
69
70**v0.2**
71
72🖥️ Native macOS app. Process lifecycle, auto-updates, system tray. Minimal IPC allowlist — webview cannot access filesystem, shell, or network directly.
73
74### Repo Engine
75
76**v0.2**
77
78📦 Purpose-built repo construction engine. SQLite-backed, local-first. Builds MST structures, constructs unsigned commits, manages collection storage. In desktop-enrolled mode, the relay proxies XRPC writes here, then signs the resulting commits. Does not serve XRPC directly to the network — the relay is always the network-facing endpoint.
79
80### Dependency Stack
81
82**v0.1**
83
84🧩 **atrium-api** — XRPC types, lexicon defs (auto-generated). **atrium-repo** — MST read/write, CAR export. **rsky-crypto** — P-256/K-256 commit signing.
85
86### Iroh Endpoint
87
88**v0.1**
89
90🔗 QUIC-based tunnel to relay. NAT traversal, connection resumption on wake. Pushes unsigned repo commits to relay for signing when online.
91
92### DID Keystore
93
94**v0.1**
95
96🔐 Signing keys in macOS Keychain (desktop) / Secure Enclave (phone). At account creation, root rotation key is split via 2-of-3 Shamir: Share 1 = iCloud Keychain, Share 2 = relay escrow, Share 3 = user's choice (device-local or BIP-39 paper backup). Basic key management for v0.1. Full recovery UI in v1.0.
97
98### Recovery Share Manager
99
100**v1.0**
101
102🛟 Full UI for Shamir share management and recovery ceremony. View share status, rotate shares, initiate recovery from device loss. Note: basic share GENERATION happens at v0.1 (during account creation). This component adds the management and recovery interface.
103
104### Compat Warning Banner
105
106**v1.0**
107
108⚠️ Non-blocking in-app warning when spec drift detected. Links to update. Never blocks launch.
109
110### XRPC Hardening
111
112**v1.0**
113
114🛡️ Request size limits on all endpoints. Rate limiting at relay. cargo-fuzz targets for CBOR/CAR/MST parsing paths. Adversarial MST key distribution testing per ATProto spec guidance.
115
116*REMOVED: rsky-pds (fork) — Replaced by repo engine in v5. Now tracking a spec, not a codebase.*
117
118---
119
120## Layer 02 — Relay Layer (Managed + BYO)
121
122### Managed Relay (Your Infrastructure)
123
124#### Iroh Relay Node
125
126**v0.1**
127
128🚇 Single-region for v0.1. Always-on tunnel endpoint. In mobile-only mode, serves as full PDS — no tunnel needed, relay handles all XRPC directly. In desktop-enrolled mode, acts as tunnel endpoint for device ↔ relay communication. Receives unsigned commits from device, constructs signed commits, proxies XRPC repo reads.
129
130#### requestCrawl Trigger
131
132**v0.1**
133
134📣 On device reconnect, pings BGS requestCrawl so new content propagates immediately.
135
136#### Firehose Emitter
137
138**v0.1**
139
140📡 Native com.atproto.sync.subscribeRepos WebSocket endpoint. Required for federation — every PDS must emit a firehose. In mobile-only mode, the relay is the PDS and emits directly. In desktop-enrolled mode, emits commits as they're signed.
141
142#### Firehose Proxy
143
144**v0.2**
145
146📡 Maintains persistent BGS WebSocket on behalf of sleeping desktop. Replays commits from buffer when desktop reconnects. Ensures BGS sees continuous uptime even when desktop is offline. Desktop-enrolled feature — not applicable in mobile-only mode. Pro/Business tier on managed relay.
147
148#### Commit Buffer
149
150**v0.2**
151
152💾 Rolling log of signed repo commits. Feeds firehose proxy during offline. Tiered retention: 7d free, 30d paid, 90d business.
153
154#### Provisioning API
155
156**v0.1**
157
158⚙️ Account setup, domain linking, relay config. Onboarding flow for new connections. Core provisioning needed from day one.
159
160#### Key Share Escrow
161
162**v0.1**
163
164🔏 Holds one encrypted Shamir share. Cannot reconstruct alone. Encrypted at rest, access-logged. Relay holds Share 2 from account creation.
165
166#### Health Monitor
167
168**v1.0**
169
170💓 Device liveness, relay uptime, ATProto spec compat. Includes canary account for silent federation failure detection.
171
172#### GeoDNS Multi-Region
173
174**LATER**
175
176🌎 2–3 relay nodes, route to nearest healthy. Simple failover with brief firehose gap. Cross-region replication interface designed but not built.
177
178#### Repo Snapshot
179
180**LATER**
181
182🗄️ Full repo backup on relay. Incremental from commit buffer. Pro+ feature. Enables one-click device migration.
183
184#### CDN / Public Cache
185
186**LATER**
187
188🌐 Serves public repo content during offline windows.
189
190### BYO Relay (User-Hosted, Free)
191
192#### Relay Binary
193
194**v1.0**
195
196📦 Open-source. Nix flake (source of truth) → Docker image + NixOS module. Tunnel + commit forwarding + requestCrawl. No firehose proxy, no snapshots.
197
198#### Device-Relay Protocol Spec
199
200**v1.0**
201
202📜 Documented contract: handshake/auth, commit push, health ping, optional feature negotiation. Includes commit ack for future trust verification.
203
204#### Feature Negotiation
205
206**v1.0**
207
208🔌 App queries relay capabilities on connect. Gracefully degrades when extended features unavailable. Suggests upgrade for missing features.
209
210*REMOVED: Inbound Message Queue — Not needed. ATProto records live in author's repo.*
211
212---
213
214## Data Flow
215
216### Desktop-Enrolled Write Path
217
2181. App creates record via XRPC (Tauri webview → Rust backend)
2192. Repo Engine constructs MST diff + unsigned commit
2203. Unsigned commit sent to relay via Iroh tunnel
2214. Relay signs commit with P-256 signing key
2225. Relay stores signed commit in buffer
2236. Relay emits to firehose / serves via XRPC
224
225### Mobile-Only Write Path (v0.1)
226
2271. Third-party app (e.g. Bluesky) calls relay XRPC directly
2282. Relay constructs record, MST diff, signs commit
2293. Relay stores and emits to firehose
230
231### Desktop-Offline Read Path
232
2331. XRPC read request hits relay
2342. Relay serves from commit buffer / repo cache
2353. Writes return 503 (relay cannot construct commits from stale state)
236
237---
238
239## Data Flow — How Bob's Post Reaches the Network
240
241*Current scenario showing firehose proxy operation during v0.2+:*
242
243**Bob's Mac** (Repo Engine constructs unsigned commit) → **Iroh tunnel** → **Relay** (Signs commit with P-256 key) → **Commit Buffer** (Persists signed commit) → **Firehose Proxy** (Stable WebSocket) → **subscribeRepos** → **BGS** (Network firehose) → **indexes** → **AppView** (Bluesky etc.)
244
245*If Bob's Mac is asleep → relay serves reads from cache, returns 503 on writes. Commit buffer feeds firehose proxy from stored commits on wake.*
246
247---
248
249## Recovery Flow — Device Migration / Dead SSD (v1.0+)
250
251**New Mac** (Installs Tauri app) → **authenticates** → **2-of-3 Shares** (iCloud + relay escrow) → **reconstructs** → **Rotation Key** (Shamir recombination) → **did:plc op** → **Key Rotation** (New signing key) → **syncs** → **Repo Snapshot** (Full repo restore)
252
253**Share sources (any 2 of 3):**
254- ① iCloud Keychain
255- ② Relay escrow
256- ③ Exported recovery file
257- Future: ④ Trusted contact (social recovery) — interface designed, not yet shipped
258
259---
260
261## Layer 03 — Infrastructure (ATProto Network)
262
263### Federation
264
265**v0.1**
266
267🌍 PDS participates in ATProto network via relay. DID document points to relay URL as canonical PDS endpoint.
268
269### DNS / Domain Automation
270
271**v1.0**
272
273🔤 Handle-as-domain resolution. Automated DNS config for custom domain handles.
274
275### DID Resolution
276
277**v0.1**
278
279🪪 did:plc or did:web pointing to relay endpoint. Relay always reachable, DID resolution never fails due to offline device.
280
281---
282
283## Layer 04 — Ops (Security, Conformance & Updates)
284
285### Update & Supply Chain Security
286
287#### 2-of-3 Threshold Signing
288
289**v1.0**
290
291🔑 CI key + offline engineer key + cold storage. Compromised CI alone cannot ship malicious updates.
292
293#### Transparency Log
294
295**LATER**
296
297📋 Sigstore-backed. Every release publicly logged.
298
299#### Apple Notarization
300
301**v1.0**
302
303🍎 First verification layer via Tauri build pipeline.
304
305#### Responsible Disclosure
306
307**v1.0**
308
309📬 security@ + published PGP key from day one.
310
311#### cargo-audit in CI
312
313**v0.1**
314
315📦 Dependency vulnerability scanning on every build. Pin exact versions in Cargo.lock. Review diffs on dep updates. Verify atrium codegen input against upstream lexicons.
316
317### Conformance Testing
318
319#### L1: Interop Test Vectors
320
321**v0.1**
322
323🧪 Every commit. Official atproto-interop-tests + interop-test-files. Byte-level checks for MST, CAR, CBOR, CID, commit proofs. Strict MST validation.
324
325#### L2: Oracle Compat Suite
326
327**v1.0**
328
329🔬 Nightly CI. Docker Compose: reference TypeScript PDS vs your Rust PDS. Compare CAR output, firehose events, MST roots.
330
331#### L3: Production Canary
332
333**v1.0**
334
335🐤 Live account on real Bluesky via your relay. Health monitor verifies posts appear in AppView. Catches silent federation failures.
336
337### Runtime Threat Mitigations
338
339#### XRPC Input Hardening
340
341**v1.0**
342
343🔒 Request size limits per endpoint. Rate limiting at relay layer. cargo-fuzz targets for CBOR/CAR/MST parsing. Adversarial MST key testing per spec DoS guidance.
344
345#### Tauri IPC Lockdown
346
347**v0.1**
348
349🏗️ Minimal allowlist: create/list/get records + status. Webview cannot access filesystem, shell, HTTP, or crypto. All sensitive ops in Rust backend only.
350
351#### Relay Trust Verification
352
353**LATER**
354
355🤝 Device verifies commits appear in firehose. Protocol designed now (commit ack with seq number), verification logic built later. Protects against censorship by relay.
356
357---
358
359## Relay Tier Pricing — v1.0 Launch
360
361### Free
362
363**$0/mo**
364
365- Iroh tunnel (NAT traversal)
366- Basic XRPC proxy
367- 7-day commit buffer
368- Key share escrow (1 share)
369- Apple notarized updates
370- No firehose proxy — BGS drops on sleep
371- See "BYO Relay" section for self-hosted option
372
373### Pro
374
375**$X/mo**
376
377- Everything in Free
378- Stable firehose proxy (always-on WebSocket)
379- 30-day commit buffer
380- CDN cache for public content
381- requestCrawl auto-trigger
382- Custom domain handle
383- Multi-region GeoDNS (post-launch)
384- Full repo snapshot (post-launch)
385- One-click device migration
386
387### Business
388
389**$XX/mo**
390
391- Everything in Pro
392- 90-day commit buffer
393- Continuous repo snapshot (post-launch)
394- Admin dashboard
395- Priority support
396- Custom relay config
397- Audit logs
398
399### BYO Relay (Self-Hosted)
400
401Not a subscription tier — an alternative deployment model. Operators run their own relay binary (distributed via Nix flake or Docker image).
402
403**Includes:**
404- Full relay functionality (identical binary to managed relay)
405- SQLite or PostgreSQL backend (operator's choice)
406- Local or S3-compatible blob storage
407- No subscription fees — operator provides their own infrastructure
408- No managed monitoring or support
409
410Available at v1.0 launch.
411
412---
413
414## All Questions Resolved
415
416### ✅ Availability — v0.1+
417
418Firehose emitter for native federation. Firehose proxy + commit buffer for v0.2+. In mobile-only phase, relay is the PDS. In desktop-enrolled, relay maintains persistent connection for sleeping device.
419
420### ✅ Durability — v1.0+
421
4222-of-3 Shamir key recovery. Tiered repo snapshots. iCloud + file export + relay escrow.
423
424### ✅ Spec Drift — v0.1+
425
426Repo Engine (atrium + rsky-crypto). 3-layer conformance: interop vectors → oracle → canary.
427
428### ✅ Relay Redundancy — v1.0+
429
430GeoDNS multi-region + BYO relay (Nix/Docker, free). Device-relay protocol spec. Feature negotiation.
431
432### ✅ Runtime Threats — v1.0+
433
434XRPC fuzzing + size limits. Tauri IPC lockdown. Commit ack protocol (designed). cargo-audit. Relay trust verification (designed, deferred).
435
436### ✅ Mobile-First Architecture — v8
437
438Relay is full PDS in v0.1. Desktop enrolls in v0.2 as repo construction engine. Four-phase milestones reconcile mobile and desktop workflows.
439
440---
441
442## Milestone Summary — Four Phases
443
444### v0.1 — Mobile-Only PDS (~3–4 months)
445
446**Goal:** User creates ATProto identity from iPhone, logs into Bluesky.
447Relay is a full PDS. No desktop involved.
448
449**Relay:** Axum + SQLite + repo engine + signing + XRPC + firehose emitter
450**OAuth:** atproto-oauth-axum integration (blocks Bluesky login)
451**Blobs:** upload/serve with local storage
452**Identity:** DID creation + Shamir split at onboarding
453**Federation:** 25 XRPC endpoints (see unified-milestone-map.md §2.1)
454**Testing:** L1 interop tests + cargo-audit
455
456### v0.2 — Desktop Enrollment (~2–3 months)
457
458**Goal:** User pairs desktop Mac, relay becomes proxy+signer.
459
460**Device pairing:** via QR code + desktop promotion
461**XRPC write proxying:** relay → desktop → relay signs
462**Firehose proxy:** for sleeping desktop
463**Blob forwarding:** via Iroh
464**Desktop offline:** → 503 on writes, reads from cache
465
466### v1.0 — Production Launch (~3–4 months)
467
468**Goal:** Production-ready product with recovery and self-hosting.
469
470**Shamir recovery ceremony:** + full share management UI
471**Tier pricing:** Free/Pro/Business
472**BYO relay binary:** Nix/Docker
473**S3 blob backend:** + CDN
474**PostgreSQL option:** for scale
475**L2 oracle suite + L3 canary**
476**XRPC hardening:** + rate limiting
477
478### v2.0+ — Signing Sovereignty (TBD)
479
480**Goal:** User's hardware signs commits directly.
481**Contingent on:** ATProto protocol evolution (multi-key support).