Teilnehmer mit fremdem PDS (OAuth)
Status: Konzept, nicht umgesetzt (2026-10-26). Das ist Stufe 1 in ROADMAP.md. Die Berechtigung ist dort geregelt: Rechte folgen der Mitgliedschaft bei einem Client und dessen Teilnahmeregeln.
Heute kann nur mitmachen, wer über den Registrar (createAccount) ein Konto auf
unserem PDS bekommt. Ziel: zusätzlich Personen zulassen, die schon ein
ATProto-Konto anderswo haben (z.B. bsky.social), ohne den bestehenden Weg
(Magic Link, passwortlos) aufzugeben.
Zwei Login-Wege
Abschnitt betitelt „Zwei Login-Wege“| Eigener PDS | Fremder PDS | |
|---|---|---|
| Konto | vom Registrar angelegt | besteht bereits |
| Login des Users | beim Client, z.B. Magic Link (Methode wählt der Client) | ATProto-OAuth: Login auf dem fremden PDS, mit dessen Methode |
| Was der Client hält | App-Passwort (von createAccount) |
OAuth-Tokens (widerrufbar, mit Scopes, DPoP-gebunden) |
| Schreiben ins User-Repo | Client mit App-Passwort-Session | Client mit OAuth-Token |
| Lesen mit Viewer | atproto-proxy → Service-Auth |
identisch |
Magic Link (eigener PDS) OAuth (fremder PDS) ──────────────────────── ─────────────────── User ─E-Mail-Link─► Client User ─Handle eingeben─► Client │ App-Passwort │ Weiterleitung zum fremden PDS, │ (vom Registrar) │ User loggt sich DORT ein ▼ ▼ unser PDS fremder PDS ──► Token mit Scopes │ │ └──── atproto-proxy ──┴──► AppView (unverändert)Warum nicht alles über OAuth? Auch unser PDS hat einen OAuth-Server, dessen Login-Seite kennt aber nur Passwort + E-Mail-Code, keinen Magic Link. Für eigene Konten bleibt deshalb der bisherige Weg.
Warum nicht App-Passwörter fremder Konten? Ein Client soll kein Passwort eines fremden Dienstes speichern; OAuth ist dafür der ATProto-Standard.
AppView: keine Änderung nötig. Service-Auth (RUNBOOK §14) funktioniert mit jedem PDS. Das Token wird gegen das DID-Dokument des Users geprüft, egal wo es liegt. Hinweis: das DID-Dokument bei Signaturfehler neu laden (Schlüsselwechsel, PDS-Umzug), nicht zu lange cachen.
Was fehlt
Abschnitt betitelt „Was fehlt“Store (atvoto)
Abschnitt betitelt „Store (atvoto)“- Firehose fremder PDS. Der Indexer hört nur auf unseren PDS
(
FIREHOSE_URL, Defaultwss://${PDS_HOSTNAME},services/indexer/src/service.js). Records in fremden Repos kommen nie an. Lösung: zusätzlich Relay bzw. Jetstream abonnieren (bsky.network), gefiltert aufch.atvoto.*und/oder auf DIDs ausregistry.participants. Cursor-Verwaltung pro Quelle. - Externe Teilnehmer registrieren.
registry.participantswird heute nur voncreateAccountbefüllt. Neu: Registrar-Methode z.B.registerParticipant(did), mit der ein Client eine externe DID seinem User zuordnet (die Zuständigkeit des Clients bleibt, Widerruf überrevokeParticipant). Die Spaltenoriginundassurancekommen schon in Stufe 0 (ROADMAP.md). - Berechtigungsregeln (entschieden 2026-10-26). Jeder Client legt in seinen
Teilnahmeregeln fest, ob und wofür er externe Konten zulässt (
origin), und meldet ihre Prüfstufe (assurance). Der Store setzt das durch. Siehe ROADMAP.md. - Profile. Anzeigename/Avatar externer User kommen nicht über unseren PDS →
Profile aus dem Firehose bzw. per
getProfilebeim fremden PDS (bekannte Lücke). - Moderation. In fremden Repos können wir nichts löschen. Das Muster Original → kanonische Kopie (Writer) deckt das ab: gezählt wird nur die Kopie im Community-Konto. Kommentare und Bewertungen werden direkt aus User-Repos projiziert, hier also Ausblenden im Read-Model statt Löschen.
Client (z.B. smartinfo)
Abschnitt betitelt „Client (z.B. smartinfo)“-
OAuth-Client: Client-Metadaten unter einer HTTPS-URL, JWKS für einen vertraulichen Client, PAR, PKCE, DPoP. Z.B. mit
@atproto/oauth-client-node. -
Scopes, etwa:
repo:ch.atvoto.dossier.argument,repo:ch.atvoto.dossier.comment,repo:ch.atvoto.content.rating,repo:ch.atvoto.peerreview.request,repo:ch.atvoto.peerreview.responserpc:<methode>?aud=did:web:api.atvoto.ch%23atvoto_appview
Option: ein Permission-Set als Lexicon veröffentlichen (z.B.
ch.atvoto.authParticipant), damit alle Clients dasselbe Paket anfragen und die Login-Seite es verständlich anzeigt. Vorher prüfen, wie weit der PDS das unterstützt. -
Eine Session-Schicht für beide Wege: beide Logins ergeben eine DID; danach unterscheidet sich nur, womit der Client den PDS aufruft (App-Passwort-Session oder OAuth-Token). Die Aufrufe an den Store sind identisch.
Reihenfolge
Abschnitt betitelt „Reihenfolge“- Stufe 0 aus ROADMAP.md (Mitgliedschaft, Teilnahmeregeln) muss stehen.
- Store: Punkt 1 (Firehose), unabhängig vorbereitbar; dann 2, 4, 5.
- Client: 6–8.
Prüfen, dass es mit fremden PDS grundsätzlich geht (Service-Auth):
scripts/service_auth_check.sh https://bsky.social <handle> → HTTP 200.
Siehe auch: RUNBOOK §14 (Service-Auth), ARCHITECTURE_SPLIT §5.1 (Registrar),
NEW_ATVOTO_CLIENT.md.