Unsurprisingly to those who know me, this is a pretty exciting discussion for me! as the person who came up with Tranquils current approach to this issue. This is something I’ve wanted to see addressed for a while and Tranquil has been the way I could “just do things” and the results have been pretty good in my opinion. Tranquils delegated accounts continue to be one of my favourites of things I have done/contributed to in the atproto space since it means that we have something for this use case that works today and that I and others use, actively, for organisation and community accounts. And @bmann.ca mentions running a community instance here which, in my opinion, should be a fine stop gap until we can agree on a final form for all of this.
I think it’s worth going over Tranquils approach here since it’s prior work in exactly this space, uses only existing protocol mechanisms (though could, and IMO likely should, be extended to allow for better UX), and keeps the “my permissions travel with me” property that @essentialrandom.bsky.social is mentioning here. That was actually a really major consideration for me when designing it! Tranquils delegation has it’s roots in my ideas on how Tangled would best support “org accounts” and me believing that Tangled taking on the responsibility of mediating access to org accounts would be messy and has uncomfortable security implications if you ask me.
As an overview of delegated/org/community accounts in the Tranquil model: In Tranquil “delegated accounts” are accounts where the OAuth login method isn’t a password or a passkey or the like but rather a nested OAuth session with another atproto account that is one of the defined “controllers”. It’s just another OAuth login method. This means that, currently, using your delegated access to a shared account means logging in to a client as that account, at which point the delegated accounts PDS will ask you for your personal handle and then pass you on to your own PDS to authenticate there, then back to the delegated account to finalise the OAuth flow of the delegated account. From there on you have a broadly normal OAuth session with the delegated accounts PDS within the limits of your defined controller status (this is handled as OAuth scopes assigned to each controller and they’re only allowed to authorise OAuth sessions with credentials that are a subset of their controller scopes). Taking actions as the delegated account is thus just normal XRPC requests to the PDS. The PDS knows that the session is a delegated session and can scope access accordingly, and will (we don’t do this in Tranquil yet but it’s coming as part of a clean up of delegated accounts) add a act claim to the inter-service auth tokens that consuming XRPC services can, if they support it, read for info about the acting controller identity. The PDS will also keep an audit log of all logins and actions performed using delegation.
Tranquils approach to me has a few upsides to the one described there:
- It’s transparent to both client and XRPC services. Nothing other than the PDS the delegated account is hosted with has to change in any way for Tranquils scheme to work. This is how I can here and now use the
tranquil.farmaccount with delegated access through my personalnel.petaccount on every single existing and future atproto client. - It keeps the semantics of inter-service tokens broadly the same. An inter-service token signed by the signing key for
tranquil.farmremains, always, a token that’s used to take actions for that account, same for all inter-service tokens signed by thenel.petsigning key. - Per my first point, it requires to support or allowance from anything other than the delegated account. I don’t need a client to allow me to use delegation for me to be able to use
tranquil.farmwith that client. I can just do that becausetranquil.farm(or rather another controller oftranquil.farmwith high enough permissions) has allowed me to do it. - PDS proxying still works entirely normally for delegated accounts.
- The OAuth flow issues are naturally resolved by the fact that the scopes for the delegated session are just standard OAuth scopes. Your own account is only ever used by the delegation handling PDS for authentication of the controller, not for authorisation, that’s done with the existing OAuth infrastructure.
- Delegated access is always revocable to the same degree that non-delegated access is. Inter-service tokens of course still can’t be revoked but a PDS could invalidate a users session at any time if the delegation relation changes.
As a catch-all point: The Tranquil approach is designed to Just Work with the existing way of doing things. This means your delegated access truly does move with you, no matter the client you use. While keeping the door open for a “progressive enhancement” like approach to improved client-side UX around these accounts.
Not without a few downsides either of course! but these mainly come from not wanting to force clients to do anything specific to support this and I believe these downsides can all be addressed with client and broader PDS support. Namely: Having to log in to a dedicated community account session has it’s upsides in that it makes the distinction of when you’re acting as yourself, vs as the community account extremely clear. However it can also have some downsides UX wise. Clients can be supported in knowing about the delegation relationship to help this. Additionally the delegated accounts PDS can allow clients to authorise calls as the delegated account using a personal inter-service token. Similar to the approach taken for createAccount during migration. This would allow clients to only deal with a session at the controllers PDS, allows for the kind of short lived access to the delegated account described here.
I’m confident Tranquils approach isn’t perfect but I do believe it to be a strong contender and at the very least a strong starting point and reference point for future protocol work (which I agree with @dholms.xyz will likely be a bigger undertaking if it is to change things at the protocol level). If nothing else Tranquil shows that this problem space does have solutions that work here and now! Even if it’s not perfect.