Thanks for sharing @dholms.xyz! These are really good questions.
A conditional, cross modality scope?
This is tricky. Just kind of thinking out-loud, I see two aspects to it:
- The scope request that the app makes
- The consent screen that the PDS shows
I think it’s interesting that, while we do want a standard, it’s possible to change the consent screen, and have the PDS give somewhat more or less permission than exactly what was asked for, without changing the scope request itself.
I’m just thinking that does give us a little bit of freedom to experiment with dynamic consent screens. ![]()
Picture an “authoirty-picker”, kinda like the iOS photo-picker, where the user explicitly picks which communities an app sees across modalities.
I kind of like this idea. It feels similar to me picking which GitHub repos I’m granting access to when I connect my GitHub account to a cloud provider.
I think it would be great if the scope request could have semi-flexible “hints” that the consent screen could read from to determine which spaces to show by default.
I’m not sure how sophisticated the scope hints would need to be to capture this particular use-case. Just brainstorming possible scopes:
community:did:plc:abc1234: Request access to all spaces of particular communitytype:app.bsky.group: Request access to all spaces of a particular type in any community.community:*: Request access to everything - all spaces of all communitiestype:*This would also be access to everything.type:app.bsky.group community:*: Request access to all communities that have anapp.bsky.groupspace???
I don’t think that’s quite right because scopes should be additive, where having multiple scopes in this case actually hints at a lessening the access.
Just own up to the limitation. And say that if you want notifications to surface in the Bluesky app, then they need to be published in the Bluesky space. This doesn’t necessarily mean publishing the thing itself in the Bluesky space. Rather you could publish a pointer/envelope to the thing in the Bluesky space.
That definitely could work. And it’s similar to what I was imagining for cases where you want data in permissioned spaces announced on the firehose.
But I do feel like giving the user more control over what they grant an app access to is probably something we are going to need at some point anyway, so I lean towards the more sophisticated consent screen.
That does lead me to another thought, though.
Adding Apps As Members of Spaces
An interesting thought is that if the community wanted to, they could add the Bluesky app as a member of the space.
Whether this is appropriate is obviously going to depend a lot on the nature / social norms of the community, but it would give the Bluesky app full access to the space without requiring consent from the members individually.
Who runs an arbiter & who hosts a community?
I do think that having the apps run the arbiter is pretty reasonable.
How do users manage the complexity of the communities they own getting scattered across a bunch of different apps?
I think the good news here is that the community’s handle / DID resolves to the arbiter so it’s not like you can “lose” it. I think there are a couple possible scenarios for managing your community:
- You can manage the community in multiple different apps because those apps support the standardized management XRPC API.
- The app you are in doesn’t support the management API for your arbiter, so it has to redirect you to an app that does.
In scenario 2, maybe the arbiter itself has a generic UI that can be redirected to, or maybe there’s a “managing app” endpoint standard so that apps know where to send you to manage a community, and it could usually send you to the app that created the community in the first place.
Scenario 1 is ideal, if it’s possible to standardize on, but I think that could be difficult.
This is related to being able to migrate between arbiters, which I agree is crucial.
I drafted some lexicons that were meant to be the standardized API for scenario 1:
In summary:
- Have all arbiters provide the same ( base ) XRPC API.
- Standardize on a minimal concept of members and spaces.
- Allow spaces and membership to carry custom metadata
- Apps and arbiter migrations will be able to read all the data.
- Understanding the metadata lexicons is optional, but necessary to make informed modifications.
I think even if this doesn’t pan out, just having to go to the app that you created a community in to manage it wouldn’t be horrible. I would really love to have communities be meaningfully interoperable between apps, but I think that may have to be worked out similar to lexicons.
Starting out communities may not interoperate across apps for a bit, until we find the lexicons that we start the converge on.
Also, I do feel like it feels right that the app that I created my community with is the one that hosts it.
I’ll be very interested to see that! I need some more references to see if this rough shape I have for these lexicons is going to support the different use-cases people have.
We are also working on getting a working arbiter implementation up as soon as possible ( hopefully this week ), which I think is important to discovering whether the API makes sense in real use.
We realized that the challenge of community management doesn’t only apply to private data, but public data too. And our latest arbiter design can apply policies over any XRPC API, so we’re hoping to be able to trial some of this for public community / org accounts, while having it aligned with the permissioned protocol’s requirements.
Don’t stress, it’ll be messy
Just to remind myself & you all: this whole layer is much more forgiving than the protocol underneath it. That’s actually why we’re intentionally trying to keep the protocol layer so simple (just a member list).
![]()
I really appreciate how simple the underlying protocol has been kept. I think, as tricky as it is to have to figure stuff out, someone has to do it, and the base protocol being simple empowers the community to figure that out in parallel with each-other, just like lexicons!