/@user and /@user/{id} are Razor pages showing an avatar's or community's
public and unlisted posts: no scripts, a strict CSP, no-referrer, noindex,
and an alternate link to the ActivityPub document. A client asking them
for activity+json is redirected to the actor or note, and the actor and
note redirect browsers here.
NodeInfo answers 2.1 as well as 2.0 (repository, homepage, a link to
FEDERATION.md) and counts only public local posts.
FEDERATION.md (FEP-67ff) lists the protocols, FEPs, route names,
activities and the security rules a peer will notice.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CzABvBkbcFqoHdmi8b9WB
5.0 KiB
Federation
PrivaPub is an ActivityPub server written in C#. This document follows FEP-67ff and describes how it federates.
Supported federation protocols and standards
- ActivityPub (server-to-server)
- WebFinger
- HTTP Signatures,
rsa-sha256/hs2019with RSA keys - NodeInfo 2.0 and 2.1
Supported FEPs
- FEP-67ff: FEDERATION.md
- FEP-f1d5: NodeInfo in Fediverse Software
- FEP-2c59: Discovery of a WebFinger address from an ActivityPub actor
Planned: FEP-1b12 (communities), FEP-8fcf (followers synchronisation), FEP-5feb (indexable), FEP-7628 (Move),
FEP-044f (quotes).
Actors
Every account is an avatar: one private login can own several, and they are deliberately unlinkable. Nothing in an actor document, a collection, NodeInfo or a delivery relates two avatars of the same login.
| Thing | Address |
|---|---|
| Actor (Person, Group, Application) | /peasants/{name} (/users/{name} redirects) |
| Inbox | /peasants/{name}/mouth |
| Outbox | /peasants/{name}/anus |
| Shared inbox | /human-centipede |
| Followers / following | /peasants/{name}/groupies, /peasants/{name}/stalking |
| Objects | /peasants/{name}/scribbles/{id} |
| Activities | /peasants/{name}/grunts/{id} |
| Direct-message context | /peasants/{name}/whispers/{id} |
| Profile and post pages | /@{name}, /@{name}/{id} |
The names are the project's own and are stable; resolve actors through WebFinger, not by guessing a path.
- The key is
{actor}#main-key, RSA 2048, served as SPKI PEM withownerset to the actor. publishedon an actor is truncated to the day.indexableisfalse.- The instance actor is
/peasants/privapub(typeApplication). It signs every fetch PrivaPub makes, so no avatar's key is used to read another server's content.
Groups
A group is either a community or a circle.
- A community is a
Groupactor. It acceptsFollowand re-shares (Announce) posts from its followers that address it. Full FEP-1b12 behaviour (announcing activities,audience, moderation) is planned. - A circle is private and does not federate yet: its actor, collections and WebFinger answer 404, and its posts are never delivered.
Activities
Received:
| Activity | Effect |
|---|---|
Follow |
follows an avatar or community; Accept is sent unless the community approves members by hand |
Undo{Follow} |
unfollows |
Create{Note, Article, Page, Question, …} |
stored when it addresses or mentions a local avatar, replies to a local post, or is addressed to a community the author follows |
Update{Note} |
replaces the content; the previous version is kept |
Update{Person} |
refetches the actor |
Delete |
deletes the object, or the actor and its follows |
Sent: Create{Note}, Delete{Tombstone}, Accept{Follow}, Announce (communities).
A Create's Note carries Mastodon's content, contentMap, summary and sensitive, plus Mention and Hashtag
tags. A post's title becomes name and is also the first, bold line of content, because Mastodon does not show
name. A content warning without its own text uses the title, or "Content warning".
Visibility is expressed in to/cc the way Mastodon does it: public, unlisted, followers-only and direct. Inbound
followers-only posts are recognised by the author's own followers collection.
Security rules a peer will notice
- Signatures. Inbox POSTs must be signed over
(request-target),host,digestanddate(or(created)). The date may be at most one hour old and fifteen minutes ahead. A bad signature gets 401, malformed input 400, an accepted activity 202, too many requests 429. Activities are processed after the 202. - Origins. An actor document is accepted only from the address it names as its
id. A key only if its actor lists it withownerset to the actor and on the actor's origin. An activity'sid, and any object it creates, updates or deletes, must be on its actor's origin. An embedded object from another origin is fetched from that origin. - Fetching. All fetches are signed by the instance actor. They go only to public addresses, follow at most three redirects and read at most 1 MB.
- HTML. Received HTML is sanitised to Mastodon's allowlist.
- Delivery. Failed deliveries are retried with Mastodon's backoff (16 attempts). A host that keeps failing is paused, starting at an hour and growing to a week.
Known limitations
- Likes, boosts, follow requests to remote accounts, media uploads and polls are not implemented yet.
- Collections expose counts, not members.
- Only
rsa-sha256-style keys are verified. RFC 9421 signatures are planned.