From 9f788377f66b975ed083a5d1acebd41aab0a8521 Mon Sep 17 00:00:00 2001 From: Bretton Date: Sun, 2 Nov 2025 17:02:30 -0800 Subject: [PATCH] docs: document OAuth DPoP vote architecture change Add comprehensive documentation explaining why vote write-forward endpoints were removed: - OAuth DPoP tokens are cryptographically bound to client's private key - Backend cannot create DPoP proofs (doesn't have the key) - Solution: Clients write directly to their PDS using com.atproto.repo.createRecord/deleteRecord - AppView indexes votes from Jetstream for aggregation Also documented future work needed for subscriptions and blocking. See: docs/PRD_BACKLOG.md#oauth-dpop-token-architecture --- docs/PRD_BACKLOG.md | 81 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/docs/PRD_BACKLOG.md b/docs/PRD_BACKLOG.md index 81e0ac2..8c4d674 100644 --- a/docs/PRD_BACKLOG.md +++ b/docs/PRD_BACKLOG.md @@ -13,8 +13,8 @@ Miscellaneous platform improvements, bug fixes, and technical debt that don't fi ## 🔴 P0: Critical (Alpha Blockers) ### OAuth DPoP Token Architecture - Voting Write-Forward -**Added:** 2025-11-02 | **Effort:** 4-6 hours | **Priority:** ALPHA BLOCKER -**Status:** ⚠️ ARCHITECTURE DECISION REQUIRED +**Added:** 2025-11-02 | **Completed:** 2025-11-02 | **Effort:** 2 hours | **Priority:** ALPHA BLOCKER +**Status:** ✅ COMPLETE **Problem:** Our backend is attempting to use DPoP-bound OAuth tokens to write votes to users' PDSs, causing "Malformed token" errors. This violates atProto architecture patterns. @@ -127,6 +127,83 @@ Backend changes: --- +### OAuth DPoP Token Architecture - Community Subscriptions +**Added:** 2025-11-02 | **Effort:** 1-2 hours | **Priority:** ALPHA BLOCKER +**Status:** 📋 TODO (Waiting for frontend implementation) + +**Problem:** +Same DPoP token issue as voting - backend cannot use user's DPoP-bound OAuth tokens to write subscription records to user's PDS. + +**Affected Operations:** +- `SubscribeToCommunity()` - [service.go:564-624](../internal/core/communities/service.go#L564-L624) +- `UnsubscribeFromCommunity()` - [service.go:626-660](../internal/core/communities/service.go#L626-L660) + +**Collection:** `social.coves.community.subscription` + +**Solution:** +Client writes directly using `com.atproto.repo.createRecord`: +```typescript +await agent.call('com.atproto.repo.createRecord', { + repo: userDid, + collection: 'social.coves.community.subscription', + record: { + $type: 'social.coves.community.subscription', + subject: communityDid, + contentVisibility: 3, + createdAt: new Date().toISOString() + } +}) +``` + +**Backend Changes Needed:** +1. Remove write-forward from `SubscribeToCommunity()` and `UnsubscribeFromCommunity()` +2. Update handlers to return errors directing to client-direct pattern +3. Verify Jetstream consumer indexes subscriptions (already working) + +**Files to Modify:** +- `internal/core/communities/service.go` +- `internal/api/handlers/community/subscribe.go` + +--- + +### OAuth DPoP Token Architecture - Community Blocking +**Added:** 2025-11-02 | **Effort:** 1-2 hours | **Priority:** ALPHA BLOCKER +**Status:** 📋 TODO (Waiting for frontend implementation) + +**Problem:** +Same DPoP token issue - backend cannot use user's DPoP-bound OAuth tokens to write block records to user's PDS. + +**Affected Operations:** +- `BlockCommunity()` - [service.go:709-781](../internal/core/communities/service.go#L709-L781) +- `UnblockCommunity()` - [service.go:783-816](../internal/core/communities/service.go#L783-L816) + +**Collection:** `social.coves.community.block` + +**Solution:** +Client writes directly using `com.atproto.repo.createRecord`: +```typescript +await agent.call('com.atproto.repo.createRecord', { + repo: userDid, + collection: 'social.coves.community.block', + record: { + $type: 'social.coves.community.block', + subject: communityDid, + createdAt: new Date().toISOString() + } +}) +``` + +**Backend Changes Needed:** +1. Remove write-forward from `BlockCommunity()` and `UnblockCommunity()` +2. Update handlers to return errors directing to client-direct pattern +3. Verify Jetstream consumer indexes blocks (already working) + +**Files to Modify:** +- `internal/core/communities/service.go` +- `internal/api/handlers/community/block.go` + +--- + ## 🟡 P1: Important (Alpha Blockers) ### at-identifier Handle Resolution in Endpoints -- 2.51.2