source: Klonkt/FEDERATION.md@ a5515b4

main
Last change on this file since a5515b4 was a5515b4, checked in by roboburr <roboburr@…>, 4 weeks ago

FEDERATION.md: accountmigratie erin, en de acht FEPs die ontbraken

Het document was van 4 augustus en liep achter op de code. Acht FEPs die
src/ noemt stonden er niet in: 1580, 633c, 7628, 888d, 9098, 9876, c648 en
e232. Over accountmigratie stond er niets -- geen Move, geen movedTo, geen
alsoKnownAs -- terwijl die er wel is.

Nieuw: een sectie Account migration (FEP-7628 voor de actor, FEP-1580 voor
de objecten, FEP-888d voor de namespace), met daarin expliciet dat de
moves-collectie geen integrity proof draagt zolang FEP-8b32 ontbreekt. Een
consument moet dus de servende host vertrouwen in plaats van de claim.

Gecorrigeerd: FEP-044f stond onder 'Under consideration' met 'quotes appear
as replies with an inline link'. Er zijn inmiddels echte quote-semantieken
(quote + e232 Link tag), dus die is naar Supported verhuisd. De regel dat
het guardian-model 'wordt gedraft als kandidaat-FEP' is vervangen door
FEP-633c met de PR erbij.

Move, Block en Offer toegevoegd aan de lijsten verzonden/ontvangen
activiteiten. Statussen (FINAL/DRAFT) overgenomen uit index.json upstream,
niet uit het hoofd.

Refs shaer-9u6.

Co-Authored-By: Claude Opus 5 <noreply@…>

  • Property mode set to 100644
File size: 12.1 KB
RevLine 
[162c7a7]1# Federation
2
3Klonkt is a small single-tenant fediverse site engine. Each site is one
4ActivityPub actor (a `Person`) that federates its posts, replies, boosts,
5likes, follows and polls, and that native or web apps can drive over
6ActivityPub Client-to-Server. This document describes what Klonkt speaks on the
7wire, following [FEP-67ff](https://codeberg.org/fediverse/fep/src/branch/main/fep/67ff/fep-67ff.md).
8
9## Supported federation protocols and standards
10
11- [ActivityPub](https://www.w3.org/TR/activitypub/) Server-to-Server (S2S)
12- [ActivityPub](https://www.w3.org/TR/activitypub/) Client-to-Server (C2S), over OAuth 2.0
13- [WebFinger](https://webfinger.net/) ([RFC 7033](https://www.rfc-editor.org/rfc/rfc7033))
14- [HTTP Signatures](https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures) (draft-cavage), `rsa-sha256`
15- [NodeInfo](https://nodeinfo.diaspora.software/) 2.1
16- [OAuth 2.0](https://www.rfc-editor.org/rfc/rfc6749) public clients with PKCE ([RFC 7636](https://www.rfc-editor.org/rfc/rfc7636), S256 only)
17- [OAuth 2.0 Authorization Server Metadata](https://www.rfc-editor.org/rfc/rfc8414) ([RFC 8414](https://www.rfc-editor.org/rfc/rfc8414))
18- [OAuth 2.0 Dynamic Client Registration](https://www.rfc-editor.org/rfc/rfc7591) ([RFC 7591](https://www.rfc-editor.org/rfc/rfc7591))
19
20## Supported FEPs
21
22- [FEP-67ff: FEDERATION.md](https://codeberg.org/fediverse/fep/src/branch/main/fep/67ff/fep-67ff.md) (FINAL): this file.
23- [FEP-f1d5: NodeInfo in Fediverse Software](https://codeberg.org/fediverse/fep/src/branch/main/fep/f1d5/fep-f1d5.md) (FINAL): `/.well-known/nodeinfo` links to a NodeInfo 2.1 document advertising software, version and the `activitypub` protocol.
[a5515b4]24- [FEP-e232: Object Links](https://codeberg.org/fediverse/fep/src/branch/main/fep/e232/fep-e232.md) (FINAL): `Link` tags with `mediaType` `application/ld+json; profile="https://www.w3.org/ns/activitystreams"` for object references inside content.
25- [FEP-044f: Consent-respecting quote posts](https://codeberg.org/fediverse/fep/src/branch/main/fep/044f/fep-044f.md) (DRAFT): a quoted fediverse object carries real quote semantics — the `quote` property plus an FEP-e232 `Link` tag — and renders as a quote card rather than a bare link.
26- [FEP-9098: Custom emojis](https://codeberg.org/fediverse/fep/src/branch/main/fep/9098/fep-9098.md) (DRAFT): `:shortcode:` emoji tags on content and display names, preserved on the wire so connected apps can render them.
27- [FEP-c648: Blocked Collection](https://codeberg.org/fediverse/fep/src/branch/main/fep/c648/fep-c648.md) (DRAFT): inbound `Block` and `Undo(Block)` are honoured.
28- [FEP-7628: Move actor](https://codeberg.org/fediverse/fep/src/branch/main/fep/7628/fep-7628.md) (DRAFT): account migration — `alsoKnownAs`, `movedTo` and the `Move` activity, sent and received. See "Account migration".
29- [FEP-1580: Move Actor Objects with a `migration` Collection](https://codeberg.org/fediverse/fep/src/branch/main/fep/1580/fep-1580.md) (DRAFT): the objects a `Move` leaves behind, exposed as a `migration` collection alongside `moves`.
30- [FEP-888d: Using `https://w3id.org/fep` as a base for FEP-specific namespaces](https://codeberg.org/fediverse/fep/src/branch/main/fep/888d/fep-888d.md) (DRAFT): the FEP-1580 terms are declared under `https://w3id.org/fep/1580/`, as that FEP registers them.
31
32Two further proposals are our own and are not (yet) part of the FEP index:
33
34- **FEP-633c: Guardians** — guardian-gated actors: wards, gated follows and
35 replies, the call-in flow, and a multi-party handshake. Implemented here and
36 submitted upstream as pull request
37 [#889](https://codeberg.org/fediverse/fep/pulls/889); the vocabulary is served
38 at [`https://ns.klonkt.com/shaer`](https://ns.klonkt.com/shaer).
39- **FEP-9876: enriched actor references** — collection members are bare URIs by
40 default and embedded objects on request, opt-in through
41 `Prefer: return=representation` ([RFC 7240](https://www.rfc-editor.org/rfc/rfc7240)).
42 Implemented; not yet submitted.
[162c7a7]43
44Beyond these, Klonkt aims for de-facto Mastodon compatibility (the
45`http://joinmastodon.org/ns#` extension terms below). See "Under consideration"
46for FEPs we track but do not yet implement.
47
48## ActivityPub
49
50### Actor
51
52Each site exposes a `Person` actor at `/ap/users/:slug` with `inbox`, `outbox`,
53`followers`, `following` and `featured` collections, and an RSA-2048 public key
54under the legacy `publicKey` / `publicKeyPem` field
55([w3id security/v1](https://w3id.org/security/v1)). The actor advertises
56`discoverable`, `manuallyApprovesFollowers` (currently always `false`),
57`featured`, and profile metadata as `schema:PropertyValue` links (including
58`rel="me"` verification links). Actor and object requests are
59content-negotiated: `application/activity+json` returns the AP document, other
60`Accept` values redirect to the human profile page.
61
62### Activities sent
63
64`Create`, `Update`, `Delete` (as `Tombstone`), `Follow`, `Accept`, `Like`,
65`Announce`, `Undo` (of `Follow` / `Like` / `Announce`), `Add` / `Remove`
[a5515b4]66(featured-pin sync), `Flag` (moderation reports), `Move` (account migration),
67and `Offer` (the FEP-633c guardianship handshake). Posts, replies, boosts,
[162c7a7]68likes and follows are delivered to remote inboxes with a signed HTTP request and
69a retrying delivery queue.
70
71### Activities received
72
73`Create`, `Update`, `Delete`, `Follow`, `Accept`, `Reject`, `Like`, `Announce`,
[a5515b4]74`Undo`, `Flag`, `Block`, `Move` and `Offer`. Inbound follows are answered with
75`Accept` and backfilled with recent posts. Every inbound activity must carry a
76valid HTTP signature; unsigned or unverifiable requests are rejected.
[162c7a7]77
78### Object types
79
80- `Note`: posts and replies, including rich replies with formatting and media.
81- `Question`: polls, single (`oneOf`) or multiple (`anyOf`) choice, with
82 `endTime`, `closed`, and Mastodon's `toot:votersCount`. Votes are received as a
83 `Note` with a `name` matching an option and `inReplyTo` the question. Tallies
84 are pushed to followers as `Update(Question)`.
85- `Image`, `Audio`, `Video`: media attachments with `mediaType`, `url` and `name`
86 (alt text). Audio attachments may carry cover art in `icon`.
87- `Tombstone`: in `Delete` activities.
88
89### Extensions and compatibility terms
90
91Every emitted object carries the full `@context`. Beyond AS2 core and
92security/v1, Klonkt declares and uses:
93
94- `as:sensitive` and `summary` for content warnings (blurred media, hidden text).
95- `as:Hashtag` tag objects (`#Tag`, linked to `/tag/:slug`).
96- `Mention` tag objects (`@user@host`, linked to the actor), resolved outbound
97 via WebFinger.
98- `contentMap`: BCP-47 language maps on posts and replies (Mastodon language
99 filter and translate).
100- `toot:discoverable`, `toot:featured`, `toot:votersCount`.
101- `schema:PropertyValue` / `schema:value` for profile metadata, and
102 `schema:embedUrl` for player-card embeds.
103
104### Collections
105
106- `followers` and `following` are count-only for the public. An authenticated
107 request from the site owner (a C2S bearer token scoped to that site) returns the
108 full list of actor URIs, so a connected app can build a contacts list.
109- `featured` lists pinned posts. Pin and unpin federate immediately as
110 `Add` / `Remove`, serialized per site to keep Mastodon's pin order.
111- A note's `replies` collection is served, and inbound threads are crawled one
112 level at a time (stale-while-revalidate, SSRF-guarded, budget-limited).
113
[a5515b4]114## Account migration
115
116Klonkt implements account moves in both directions, following
117[FEP-7628](https://codeberg.org/fediverse/fep/src/branch/main/fep/7628/fep-7628.md)
118for the actor and
119[FEP-1580](https://codeberg.org/fediverse/fep/src/branch/main/fep/1580/fep-1580.md)
120for the objects the actor leaves behind.
121
122- **Actor terms.** `alsoKnownAs` and `movedTo` are declared with the same term
123 definitions Mastodon ships, so an existing implementation reads them without
124 special-casing. `alsoKnownAs` is reserved for former identities of the same
125 actor; a reference to an external register (a MusicBrainz artist, say) uses
126 `schema:sameAs` instead, precisely so that a move cannot be confused by it.
127- **The `Move` activity** is both sent and received. FEP-7628 moves *followers*
128 and says so explicitly; the objects are a separate problem, which is what
129 FEP-1580 addresses.
130- **Object migration.** A migrated site exposes a `migration` collection and a
131 `moves` collection, plus `migrationComplete`, `migratedFrom` and `migratedAt`.
132 The terms live under `https://w3id.org/fep/1580/`, the namespace that FEP
133 registers by way of FEP-888d. The FEP's own CURIE for the collection is
134 `migration:migration`; Klonkt emits the JSON key `migration`, because that is
135 what a consumer reads on.
136- **Importing.** An import from an export is not treated as a separate case: the
137 same path ingests from a source actor.
138
139One gap is worth stating plainly: the `moves` collection carries **no integrity
140proof**. Without [FEP-8b32](https://codeberg.org/fediverse/fep/src/branch/main/fep/8b32/fep-8b32.md)
141there is no signature under it, so a consumer has to trust the serving host
142rather than the claim itself. This is tracked and not yet resolved.
143
[162c7a7]144## Client-to-Server (C2S)
145
146Native and web apps drive an account over ActivityPub C2S. This is not the
147Mastodon client API: Mastodon apps (Ivory and the like) are not supported here.
148
149- Discovery: the actor advertises its OAuth endpoints, and
150 `/.well-known/oauth-authorization-server` (RFC 8414) returns the authorization,
151 token and registration endpoints, `response_types=["code"]`,
152 `grant_types=["authorization_code"]`, `code_challenge_methods=["S256"]`,
153 `token_endpoint_auth_methods=["none"]` and `scopes_supported=["c2s"]`.
154- Registration: `POST /oauth/register` (RFC 7591), public clients only.
155- Authorization: PKCE authorization-code flow with a consent screen where the
156 user picks which site the app may act for. Tokens are hashed at rest and bound
157 to a single user and site.
158- Outbox: `POST /ap/users/:slug/outbox` with a bearer token accepts `Create`
159 (a bare `Note` is wrapped in a `Create` per spec), `Like`, `Announce`,
160 `Follow` and their `Undo`. Content is sanitized; a token cannot post for a
161 different site. `Delete` and `Update` over C2S are not yet implemented.
162
163## Authentication
164
165- S2S: HTTP Signatures (draft-cavage), `rsa-sha256`, over
166 `(request-target) host date digest`, with a configurable clock-skew tolerance
167 and reverse-proxy-aware host matching. Object Integrity Proofs
168 (FEP-8b32) are not used.
169- C2S: OAuth 2.0 bearer tokens, public clients with PKCE (S256), scope `c2s`.
170
171## Moderation and safety
172
173- Inbound `Flag` reports are stored for the site owner; the owner can send an
174 outbound `Flag` to a remote actor's server.
175- The owner can remove an inbound reply from a thread; a tombstone prevents the
176 thread crawler from re-fetching it.
177- Actor and domain blocks silently drop matching activities (no error
178 disclosure) and purge existing content.
179- All outbound fetches are SSRF-guarded (private-range IP blocking on every
180 redirect hop, per-request timeout).
181
182## Under consideration (not yet implemented)
183
184Klonkt tracks the following proposals but does not implement them yet. Draft
185specs are marked; per project policy, drafts are only adopted deliberately and
186with a note in the changelog.
187
188- Reply control. FEP-5624 (per-object reply control) is WITHDRAWN as of
189 2025-06-24; its Mastodon terms `canReply` / `ApproveReply` / `RejectReply`
190 remain in production use. The live successor discussion is in drafts FEP-171b
191 (conversation containers), FEP-7458 (replies collection) and FEP-11dd (context
192 ownership). Klonkt currently accepts all replies to its posts.
193- Search-indexing consent: FEP-5feb (DRAFT). No `indexable` flag is emitted yet.
194- Actor public keys as Multikey: FEP-521a (FINAL). Klonkt still uses the legacy
195 `publicKey` representation.
[a5515b4]196- Object Integrity Proofs: FEP-8b32 (DRAFT). Not used. This is also what leaves
197 the `moves` collection unsigned; see "Account migration".
[162c7a7]198- Followers collection synchronization: FEP-8fcf (FINAL). Not implemented.
199
200## Additional documentation
201
[5143ccf]202- Client-to-Server API for apps (the Shaer contract): `docs/shaer-c2s-api.md`.
[162c7a7]203- Source code: `src/services/ActivityPubService.js` (core AP logic),
204 `src/routes/activitypub.js` (S2S, WebFinger, NodeInfo),
205 `src/routes/oauth.js` (C2S / OAuth).
206- Changelog: `CHANGELOG.md` (and `CHANGELOG.nl.md`, `CHANGELOG.de.md`).
Note: See TracBrowser for help on using the repository browser.