An easy-to-host PDS on the ATProtocol, iPhone and MacOS. Maintain control of your keys and data, always.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Desktop PDS — System Architecture#

v8 — Mobile-First Reconciliation · Four-Phase Milestones

Sovereign AT Protocol PDS on macOS via Tauri + Repo Engine + Iroh

Milestone Legend#

v0.1 — Mobile-Only PDS · relay is full PDS

v0.2 — Desktop Enrollment · relay as proxy+signer

v1.0 — Public Launch · product-ready

LATER — Designed, built post-launch


Changelog#

v8 Changes — Mobile-First Reconciliation#

Architecture 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.

  • NEW Four-phase milestone model (v0.1 / v0.2 / v1.0 / v2.0+)
  • NEW Phase 0: Mobile-Only lifecycle (relay as full PDS)
  • FIX Signing model: relay always signs, device constructs unsigned commits
  • FIX Tier model: Free/Pro/Business + BYO as deployment model
  • FIX Firehose: native emission (mobile-only) vs proxy (desktop-enrolled)
  • FIX Shamir: basic share generation moves to v0.1 (required at onboarding)
  • FIX DID keystore: Shamir split required at account creation, not v1.0
  • REF See unified-milestone-map.md for phase details

Previous Versions#

v2: 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.


Device Lifecycle Phases#

The product launches mobile-first. The relay is a full PDS before any desktop is involved.

Phase: Mobile-Only (v0.1)

  • Relay behavior: Full PDS — hosts repo, serves XRPC, signs commits, emits firehose
  • Repo location: Relay (primary and only copy)
  • Phone role: Identity wallet (key management, device admin)
  • Desktop: Does not exist yet

Phase: Desktop-Enrolled (v0.2)

  • Relay behavior: XRPC proxy + signer — forwards writes to desktop, signs commits, serves reads from cache
  • Repo location: Desktop (primary), relay (cache)
  • Phone role: Identity wallet + device manager
  • Desktop: Runs repo engine, constructs unsigned commits

Phase: Desktop-Offline (v0.2+)

  • Relay behavior: Serves reads from cache, 503 on writes
  • Repo location: Desktop (authoritative but unreachable)
  • Phone role: Same as desktop-enrolled
  • Desktop: Sleeping / powered off

Layer 01 — Device Layer (Desktop, v0.2+)#

In v0.1 (Mobile-Only), there is no device layer. All operations run on the relay.

Tauri Shell#

v0.2

🖥️ Native macOS app. Process lifecycle, auto-updates, system tray. Minimal IPC allowlist — webview cannot access filesystem, shell, or network directly.

Repo Engine#

v0.2

📦 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.

Dependency Stack#

v0.1

🧩 atrium-api — XRPC types, lexicon defs (auto-generated). atrium-repo — MST read/write, CAR export. rsky-crypto — P-256/K-256 commit signing.

Iroh Endpoint#

v0.1

🔗 QUIC-based tunnel to relay. NAT traversal, connection resumption on wake. Pushes unsigned repo commits to relay for signing when online.

DID Keystore#

v0.1

🔐 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.

Recovery Share Manager#

v1.0

🛟 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.

Compat Warning Banner#

v1.0

⚠️ Non-blocking in-app warning when spec drift detected. Links to update. Never blocks launch.

XRPC Hardening#

v1.0

🛡️ 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.

REMOVED: rsky-pds (fork) — Replaced by repo engine in v5. Now tracking a spec, not a codebase.


Layer 02 — Relay Layer (Managed + BYO)#

Managed Relay (Your Infrastructure)#

Iroh Relay Node#

v0.1

🚇 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.

requestCrawl Trigger#

v0.1

📣 On device reconnect, pings BGS requestCrawl so new content propagates immediately.

Firehose Emitter#

v0.1

📡 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.

Firehose Proxy#

v0.2

📡 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.

Commit Buffer#

v0.2

💾 Rolling log of signed repo commits. Feeds firehose proxy during offline. Tiered retention: 7d free, 30d paid, 90d business.

Provisioning API#

v0.1

⚙️ Account setup, domain linking, relay config. Onboarding flow for new connections. Core provisioning needed from day one.

Key Share Escrow#

v0.1

🔏 Holds one encrypted Shamir share. Cannot reconstruct alone. Encrypted at rest, access-logged. Relay holds Share 2 from account creation.

Health Monitor#

v1.0

💓 Device liveness, relay uptime, ATProto spec compat. Includes canary account for silent federation failure detection.

GeoDNS Multi-Region#

LATER

🌎 2–3 relay nodes, route to nearest healthy. Simple failover with brief firehose gap. Cross-region replication interface designed but not built.

Repo Snapshot#

LATER

🗄️ Full repo backup on relay. Incremental from commit buffer. Pro+ feature. Enables one-click device migration.

CDN / Public Cache#

LATER

🌐 Serves public repo content during offline windows.

BYO Relay (User-Hosted, Free)#

Relay Binary#

v1.0

📦 Open-source. Nix flake (source of truth) → Docker image + NixOS module. Tunnel + commit forwarding + requestCrawl. No firehose proxy, no snapshots.

Device-Relay Protocol Spec#

v1.0

📜 Documented contract: handshake/auth, commit push, health ping, optional feature negotiation. Includes commit ack for future trust verification.

Feature Negotiation#

v1.0

🔌 App queries relay capabilities on connect. Gracefully degrades when extended features unavailable. Suggests upgrade for missing features.

REMOVED: Inbound Message Queue — Not needed. ATProto records live in author's repo.


Data Flow#

Desktop-Enrolled Write Path#

  1. App creates record via XRPC (Tauri webview → Rust backend)
  2. Repo Engine constructs MST diff + unsigned commit
  3. Unsigned commit sent to relay via Iroh tunnel
  4. Relay signs commit with P-256 signing key
  5. Relay stores signed commit in buffer
  6. Relay emits to firehose / serves via XRPC

Mobile-Only Write Path (v0.1)#

  1. Third-party app (e.g. Bluesky) calls relay XRPC directly
  2. Relay constructs record, MST diff, signs commit
  3. Relay stores and emits to firehose

Desktop-Offline Read Path#

  1. XRPC read request hits relay
  2. Relay serves from commit buffer / repo cache
  3. Writes return 503 (relay cannot construct commits from stale state)

Data Flow — How Bob's Post Reaches the Network#

Current scenario showing firehose proxy operation during v0.2+:

Bob's Mac (Repo Engine constructs unsigned commit) → Iroh tunnelRelay (Signs commit with P-256 key) → Commit Buffer (Persists signed commit) → Firehose Proxy (Stable WebSocket) → subscribeReposBGS (Network firehose) → indexesAppView (Bluesky etc.)

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.


Recovery Flow — Device Migration / Dead SSD (v1.0+)#

New Mac (Installs Tauri app) → authenticates2-of-3 Shares (iCloud + relay escrow) → reconstructsRotation Key (Shamir recombination) → did:plc opKey Rotation (New signing key) → syncsRepo Snapshot (Full repo restore)

Share sources (any 2 of 3):

  • ① iCloud Keychain
  • ② Relay escrow
  • ③ Exported recovery file
  • Future: ④ Trusted contact (social recovery) — interface designed, not yet shipped

Layer 03 — Infrastructure (ATProto Network)#

Federation#

v0.1

🌍 PDS participates in ATProto network via relay. DID document points to relay URL as canonical PDS endpoint.

DNS / Domain Automation#

v1.0

🔤 Handle-as-domain resolution. Automated DNS config for custom domain handles.

DID Resolution#

v0.1

🪪 did:plc or did:web pointing to relay endpoint. Relay always reachable, DID resolution never fails due to offline device.


Layer 04 — Ops (Security, Conformance & Updates)#

Update & Supply Chain Security#

2-of-3 Threshold Signing#

v1.0

🔑 CI key + offline engineer key + cold storage. Compromised CI alone cannot ship malicious updates.

Transparency Log#

LATER

📋 Sigstore-backed. Every release publicly logged.

Apple Notarization#

v1.0

🍎 First verification layer via Tauri build pipeline.

Responsible Disclosure#

v1.0

📬 security@ + published PGP key from day one.

cargo-audit in CI#

v0.1

📦 Dependency vulnerability scanning on every build. Pin exact versions in Cargo.lock. Review diffs on dep updates. Verify atrium codegen input against upstream lexicons.

Conformance Testing#

L1: Interop Test Vectors#

v0.1

🧪 Every commit. Official atproto-interop-tests + interop-test-files. Byte-level checks for MST, CAR, CBOR, CID, commit proofs. Strict MST validation.

L2: Oracle Compat Suite#

v1.0

🔬 Nightly CI. Docker Compose: reference TypeScript PDS vs your Rust PDS. Compare CAR output, firehose events, MST roots.

L3: Production Canary#

v1.0

🐤 Live account on real Bluesky via your relay. Health monitor verifies posts appear in AppView. Catches silent federation failures.

Runtime Threat Mitigations#

XRPC Input Hardening#

v1.0

🔒 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.

Tauri IPC Lockdown#

v0.1

🏗️ Minimal allowlist: create/list/get records + status. Webview cannot access filesystem, shell, HTTP, or crypto. All sensitive ops in Rust backend only.

Relay Trust Verification#

LATER

🤝 Device verifies commits appear in firehose. Protocol designed now (commit ack with seq number), verification logic built later. Protects against censorship by relay.


Relay Tier Pricing — v1.0 Launch#

Free#

$0/mo

  • Iroh tunnel (NAT traversal)
  • Basic XRPC proxy
  • 7-day commit buffer
  • Key share escrow (1 share)
  • Apple notarized updates
  • No firehose proxy — BGS drops on sleep
  • See "BYO Relay" section for self-hosted option

Pro#

$X/mo

  • Everything in Free
  • Stable firehose proxy (always-on WebSocket)
  • 30-day commit buffer
  • CDN cache for public content
  • requestCrawl auto-trigger
  • Custom domain handle
  • Multi-region GeoDNS (post-launch)
  • Full repo snapshot (post-launch)
  • One-click device migration

Business#

$XX/mo

  • Everything in Pro
  • 90-day commit buffer
  • Continuous repo snapshot (post-launch)
  • Admin dashboard
  • Priority support
  • Custom relay config
  • Audit logs

BYO Relay (Self-Hosted)#

Not a subscription tier — an alternative deployment model. Operators run their own relay binary (distributed via Nix flake or Docker image).

Includes:

  • Full relay functionality (identical binary to managed relay)
  • SQLite or PostgreSQL backend (operator's choice)
  • Local or S3-compatible blob storage
  • No subscription fees — operator provides their own infrastructure
  • No managed monitoring or support

Available at v1.0 launch.


All Questions Resolved#

✅ Availability — v0.1+#

Firehose 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.

✅ Durability — v1.0+#

2-of-3 Shamir key recovery. Tiered repo snapshots. iCloud + file export + relay escrow.

✅ Spec Drift — v0.1+#

Repo Engine (atrium + rsky-crypto). 3-layer conformance: interop vectors → oracle → canary.

✅ Relay Redundancy — v1.0+#

GeoDNS multi-region + BYO relay (Nix/Docker, free). Device-relay protocol spec. Feature negotiation.

✅ Runtime Threats — v1.0+#

XRPC fuzzing + size limits. Tauri IPC lockdown. Commit ack protocol (designed). cargo-audit. Relay trust verification (designed, deferred).

✅ Mobile-First Architecture — v8#

Relay is full PDS in v0.1. Desktop enrolls in v0.2 as repo construction engine. Four-phase milestones reconcile mobile and desktop workflows.


Milestone Summary — Four Phases#

v0.1 — Mobile-Only PDS (~3–4 months)#

Goal: User creates ATProto identity from iPhone, logs into Bluesky. Relay is a full PDS. No desktop involved.

Relay: Axum + SQLite + repo engine + signing + XRPC + firehose emitter OAuth: atproto-oauth-axum integration (blocks Bluesky login) Blobs: upload/serve with local storage Identity: DID creation + Shamir split at onboarding Federation: 25 XRPC endpoints (see unified-milestone-map.md §2.1) Testing: L1 interop tests + cargo-audit

v0.2 — Desktop Enrollment (~2–3 months)#

Goal: User pairs desktop Mac, relay becomes proxy+signer.

Device pairing: via QR code + desktop promotion XRPC write proxying: relay → desktop → relay signs Firehose proxy: for sleeping desktop Blob forwarding: via Iroh Desktop offline: → 503 on writes, reads from cache

v1.0 — Production Launch (~3–4 months)#

Goal: Production-ready product with recovery and self-hosting.

Shamir recovery ceremony: + full share management UI Tier pricing: Free/Pro/Business BYO relay binary: Nix/Docker S3 blob backend: + CDN PostgreSQL option: for scale L2 oracle suite + L3 canary XRPC hardening: + rate limiting

v2.0+ — Signing Sovereignty (TBD)#

Goal: User's hardware signs commits directly. Contingent on: ATProto protocol evolution (multi-key support).