I have a Bluesky identity that I registered primarily to follow someone that I happened to meet in person while stumping for the Rio Grande Plan[0]. I only have like five posts on it, but I would like to migrate that over to the same domain I already self-host Mastodon on. Bluesky has an option to have your handle on a custom domain, but that involves publishing a DNS record containing a did:plc whose keys are custodially owned by Bluesky. This is not so much an exit as it is an overcomplicated verification scheme.
My assumption is that if Bluesky wanted a better credible exit than ActivityPub, then we would need some way to rotate keys so that I could have my own PDS publish new posts on my existing identity and have other AppViews recognize that as the same kmeisthax that was previously using Bluesky as a PDS. The Mastodon exit is woefully inadequate, but at least if the admin cooperates, you can redirect your account and export your data. Everyone else on any other ActivityPub instance will see the same thing. As it currently stands, ATProto has a great way to migrate between AppViews[1], but no way to migrate off an uncompliant PDS.
[0] The Rio Grande Plan is a citizen-led movement calling for burying the heavy rail corridor going through Salt Lake City.
[1] ActivityPub is actually really lousy at cross-app interaction. If you're on a Mastodon instance, there is no way to participate in a Lemmy forum. Mastodon does not understand how to send the correct ActivityPub messages that Lemmy expects; and there's no protocol for Lemmy to tell Mastodon to publish certain ActivityPub messages on its behalf.
Show me the ATProto server that can integrate with BlueSky.
Can you? The same Glitch that shut down last year? https://blog.glitch.com/post/goodbye-glitch
Regardless, ActivityPub and ATProto have different designs and goals. Your question is akin to comparing a helicopter and an airplane.
There's no such thing as a "ATProto server". How complicated it is, and the trade-offs it made are valid criticisms of it. It all depends on what exactly your goal is as a participant of a distributed social network.
Want your own AppView so you can have nekusar.net and post your messages and people on BSky see it ? https://github.com/blacksky-algorithms/atproto
ActivityPub zealots would do well to calm down for one second, this can't be good for your heart man.
Honestly my main question here is "If you disagree with various ActivityPub instances' defederations, you can get around this by starting your own instance that federates with everything; is there an equivalent for bypassing Bluesky's moderation decisions?"
If you just want to post messages on your website that get syndicated to BlueSky (as blog post links or full threads or whatever) you could have your website server make API calls to your PDS (whether that's self-hosted or not).
If you're talking about building your own custom BlueSky app, "AppView" is not synonymous with "viewer app"; basically it's an "AppView" because it provides a "view" of the network necessary to power an end user "app". I.e. it holds a copy of every single post, repost, and like, so you don't have to. Your custom app would simply make requests to the logged-in user's PDS, which routes most of those requests to that user's preferred AppView.
If the thing you want to own is your identity and data, you can fairly easy run a PDS yourself. If the thing you care about is different moderation decisions, you can run your own labeller (moderation system) or subscribe to another someone else has made.
To 'own your data' you just need a PDS, which should be cheaper to run than an ActivityPub server
To build an app you need some of the more expensive parts
¿Por qué no los dos?

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",
"id": "https://mastodon.social/users/robin",
"type": "Person",
"following": "https://mastodon.social/users/robin/following",
"followers": "https://mastodon.social/users/robin/followers",
"inbox": "https://mastodon.social/users/robin/inbox",
"outbox": "https://mastodon.social/users/robin/outbox",
"preferredUsername": "robin",
"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",
"id": "https://mastodon.social/users/robin",
"type": "Person",
"following": "https://pds.berjon.com/xrpc/org.w3.activitypub.following",
"followers": "https://pds.berjon.com/xrpc/org.w3.activitypub.followers",
"inbox": "https://pds.berjon.com/xrpc/org.w3.activitypub.inbox",
"outbox": "https://pds.berjon.com/xrpc/org.w3.activitypub.outbox",
"preferredUsername": "robin.berjon.com",
"name": "Robin Berjon"
}
Success? Not quite.
I know you're sitting on the edge of your seat, biting your nails, for some of you clutching your pearls waiting to hear if we can just run ActivityPub over ATProto with just a bit of JSON tinkering and an ATProto app, without changing either spec. The answer is: not quite, but it's not so far as to be unbridgeable or even impractical.
The first issue is that an XRPC nsid (e.g. org.w3.activitypub.inbox) can either be a query (GET) or a procedure (POST) but as far as I can tell, not both. But the ActivityPub inbox property has to support multiple methods. Setting aside perennial debates over REST versus RPC (yaaaawn), this is not a major problem to bridge. Either the actor document could be update with separate properties for different methods (that can point to the same URL for non-ATProto implementations), or XRPC Lexicons could be change to support overloaded methods. The only thing standing in the way of a bridge here is that people get religious about this decisions. In the practical world, it's a relatively easy fix.
A second issue is that the identity and handle systems aren't fully aligned. I believe that nothing prevents com.atproto.identity.resolveHandle from resolving @robin@mastodon.social just as it resolves @robin.berjon.com, it might simply drop the leading @ and replace the other by a ., then use DNS to resolve the DID. This is even compatible with an IndieWeb ActivityPub in which actors have their own domains (as is relatively common for ATProto users). It should be possible to have an actor document also point to the DID, and the DID document link back to it for good measure.
(I'm not going to touch on the limitations of DIDs or specifically issues with did:plc here since they don't affect integration. I've been wondering if DSNP may offer the right foundation for a DID method, but that's a topic for another time.)
And… that's it? My bet is that, since I haven't had the chance to actually implement this end to end, I'm probably missing some snags. But at first blush this is more feasible than you would think from the bitter online debates.
Overwhelmingly, our experience of social media is in siloes. They are closed environments that are designed to keep you on the inside and that integrate very poorly with the rest of the world.
Both the Activity* standards and ATProto break this siloing in different ways. Activity* are built around URLs and can sort of "socialise" more or less anything on the Web, which is great, but they don't touch the underlying substrate. The expectation tends to be that either you run your own server (which isn't for everyone) or you have to join a federated server, which tends to put you at the mercy of an admin (and, as some people are unfortunately finding out, not all admins are great). ATProto, on its side, provides a good initial foundation for an extensible PDS designed around user agency and credible exit. This means that your online presence can be custodially hosted (so you need not worry about running a server) but if you don't like your host, you can be guaranteed to be able to take your content elsewhere (verifiably) and nothing will change, you won't even need to update your handle or set up redirection.
Which is to say: they solve different problems and the solutions are complementary. By taking the small steps to make these two worlds compatible, we get significantly more from both.
Seems like it'd be worth a shot!
This post is part of a series on reimagining parts of the Web. You can read the other entries in the series at:
Many thanks to the following excellent people (in alphabetical order) for their invaluable feedback: Amy Guy, Benjamin Goering, Ben Harnett, Blaine Cook, Boris Mann, Brian Kardell, Brooklyn Zelenka, Dave Justice, Dietrich Ayala, Dominique Hazaël-Massieux, Fabrice Desré, Ian Preston, Juan Caballero, Kjetil Kjernsmo, Marcin Rataj, Margaux Vitre, Maria Farrell, and Tess O'Connor. Needless to say, anything dumb and stupid in this article is entirely mine.