The Case For Universal Login and "Off-Protocol" Services

Noe this post is also available on Leaflet:

For the last year, we have been working on Roomy with a clear integration to the ATProtocol. At the same time, we’ve also had a distinctly “off-protocol” strategy for data handling: we don’t store Roomy’s canonical data on the ATProto PDS. The reason for this is that the PDS because has shortcomings, such as a lack of private data, that make it unsuitable for Roomy’s needs.

This is actually completely natural! Bluesky’s needs, such as distributing individually authored content to the world where it can be aggregated on a global scale, is not at all similar to Roomy’s needs. The ATProto PDS is designed in a way that is very effective for many different applications, but a richly collaborative, realtime community space, is not one of them. Neither is it designed as a media server or a git server.

It’s unrealistic to assume that the PDS is going to be suitable for every kind of application, and that is no failure on the part of the PDS! It’s just not possible for one kind of server to do everything.

The case I want to make today is that having different kinds of service providers other than the PDS should become a completely normal and well facilitated part of the ATProto ecosystem.

Note: Below I’m going to talk about some of the ways that Roomy works, but not all of these features have been deployed yet. I’ll be discussing how Roomy is going to work soon if not already.

We Are Making a New Kind of PDS

Two days ago we realized that with Roomy we were not merely making an “off-protocol” app, we were making a new kind of PDS.

When I think about what makes the PDS important to me, it’s summed up in three major points:

  • The PDS can be self-hosted or hosted by a provider,
  • You can migrate your PDS hosting between providers,
  • And there is an API that I can use to access all the data on my PDS.

These three things are what give users freedom.

The Leaf server, which we use to power Roomy, provides all of these features just like the PDS does, and users will have just as much ownership of their data using Roomy as they will using Bluesky. The only difference is the API.

Roomy Shouldn’t Have to Host a PDS to Inter-op with Bluesky

A crucial component of this is identity. We need you to be able to sign-up to Roomy, without ever having created a Bluesky / ATProto account.

We also want you to be able to take your Roomy account, and login to Bluesky with it.

But today this requires us to host a PDS for Roomy, and I’d argue that shouldn’t be necessary.

Roomy’s Leaf server implements all of the user storage features that it needs, and there’s no functional reason for us to host a PDS other than for authentication purposes.

I don’t think that an entire PDS should be necessary just to do authentication. Roomy can create a DID for our users, and allow them to manage their account, without needing a PDS.

What Universal Login Could Look Like

We’re imagining a scenario where we could have universal web login in a way that doesn’t restrict you to using an ATProto PDS, and that still gives you the awesome, “login with your internet handle” experience in an inter-operable way.

For example, lets follow Alice’s journey which starts by registering a new account with Roomy.

DID Creation

The first thing Roomy will do is create a new DID on the plc.directory. Just like when you create an account on a PDS, the Roomy server will create a rotation key to manage PLC records.

Services & Verification Methods

Instead of creating an AtprotoPersonalDataServer service, it will create two services:

  • A LeafServer that will be used by Roomy
  • A WebAuthServer that will be used to perform authentication handshakes.

Both of these will also have corresponding verification methods and keys:

  • The Leaf server will use its key to sign records stored on the server and to authenticate itself when it sends responses to clients.
  • The web auth server will use its key to authenticate the user, very similar to how the PDS authenticates users today.

By splitting the data storage service from the authentication service, we remove the unnecessary dependence on an entire PDS, when we are are already providing all those features with our Leaf server.

Logging into Bluesky

Now what happens when Alice wants to use her Roomy account to log into Bluesky?

Today you can’t even begin because Bluesky asks you for a PDS host up front on the login page instead of looking it up from your web handle.

In our hypothetical scenario, though, Bluesky will allow Alice to put in her handle, alice.roomy.chat, and Bluesky will resolve that to her DID document to find that, while she has a WebAuthServer registered, she doesn’t have a Bluesky PDS.

Bluesky will start by authenticating Alice using the WebAuthServer’s API. Once they are authenticated, then Bluesky can tell Alice that she doesn’t have any PDS hosting services registered for her account.

Because Bluesky offers PDS hosting, though, it can redirect to Alice’s WebAuthServer with something like an OAuth scope request, to have Alice confirm that she would like to register Bluesky as her new PDS hosting provider. If alice confirms, the WebAuthServer can update Alice’s DID to list Bluesky’s PDS server as her PDS host.

Now she can continue to use Bluesky with Bluesky’s hosting, even though she is using her Roomy account!

Roomy’s Not the Only One

I think Roomy’s need to make a custom “PDS” is not an isolated case. Already we have tangled.sh offering git hosting and needing to use a custom “Knot” server, and we’ve also got stream.place and community discussion around having a Media PDS / Service as a kind of PDS “sidecar”.

Media PDS / Service

Private data is another use-case where having a secondary PDS or service of some sort may be our best road forward.

I think this is good! We just need a way to make the ATProto PDS one among multiple kinds of services offered to “universal web ID” users.

Maybe we could even get to the point of logging into Bluesky with a Mastodon or other ActivityPub account, if it wasn’t a requirement for Mastodon to literally run an entire PDS just for auth purposes.


Not being able to use the PDS for an app shouldn’t have to give the impression that you “don’t own your data”. The PDS isn’t the only server that can provide alternative hosting and data migration. I think we just need a way to make sure that authentication is still supported even for non-PDS servers.

Disadvantages to Multiple Services

While I firmly believe that having multiple services is essential, it’s worth acknowledging that there are some disadvantages to multiple servies.

The biggest one is that different services have different APIs, so apps that want to inter-operate with those services will be required to use those different APIs.

This, though, is just a fact of life. If you have different needs, you may need a different API. Making everybody to use the same API isn’t going to improve the situation when new APIs are actually needed.

I think the goal would be to have a relatively small number of core services that most apps could use, and only for special use-cases would new servers need to be created.

For example, Roomy’s Leaf server is focused on creating realtime community spaces, and it is actually app agnostic. It could be used by other ATProto apps where it fits their needs.

It sounds like the media service discussed on the community forum would be another re-usable service that many different apps could use.

Conclusion

As a community I think we are going to need more than the PDS, and maybe there’s a chance we could figure out how to make that happen in a seamless way where users can optionally self-host, yet still be able to login to all of our hosted apps with different needs easily.


I know there are a lot of details that would need to be figured out to make this work, and we’d need to get buy-in from Bluesky if we wanted you to be able to actually login to Bluesky from a DID that doesn’t have a PDS service yet.

But I find this idea quite inspiring, and would love to get some community feedback on it.

Postscript: Universal Profiles

This is all somewhat related to a recent interest in the ATProto community to figure out how to manage a cross-app profile.

Universal profiles on the open social web

If you log into Roomy with, for example, a Tangled account, there isn’t a standard profile that Roomy can look for to get basic stuff like your name, profile, description, and links.

While we could just make a standard profile lexicon and stick it on the PDS, I think that it would be far better to put a URL to a profile JSON or something similar as a service in your PLC record. We could still define the format with a Lexicon.

That way we have a universal profile definition that doesn’t require hosting a PDS. It’s something that anybody can do regardless of app or protocol, as long as they use DIDs.

8 Likes

Excellent write-up! I’ve also highlighted this concept to separate authentication from a PDS awhile back. It artificially limits the innovation that can happen within the decentralized AT protocol. A single pds is also an artificial and unnecessary limitation. The elegance of a web server is it’s simplicity in defining primitives that continue to be extensible not limiting decades later. I feel these unnecessary constraints are a blindspot to Bluesky and others who’ve been close to the technology. The failure to listen to constructive and complimentary feedback from outside voices is unfortunate and could undermine the evolution of the protocol. There is a lot of value in listening to external voices who’ve been architecting solutions over the last few decades. I’m all in on a future that wrestles back control of the Internet from corporate clutches. Decentralization with interoperable open standards and building blocks holds a lot of promise in helping to achieve that goal. AT protocol has the potential to be a major component but it’s limitations need to be openly debated in order to evolve beyond Bluesky centricity in my opinion.

I think that combining accounts with data storage is a key win of ATProto.

And I think auth needs to be “next to” the data.

So as long as a system does auth and data it can participate (but at that point, you are providing the component we currently call a PDS).

You already say that Leaf is going to provide data and storage. So yes, to participate as first class participants you will need to implement the interfaces that ATProto requires.

You are “hosting a PDS” - it’s just one you built
yourself.

And yes, you need to provide people with an ATProto account to participate in the ATProto network.

I think this is orthogonal to off protocol needs.

I DO think that other services being registered in the DID doc is a good idea! You can totally run a network of leaf servers.

I don’t think the auth layer is one that is easy to swap out or make interoperate - your example flow with Bluesky needing to make changes and have some other auth system doesn’t sound acceptable from an implementation or UX view.

I don’t think implementing PDS endpoints is that big of an ask for first class participation in the network.

1 Like

@thisismissem.social pointed out to me that the authorization server for different services in you DID document may be different from each-other, and that the authorization server is actually looked up by checking for metadata on the service endpoint, not inside the DID doc.

I didn’t realize that was how it works, and that makes a lot of sense, but I think what I laid out still remains mostly the same conceptually.

I’m realizing that what I was describing essentially amounts to having something like Domain Connect for the DID document: a standardized way for providers to add services to your DID document with your consent. It may not need to be a full-blown auth server, being that different services may have different auth servers.

I’m not exactly what that looks like if you have an app that needs to authenticate to multiple services, though. It could be frustrating to have to login to multiple backend services if they used different services. So it would probably be preferable if there was just a single authentication server.


It’s worth noting that for now Roomy will be running a PDS, and we’re perfectly fine with that.

Personally I think having a universal, self-hostable web login where you can use your domain as a handle is incredibly useful and important, and that it would be crucial for Bluesky / ATProto, having been the first ones to make the practice somewhat “mainstream”, to support it if it’s to have much hope for catching on.

Requiring you to host an ATProto PDS just to have a universal web login seems completely unnecessary, but ATProto wasn’t necessarily trying to provide a universal web login anyway.

I understand wanting to have some kind of a baseline API, but having the baseline functionality be defined by the needs of Bluesky, and to not have private data included in that baseline, seems hard to justify as the API that all web sign-in providers would need to provide. ( Again, maybe that’s not what ATProto wants to be anyway, so that’s fair. )

Maybe what I really want is just IndieLogin + “Domain Connect” for DIDs. I had just kind of accidentally stumbled upon what seemed like a very interesting tweak in the relationship between service providers and your web ID that seemed to be very close to my idea of the ideal scenario if we could make it not ATProto specific.

This is something that would require very broad buy-in to be useful, though, so it may not be more useful than a thought experiment unless a lot of people think it’s a compelling direction.

1 Like

It seems to me that this whole thread can be boiled down to this:

Services that only want to use AT Protocol for account identity need a way to to onboard new-to-atproto users without taking on the burden of hosting the user’s PDS.

As one also building such a service, we too would love to see a solution this. In our case, every client is required to have its own “delegated” keypair, so authentication can be done by the client signing over messages with this key pair. (No additional services using OAuth required.)

Here’s a sample DID after onboarding with our service (ATSMS):

The problem is that it is not a valid AT Proto account identifier because:

  • A valid signing key (one with id ending in #atproto) is required for atproto functionality, and an account with no valid key in their DID document is broken.
  • A working PDS is required for atproto account functionality, and an account with no valid PDS location in their DID document is broken.

That is, it is a valid decentralized identifier, just not a valid AT Protocol account identifier. The easiest way to fix this, to just add the AT Protocol PDS. Ideally, we could just leverage a third party provider for this, is anyone doing this yet?

The other option—the one you are pursuing—is to investigate a change to the AT Protocol such that authentication could be done without requiring a PDS. This would require relaxing the constraint that the AT Protocol DID have a PDS service specified, in addition to leveraging some other way to authenticate using the #atproto verificationMethod key. To me, this feels like it pretty big departure from AT Protocol.

2 Likes

This isn’t the first conversation I’ve seen this month involving AT app developers being skeptical that the easiest way to facilitate registration is to host their own PDS on the side:

I am inclined to agree with Boris on this from a protocol/intent perspective:

But I think we definitely have to make this more intuitive, both because there are implications down the line for hosting user content from another AppView that developers might not want, and because this seems to be at least a small blocker to prototyping at the moment. So I don’t think we’ve fully solved this yet.

2 Likes

I can definitely agree that this is a big part of it.

I admit that I’m not 100% sure what I’m looking for in it’s most focused form and that I may have conflated my user story with an incomplete implementation idea.

I think fundamentally I want to be able to take my web ID with me into various different apps freely, without forcing those apps to provide infrastructure they don’t need.

I feel like I should “in a perfect world” be able to log into Roomy and Mastodon with the same DID that I log into ATProto with, and as I log into new apps, if they require services that I don’t have yet, there should be an easy way for me to register for those services from some provider, and this process should be easy to understand for the user.

My universal ID should allow apps like Bluesky and Roomy to do essentially an OAuth scope request that says, “Roomy would like to register a Leaf service provider for your account” or “Bluesky would like to register an ATProto service provider for your account”, and those services will then be added to my DID. At that point, other Leaf and ATProto apps will use those registered services.

Coming back to this:

It seems OK to me to need to explicitly register with a PDS provider like Bluesky, if the app you are using doesn’t want to be responsible for PDS hosting, but the app should be able to create a DID, or use whatever DID the user provided, without it having to have a PDS service endpoint first, and then go register for a Bluesky PDS with it.

I think maybe this doesn’t require having a specific auth server like I initially thought. Different services can have their own auth server, and the PDS can continue to be it’s own auth server.

For instance, what if you logged into an app for composing and sending emails. It might require you to have an SMTP service registered. That SMTP service would probably have it’s own auth server completely different from your other services. That’s OK, and when you try to log into the email composer app, it will lookup the OAuth metadata and redirect to whatever auth server that your particular SMTP service uses.

I think maybe the only missing component to making that possible is a standardized API / flow for managing the services registered on your DID.

Technically we can use ATProto for this today if your DID is managed by a PDS, but I think it could warrant its own standard so that a whole PDS isn’t required.

Honestly, though, being that things work pretty well right now, it might not be worth the effort.

1 Like

Strongly disagree with this sentiment. It is a huge lift to ask app builders to host user PDS.

Companies like Auth0 were born just to simplify the auth component for app builders, let alone hosting all other AT Protocol data. I’m barely able to get our MVP out the door, I don’t also want to deal with infra to host a PDS.

When this network grows to 100s of millions of users, we will see companies fill this need, just like Auth0 filled the need for developer tooling around authentication. The question is what do app builders do in the mean time?

For what it’s worth, we will absolutely be making it easier to just “register with BSky” for any new app (and publishing examples to help with this):

The question of whether you want to host a PDS on your own is an important one that has implications for data sovereignty and user choice, but in the perfectly reasonable case that you don’t want to do that, there is currently one very straightforward option that we (intentionally) minimize when trying to describe this problem space.

What I’m not convinced of is that there’s a real use case for an “auth-only” PDS — i.e., you don’t want to auth with BSky or another large provider but you also don’t want to host user data.

3 Likes

Do you happen to know if part of your work will involve allowing app builders to add additional services/keys and rotation keys prior to DID being created?

What I’m not convinced of is that there’s a real use case for an “auth-only” PDS — i.e., you don’t want to auth with BSky or another large provider but you also don’t want to host user data.

With AT Protocol, you are effectively authenticating with yourself, so I’m not sure I understand what you mean by “auth with BSky or another large provider”?

PDS hosting is a trade off of building equivalent systems yourself.

It really is not hard to run a PDS and create accounts on the fly (see Tangled as one that has decided to go this route).

I know of at least one person planning out an Auth0 like service who will run a PDS for you plus some other things … but that’s just a slightly different build vs buy situation.

And of course, apps will start by NOT running a PDS. They decide to run one because it gives them smoother UX for new signups (or whatever reason makes sense for them).

A lot of us ATProto folks most explicitly don’t want that, and consider “Login / Register with Bluesky” to be a failure mode…because you absolutely will “win” and the ATmosphere loses. So thinking about how to brand this and roll this out so it’s a win for everyone is the challenge.

Representing Bluesky-the-product, you should totally work on this! But it doesn’t solve the ATProto branding and adoption problem.

4 Likes

Snapshot of recent discourse:

3 Likes