Note: this post has been revised to be split into two sections: a description of what happened, and my analysis. I hope to make it clear that, while I do not like ATProto in general, I am trying to make good-faith critcisms of specific design decisions and outcomes, and in fact, this post getting updoots on HackerNews appears to have gotten the attention of the team, so, mission accomplished. ref, ref My account has since been manually reinstated; this has not happened for any of the other users that have had this issue, as far as I know.
What Happened
Today, I tried setting up an ATProto account for use with Bluesky, with did:web instead of did:plc. Let’s walk through the process:
-
Set up the PDS software on a server I control. Because I use NixOS, this was very easy.
-
Create a did:web. This means creating a public-private keypair; I initially tried following this tutorial from Mai Lapyst, but it’s very out of date, and doesn’t include a critical step.
-
With that did:web, upload the
did.jsondocument to my webserver and set the appropriate DNS entries. Easy enough, except that I also had to set the CORS header for thedid.json. -
Create an account on my new PDS. I was able to get an invite and create an account, but it was in the “deactivated” status, and I couldn’t activate it. This had to be done by making requests manually with
curl, reading the error outcomes in the PDS’s logs on my server. -
Seek help in the ATProto Touchers Discord server, and at their advice delete the account.
-
Start over and re-create everything from scratch, correctly replacing the public key in my DID with the public key from
getRecommendedDidCredentials. -
Log into Bluesky (bsky.app) and get a “Profile does not exist error.”
It was at this point that I found this GitHub issue, which seems to imply that, since I deleted my (completely empty and unused) account, my did:web is blacklisted from the remaining mostly-centralized bit of the system, the AppView. The term for this is being “burned”, and it was later confirmed by some more experienced users that this is a known but undocumented behavior of the Bluesky AppView.
I had one of my friends who uses Bluesky take a look, and the failure mode is interesting. On Bluesky, I didn’t exist at all. (She could not see my likes, or my follow of her.) On Blacksky production, my display name and bio were visible, but not my posts. On Blacksky’s own AppView, it’s the opposite; my posts appeared under an “invalid” profile. I have been un-“burned” by a manual process, but not because of my support request; this post made it to the front page of Hacker News, and Bryan Newbold saw it there.
This is bad.
The Opinion Zone
So, a while ago, I wrote a post called “Key Management, ATProto, and Decentralization” in which I complained about ATProto’s approach to decentralization. Since then, Blacksky has spun up an AppView, which makes it theoretically possible to have an actually decentralized experience on Bluesky. This was my line in the sand, stated many times; I would make an account when and only when it was possible to do so without using anything running on Bluesky-the-company’s hardware. That’s now, so I figured I’d try it.
I use lots of systems I don’t love, like Signal, Matrix, and Mastodon. I use them because they give me access to social interaction with people I care about. ATProto, and specifically Bluesky, is the same; I have friends who don’t post anywhere else. Today, I follow them by RSS, but can’t interact with their posts. That’s where my motivation to use the network comes from, along with understanding how, and how well, the newly decentralized AppView layer works.
Very little of this process is documented. Sure, the individual endpoints are - kind of - but the only place the whole process is collected in one place is in the comments to this GitHub issue… which is closed as WONTFIX. The documentation for that getRecommendedDidCredentials endpoint that I missed reads in full:
Describe the credentials that should be included in the DID doc of an account that is migrating to this service.
Note that I am not “migrating”; this account is new. Plus, the JSON keys it returns are almost, but not quite, the same as those in a DID document, and the key it returns actually has to be edited by hand in order to be usable.
This is not good! did:web has been held up as the “less centralized” or “bring your own trust” option, as opposed to did:plc, and it seems like there has been very little effort to make it usable, certainly not for “normal” users.
But there’s another issue, a bigger issue. Why is a centralized “burn” able to completely prevent me from interacting with people using Bluesky?
You may be aware that Mastodon has a similar system. If you set up a Mastodon server and then delete the database, anyone you’ve already federated with won’t federate with you again, because you can’t prove you’re the same instance. It’s a genuine issue - but it wouldn’t have resulted in this, because I hadn’t even made a post on my now-burned did:web identity, nor followed anyone.
Even if I had, though, that would have burned a connection, not all connections. My experience would be degraded, but not ruined, and I could work with the admins of the affected servers to remediate it. You could say the same here, of course; I had to get my account back by Bryan Newbold happening to see this post on Hacker News. There is only, really, one connection that matters; maybe two, if you count Blacksky, but their AppView is not generally available yet. That’s centralization. I don’t understand how you could call it anything else.
I don’t like Bluesky, or ATProto; I wish we lived in a world were community-driven projects got megabucks and we were all self-hosting little social media servers for our communities. We don’t live in that world, so we have to interoperate with VC-backed, corporate social media. When those platforms call themselves “decentralized”, I think they should deliver.