Roles & access
Flat role-based access. A member can do whatever any of their roles allows. Reads are enforced per space; everything else is up to the app.
Flat RBAC
Authorization is flat role-based access control. A group defines many roles and gives each member one or more of them. Each role grants a set of standardized actions.
There are no deny rules or caveats, so authorization composes by taking the union of all actions a member’s roles allow. There is no precedence, hierarchy or evaluation order. If any of your roles grants invite, you can invite.
{
"$type": "group.opensocial.permissions",
"bindings": [
{
"role": "admin",
"actions": [
"group.configure", "space.create", "space.configure",
"space.delete", "role.assign", "eject", "invite", "admit",
"mod.read", "mod.resolve", "label", "takedown"
],
"assignable": ["member"]
},
{ "role": "moderator", "actions": ["mod.read", "mod.resolve", "label"] },
{ "role": "member", "actions": [] }
]
}
Roles are declared by role records in the members space and bound to actions by the single permissions record.
Actions
There are twelve actions. Each one guards a set of methods.
| Action | Governs |
|---|---|
mod.read |
See the moderation queue and subject histories. |
mod.resolve |
Resolve or escalate a subject, add notes. |
label |
Apply and negate labels, except !hide and !takedown. |
takedown |
Apply and negate !hide and !takedown. |
invite |
Issue invites. |
admit |
Approve join requests. |
eject |
Remove a member, bounded by assignable. |
role.assign |
Grant and revoke roles, bounded by assignable. |
space.create |
Create a space under the group DID. |
space.configure |
Change a space’s config, including its access record. |
space.delete |
Delete a space. |
group.configure |
Edit the profile, rules, roles and permissions. |
Bounded actions
Two actions are parameterized by the roles they apply to: assigning a role and ejecting a member. A binding’s assignable list names the roles its holders may grant, revoke or eject. With assignable: ["member"], a role can make someone a member and eject members, but it can’t create another admin or eject one.
Role conventions
Roles may carry conventions. An app like Bluesky may treat roles named admin and moderator specially and show badges or extra controls for them. Other roles may just be flair. A group is free to ignore any convention.
Read access, per space
Every space has an access record listing the roles that may read it. The host enforces this: it only lets a reader into a space if one of their roles is listed.
{
"$type": "group.opensocial.access",
"readableBy": ["member"]
}
Everything else is the app’s
Who may write to a space, pin a thread, post in an announcements channel or create an event is modality-specific. These are app features, and each is declared in the modality’s own lexicon within its space. Those declarations can still refer to the group’s roles.
This is deliberate. The group standard can’t know what “pin” means in every app, but every app can say “only moderator may pin” using the same roles the group already has.