code
Clone this repository
https://tangled.org/bretton.dev/coves
git@knot.bretton.dev:bretton.dev/coves
For self-hosted knots, clone URLs may differ based on your setup.
Implements user-scoped OAuth tokens for subscription operations, replacing
the deprecated OAuth/DPoP implementation with simplified JWT validation.
This merge includes 8 commits:
1. Remove deprecated OAuth implementation (2,738 lines)
2. Add JWT validation with JWKS fetching (845 lines)
3. Store user access tokens in middleware context
4. Update service to use user tokens for subscriptions
5. Update handlers to extract and forward tokens
6. Fix integration tests for new auth flow
7. Update server initialization
8. Update all documentation
Key Changes:
- ✅ Users can now subscribe/unsubscribe (proper PDS authorization)
- ✅ Simplified auth system (-615 net lines)
- ✅ All E2E tests passing with real authentication
- ✅ Comprehensive documentation (PRD_OAUTH.md)
Known Issue:
- Subscription indexing needs Jetstream consumer in production
(see docs/PRD_COMMUNITIES.md)
Net change: -615 lines (removed 3,166, added 2,551)
Documentation updates:
PRD_OAUTH.md (new):
- Document OAuth Phase 1 vs Phase 2 approach
- Explain why we simplified from DPoP to JWT-only
- Detail the new authentication flow
- Document known limitations and future work
PRD_COMMUNITIES.md:
- Mark OAuth authentication as complete (2025-10-16)
- Add new critical blocker: subscription indexing
- Document missing Jetstream consumer in production
- Update security section with completion status
PRD_BACKLOG.md:
- Mark user subscription auth issue as resolved
- Reorganize priorities post-OAuth completion
CLAUDE.md:
- Update builder guidelines
- Clarify security-first principles
- Add atProto authentication best practices
Server and infrastructure updates:
- Initialize auth middleware with JWT validation
- Remove OAuth route registration
- Update imports to use new auth package
- Clean up unused OAuth configuration
- Update PDS provisioning comments for clarity
- Fix repository query parameter ordering
These changes complete the migration from OAuth to JWT-based auth
throughout the application initialization and routing layers.
Update integration tests to pass access tokens:
- Pass accessToken to SubscribeToCommunity() calls
- Add comments explaining token usage in tests
- Verify subscribe/unsubscribe E2E flows with real auth
Tests now validate the complete authentication chain:
1. User authenticates with PDS (gets access token)
2. User makes request with Authorization header
3. Middleware validates JWT and stores token
4. Handler extracts token from context
5. Service uses token to write to user's PDS repo
6. PDS validates user owns the repository
7. Record successfully written
All E2E tests pass with real PDS authentication.
Update community handlers to pass user tokens through:
Subscribe/Unsubscribe handlers:
- Extract user access token from request context
- Validate token presence (return 401 if missing)
- Pass token to service layer for PDS operations
Create/Update handlers:
- Update comments to clarify security model
- Document that createdByDid/updatedByDid come from JWT
- Document that hostedByDid is server-side derived
This completes the token flow: middleware → handlers → service → PDS,
ensuring each layer has the credentials needed for proper authorization.
Update subscription methods to accept and use user access tokens:
- Add userAccessToken parameter to SubscribeToCommunity()
- Add userAccessToken parameter to UnsubscribeFromCommunity()
- Add deleteRecordOnPDSAs() helper for user-scoped deletions
- Use createRecordOnPDSAs() for subscription creation
- Validate token presence before PDS operations
This fixes the authorization issue where we were using instance
credentials to write to user repositories, which the PDS correctly
rejected with 401 errors.
Now each user operation uses that user's own access token, ensuring
proper atProto authorization semantics.