ActivityPub over ATProto

albuic1 pts0 comments

ActivityPub Over ATProto

There's a joke in movement politics that if you have one Trotskyist (and you can replace "Trotskyist" with any number of other denominations), you have one Party; if you have two Trotskyists, you have two Factions; and if you have three Trotskyists, you have a party split.

It feels like that's the vibe the open social media space is in nowadays. People feel that they need to pick a side and defend it, preferring to eat one another's face rather than make sure the leopards don't. I guess in a way that's very social media. It's also very stupid.

I would like to relieve the tedium of this posturing by making a suggestion that everyone can hate together. Or, more seriously, I would like to go through a short exercise to demonstrate that it might not be the dumbest thing to pay a little bit more attention to interesting architectural details. This can set the stage for a broader discussion of social media on the Web.

This is just a sketch and it has issues. I initially wanted to prototype this but the situation at work is such that I have precious little bandwidth for prototyping (so I'm mostly dumping my notes onto this blog). Think of it as a design provocation, and the provocation is this:

With relatively little work, we could run ActivityPub atop an AT Protocol PDS.

I won't try to convince you that we could do that without making some modifications to the current state of either or both, but I would like to draw your attention to why this is something worth thinking about and, with any luck, convince you that we should be moving in that direction (even if not necessarily this exact combo). Note that I find it hard to believe that I would be the first person to think of this, but I failed to find anything. Maybe you think that I ought to be the only person to ever have this idea.

The first thing to understand is that the AT Protocol is not Bluesky. ATProto is intended to be a generic toolbox for building social media applications, and it arguably extends (or can readily be extended) beyond that into supporting general infrastructure for a Personal Data Server (PDS). In fact, the ATProto architecture is explicitly described in terms of a PDS and of that PDS being a user agent. While Bluesky have been clear that they intend to keep control over the app.bsky API routes that implement Bluesky atop ATProto, they have also been clear that the com.atproto routes are intended to be an open standard. (This has yet to get the governance to guarantee it, but I'm not in the business of asking for permission anyway.)

The reason I draw your attention to this distinction is because ATProto has interesting properties, notably in how it supports pluggable identity that doesn't depend on the server you use as well as signed data repositories. This puts power in the hands of the users and not (as is the case with vanilla federation) in those of server admins. It means that you can always guarantee credible exit, you cannot get locked in. By default, email-style federation (which is the underlying model for AP) is subject to capture, and indeed email is captured (~85% Gmail and migration is at the domain level or by kindness of the admins who might accept forwarding).

However, ATProto on its own doesn't do any social media. It's "just" a layer atop of which protocols can be implemented. This doesn't mean that it can be used to implement arbitrary protocols, but ActivityPub/Activity Streams has a very good indirection that makes that a lot easier: the Actor document. An actor is any entity that can have an activity, and can therefore be doing things on social. You can get an actor document from more or less anywhere, for instance you can look at mine by adding .json to the URL of my Mastodon identity. You could obtain it by resolving a handle to a DID, and finding that info embedded in the DID document.

The actor document has a neat feature: it gives you the URLs of the API endpoints for a variety of operations. That is to say, instead of expecting endpoints for the entire API to be at predetermined locations, it specifies arbitrary URLs for each one of them. After cutting some of the cruft from my Mastodon actor doc, we can see several of these listed there:

"@context": "https://www.w3.org/ns/activitystreams",<br>"id": "https://mastodon.social/users/robin",<br>"type": "Person",<br>"following": "https://mastodon.social/users/robin/following",<br>"followers": "https://mastodon.social/users/robin/followers",<br>"inbox": "https://mastodon.social/users/robin/inbox",<br>"outbox": "https://mastodon.social/users/robin/outbox",<br>"preferredUsername": "robin",<br>"name": "Robin Berjon"

This means that we can use this as a level of indirection to point to one's own ATProto PDS with ActivityPub routes:

"@context": "https://www.w3.org/ns/activitystreams",<br>"id": "https://mastodon.social/users/robin",<br>"type": "Person",<br>"following": "https://pds.berjon.com/xrpc/org.w3.activitypub.following",<br>"followers":...

social atproto https mastodon robin users

Related Articles