Blogging & Open Web

ActivityPub for a Personal Website — What Federation Standardizes, and What It Leaves to You

ActivityPub for a Personal Website — What Federation Standardizes, and What It Leaves to You

ActivityPub for a Personal Website — What Federation Standardizes, and What It Leaves to You

A personal website usually speaks in one direction: the author publishes a page, and readers visit it. RSS, WebSub, and ordinary hyperlinks make that relationship more useful, but they do not turn the site into a participant in a shared social graph. ActivityPub starts with a different question: what would it take for one server to understand that another server has published, followed, liked, or updated something?

The answer is not “use one universal social-media application.” ActivityPub is a protocol with a data model around it. It defines important messages and endpoints, while leaving many visible and operational decisions to each implementation. That distinction matters for anyone considering federation for a personal site. It is possible to understand the architecture without assuming that every site needs to become a full social network.

Activity Streams Is the Vocabulary

ActivityPub is based on Activity Streams 2.0. Activity Streams provides a JSON-based way to describe objects and activities. An object may be a note, article, image, person, collection, or another type defined by the vocabulary. An activity describes an action such as Create, Follow, Like, Update, or Undo.

This is easier to picture as a sentence than as a database table: an actor creates an object, or an actor follows another actor. The JSON representation gives machines fields such as actor, object, type, and addressing properties. The Activity Vocabulary defines common types and properties, while the core specification describes their JSON serialization and collection model.

The vocabulary is extensible. That is useful because social applications do not all have the same objects or actions. It also creates a boundary: an extension that one implementation understands may be ignored by another. An implementation can therefore accept the shape of an object without offering identical behavior for every extension. Interoperability is helped by using common types when they apply, rather than inventing a new name for an existing concept.

ActivityPub Has Two Related APIs

The ActivityPub Recommendation describes two protocol layers:

  • Client to server: a client acts on behalf of an actor, such as posting an activity to that actor's outbox.
  • Server to server: servers deliver activities to actors on other servers. This is the federation part.

A server can implement one of these profiles without necessarily implementing both. That is an important correction to the idea that “ActivityPub” is one monolithic feature. A personal website might begin by publishing a machine-readable actor and outbox, while a larger service may also provide clients, authentication, moderation tools, and remote delivery.

Actors, Inboxes, and Outboxes

In ActivityPub, a person, organization, application, or service can be represented by an actor. The actor is identified by a URI and exposes an inbox and an outbox. The inbox is where activities addressed to the actor are received. The outbox contains activities produced by the actor, subject to the server's access rules.

There can also be collections such as followers and following. These are protocol objects, not necessarily pages that a human must see. A user interface may present them as lists, hide them, paginate them, or use a completely different design. ActivityPub cares that the relevant data and endpoints have the expected meaning.

For a simplified public post, the flow looks like this:

  1. A client submits a new object or activity to the actor's outbox.
  2. The server creates or records the object and determines its recipients from addressing fields such as to and cc.
  3. The originating server discovers the recipient actor and its inbox.
  4. The originating server sends the activity to that remote inbox.
  5. The receiving server validates and processes the activity according to its own rules.

This is a delivery model, not a guarantee that the remote server will display the content in a particular timeline. The receiving implementation still decides how it stores, moderates, ranks, hides, or presents what it receives.

Discovery Is a Separate Problem

A server cannot deliver to an actor it cannot locate. ActivityPub gives actors stable identifiers and endpoints, but account discovery often involves WebFinger. RFC 7033 defines a protocol for discovering information about an entity identified by a URI. A client sends an HTTPS request to /.well-known/webfinger with a query target and receives a JSON Resource Descriptor.

In practical terms, WebFinger can help map a human-friendly identifier to a profile or actor URL. It is useful to keep the boundaries clear: WebFinger is a discovery protocol, not a replacement for ActivityPub's activity delivery. It also has its own privacy requirements. Information exposed through discovery is easier to find, so a server should not publish personal data merely because it can put that data in a response.

After discovery, an ActivityPub client or server retrieves an actor or object using HTTP content negotiation. The Recommendation describes Activity Streams representations such as application/activity+json and the Activity Streams JSON-LD media type. A browser-facing HTML page and a machine-facing Activity Streams representation may refer to the same resource, but they are not the same document.

What ActivityPub Does Not Standardize

Protocols are often most useful when we notice what they intentionally leave open. ActivityPub does not prescribe a single timeline algorithm. It does not define whether a server must show chronological posts, recommendations, lists, or no timeline at all.

It also does not give every implementation the same account model. An actor might represent a person, a bot, an organization, or a service. The relationship between human users and actors is left to the implementation. One person may control several actors, and an actor may be automated.

Moderation is not solved by the existence of an inbox. A receiving server still needs policies and controls for spam, unwanted follows, impersonation, malicious content, remote blocking, and appeals. The ActivityPub specification's security considerations discuss validation, spoofing, recursive objects, spam, federation denial of service, and content sanitization, but those warnings are not a complete moderation product.

Authentication also needs care. The core protocol describes authorization and points toward mechanisms such as signatures, but a deployment still has to choose and implement an appropriate profile. The official W3C ActivityPub repository lists related WebFinger and HTTP Signature profiles as additional documents. A server should not treat a syntactically valid JSON document as proof that its claimed actor sent it.

Why This Matters for a Personal Website

For a personal website, ActivityPub is not automatically the next feature after adding an RSS feed. It introduces a new surface area: stable identifiers, public representations, remote requests, retry and deduplication behavior, access control, moderation, storage, and security review.

A cautious design might separate the decisions into stages. First, decide what should be public and which URLs are stable. Next, define a small Activity Streams representation for an article or author. Then consider discovery and read-only federation before accepting remote writes. Only after the threat model and operational costs are understood should a site consider follows, replies, likes, or arbitrary remote activities.

This ordering is not a requirement from the specification. It is an engineering judgment. The protocol makes it possible to join a federated graph, but it does not make the graph simple to operate. A small site may gain more from clear canonical URLs, RSS, WebSub, and an accessible HTML page than from accepting every activity another server can send.

Conclusion

ActivityPub is best understood as a set of agreements between servers. Activity Streams supplies the vocabulary; ActivityPub defines client-server and server-server interactions; WebFinger can help with discovery. Actors, inboxes, outboxes, collections, addressing, and HTTP representations provide the pieces from which federation can be built.

But federation is not the same as a finished social experience. The protocol does not choose a timeline, moderation policy, storage engine, account design, or deployment security model for us. That is both its strength and its cost. A personal website can treat ActivityPub as an opportunity to publish beyond one platform, while still asking a less fashionable question first: which parts of that relationship should the site actually be responsible for?

References

  1. ActivityPub, W3C Recommendation, Christine Lemmer-Webber et al., 23 January 2018.
  2. Activity Streams 2.0, W3C Recommendation, James M. Snell and Evan Prodromou, 23 May 2017.
  3. Activity Vocabulary, W3C Recommendation, James M. Snell and Evan Prodromou, 23 May 2017.
  4. RFC 7033: WebFinger, Peter Saint-Andre et al., IETF, September 2013.
  5. W3C ActivityPub repository, official project documentation.