Continuing the discussion from Permissioned Data PDS Lexicons:
@rochebit.net, starting a new topic since the previous one was specifically about lexicons.
The permissioned data proposal does make space membership include full read / write access, but I think that is as it should be.
That said, I also want to enable all the different access patterns you’re talking about here. They are extremely important for the app me and my team are making, roomy.space, which is similar to Discord.
This has been basically my full concern for about the last couple months, so I’ll try to make the case that the permissioned space proposal is OK as is, and that we can still have the extra features we want with it.
This is something I need to turn into a proper, focused Leaflet at some point, but I’ll try to get the ideas out here first.
Write Access Is Way More Complicated
First of all, the issue with adding write access to the spec is that as soon as you need write access control, things get way more complicated. There’s all kinds of different ways you could decide to authorize writes and putting any one of them on protocol would be very opinionated and rule out changing it later, which is a problem.
It also works against the core ATProto idea of user’s having their data on their own PDS.
There’s no way that we could stop users from writing data to their own PDS if we wanted to. So if we still want to let people put private data on their PDS, we really can’t stop them from writing anything to it.
The proposal still allows write access to be “controlled” by AppViews by ignoring data that is not allowed / invalid somehow. This is similar to how AppViews work today on public data. They can’t just trust the user input, but they also can’t stop the user from writing to their PDS.
That’s OK for some things, but not for everything, like you point out. I’ll get into a way to handle strict access control like you are talking about without changing the permissioned data proposal further down.
The Proposal Adds Just Enough For Read Access Control ( And That’s Good )
The permissioned space proposal adds just enough to let us sync private data that is hosted on our PDSes. I think that’s good. It’s simple and doesn’t restrict the kinds of solutions that we can build on top.
It lets us make custom space hosts that can use whatever logic we want to create spaces and control who can read them, while still allowing the actual data to be hosted on the PDSes.
It fits the ATProto model really well.
Write Access Control Is Missing From Public and Permissioned Data
What we realized while evaluating our needs for Roomy is that write access control isn’t just missing from permissioned data, it’s missing from public data, too! There’s no way to make an “organization” or “community” account where you can control what gets written by whom.
Any time an app runs into this need, they have to put the data on the AppView and start treating it as authoritative, which causes difficulty with letting people host their own AppViews and generally goes against having all of our data on protocol.
I haven’t read through the whole thing yet, but this leaflet by Tangled touches on the challenges that exist because there’s no such thing as community-owned / access controlled data:
What if Bob nukes his account? Suddenly all bob’s work to that repo will disappear from entire network. This should not happen and obviously not an expected behavior in collaboration platform. For example, we don’t expect old contributor to be able to nuke all their codes and commits from the project without permission just because they want to. Current Tangled appview is working fine because we use our own DB as a source of truth collecting all events in real-time since the very beginning, validating them just as we received them.
So in general we have this issue where ATProto only has a concept of personal data, and there is no facility community / organization data. Personal data is simple, because you never need to do write access control beyond checking whether you are the PDS owner. It is hard to make an access control mechanism that works for every application, especially when every app can make its own lexicon which has its own semantics and needs its own access control rules.
Experimental Community Arbiter Service
So the solution that we’re working on is a generic authorization service that can sit in front of a PDS and provide access control for public ATProto repos, as well as act as a space host and provide access control for permissioned repos.
I’ve almost got a working prototype that uses the Rego policy language to let you create completely custom access control rules.
It works almost like an XRPC proxy that can be associated to a community / org DID and presents a standard ( work-in-progress ) API for managing group membership compatible with the permissioned space proposal.
It can then use that group membership in order to make policy decisions about who can write what to the public repo and permissions spaces, under that DID’s authority.
The cool part about this is that it lets us move authoritative data back on protocol, while not sacrificing on access control. The Rego policy is extremely flexible, and can even make XRPC requests to remote servers in order to determine whether access is granted for a particular request.
We’ve been calling the service the “arbiter” and I’ve been writing about our plans for it as it has developed, but I don’t have a good writeup on the latest plan with the Rego policies. You can see how the idea has been evolving by following the chaing of Leaflets if you want:
I’ve almost got a working prototype where you’ll be able to create new community / org accounts and control access to the public ATProto repo of the account with a customizable policy. It should also be able to act as an alternative to https://opensocial.community.
There’s a lot to figure out, but we think we’ve got a good base and are ready to start experimenting with actual use as soon as possible.
A great part about ATProto and the permissioned data proposal, in my opinion, is that it leaves the door wide open for us to do create things like making a custom arbiter for community data.
If this were to be specified in the protocol itself, then people would be forced to use a particular form of access control that may not work for everybody. But because it is left unspecified, we are able to come up with our own solutions.
Having to come up with our own solutions isn’t always the nicest, but I appreciate that we aren’t forced into a paricular model, and even if some people use our arbiter, since it is built on top of the existing protocol, other apps can be minimally interoperable with it, even though they may not know about the specifics of our extensions on top of the protocol.