Contribution Data in atproto

Given the need for custom sync I don’t know that what I’m about to describe is relevant to your use-case, but I would like to address the idea of contribution-driven data more generally.

This is exactly the kind of data that Roomy is concerned with because, beyond chat, it aims to provide communities “gardening” tools for long term cultivation of knowledge, including forum-like threads and wiki-like pages.

While different communities will have different needs and this will need to be configurable, threads and pages should usually not be able to be deleted without notice by community members after “contribution” to the community space.


But we actually think that the permissioned data proposal is perfectly fine for this!

In this case the Roomy “guild”[1] is represented by a DID acting as the space host for permisioned spaces.

Each channel, thread, and wiki page is it’s own permissioned space, and instead of generally expecting everybody to write to their own perm repos in the space, we’re actually expecting records to be written to the guild’s perm repo under the guild DID. This makes sure the community always has the data, and also allows the admins to moderate the space.

There is actually no reason to stop a user from writing copies of the records to their own perm repo too, so that they have a copy of their data if the guild chooses to moderate or delete their content.


The obvious challenge in this case is that we need to allow multiple writers to a single repo which is not an existing pattern in ATProto.

That’s why we’re working on an “arbiter” that will sit in front of an XRPC API, such as the PDS’s permissioned data API, and enforce a very configurable policy written in Rego, that can be customized per-guild.

So the arbiter sits as a middleman in front of the space host to allow anybody to contribute to the chats, wikis, etc. while enforcing rules like “you can only set your own DID as the author of the chat message”, “only team members can use @everyone mentions”, “only admins can delete chats by other users”, etc.

The nice thing about this is that it’s just a normal ATProto repo to any other app. The only thing that changes is that writers to the repo are required to send their request through the arbiter, instead of directly to the PDS, because they are not writing to their own PDS.


Any AppView could actually do the same thing the arbiter is doing if it wanted to. The PDS just become’s the AppView’s canonical datastore, living on protocol instead of in Postgres or something like that.

The hope with the arbiter, though, is to make it easier to use this “community / organization owned” data thing, on protocol, so that we don’t need everybody to re-implement access control for the PDS / permissioned repos and so clients can have a relatively standard way of issuing writes to repo data through an arbiter.


Again, maybe this doesn’t help you if you already determined that you need custom sync, but as far as contributed data in general, I don’t see that it necessitates a break from ATProto once permissioned data lands.


  1. unfortunately Roomy “guilds” are called “spaces” but that makes it so much harder to talk about now that perm data also uses the term. :sweat_smile: ↩︎

4 Likes