MenuRoles & access

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.