Federated Groups - Feature Specifications & Issues

Copy Markdown View Source

Federated groups enable self-governed spaces where members from different servers coordinate, collaborate, and organize around shared topics without platform lock-in.


Implement group creation and settings

Users with appropriate permissions can create, manage, and delete groups with customizable settings.

  • [x] Create new group with name, description, icon, and banner image
  • [x] Edit group metadata (name, description, images)
  • [x] Lock/archive group
  • [x] Delete group and handle cleanup (member removals, content deletion) - soft delete only
  • [ ] Set group code of conduct and rules
  • [x] Configure membership & privacy settings (Open/Visible/Private presets)

Related Areas: Authentication, Permissions, Database Schema


Implement member joining, leaving, and role assignment

Members can join groups, leave at any time, and admins can manage membership, roles, and permissions.

  • [x] Users can join open groups with one click (after reading code of conduct)
  • [x] Users can request to join moderated-join groups
  • [ ] Mods can approve/reject join requests (-> UI structure exists but workflow incomplete)
  • [x] Mods can invite specific user to groups (via Bonfire.Invite.Links)
  • [x] Members can leave groups at any time
  • [ ] Mods can remove members from groups
  • [x] Mods can assign member roles (moderator, X, Y, member) - via boundaries integration
  • [x] Define permissions per role (post, edit, moderate, curate, invite, delete group)
  • [x] Display member list with roles and join dates
  • [x] Sidebar navigation: Shows user's groups with nested hierarchy
  • [x] Star favourite groups/topics for easy access (uses bookmark functionality)

Related Areas: Permissions, Notifications, Federation


Issue 3: Group Feed & Posts

Members can create posts, discussions, and threaded conversations within a group, separate from their personal feed.

  • [x] Post content within a group (create text post, media, etc)
  • [x] Posts optionally appear only in group feed (and not profile timeline)
  • [x] Reply to posts with nested threaded conversation view
  • [x] Edit and delete own posts
  • [ ] Mods can remove posts from other members
  • [ ] Mods can pin important posts to group top
  • [ ] Search posts within group

Related Areas: Database, Feed Algorithms, Permissions, Federation


Channels

Groups can have multiple channels (topics/rooms) for different topics, allowing members to organize conversations without everything collapsing into one feed.

  • [x] Mods (or members with permission) can create, edit, delete channels within groups
  • [x] Channels have names, and descriptions
  • [x] Channels have a parent group (or channel), and can be linked to related channels/groups
  • [x] Can post within a specific channel
  • [x] Channel mentions in posts creates links and posts or submits to channel
  • [x] Members can browse and filter by channel
  • [ ] Channel membership & privacy settings (see dedicated issue)
  • [ ] Optional: Permissions per channel (who can post, view)

Related Areas: Database Schema, Permissions, UI/UX


Group Discovery & Exploration

Users can discover and explore public/open groups based on interests, topic, or recommendations.

  • [x] Directory of public groups/channels (browsable, searchable, filterable)
  • [ ] Filter by category, topic, activity level
  • [x] Display group info (size, description, recent activity)
  • [x] Search groups by name or keyword
  • [ ] Recommended groups curated by instance admins
  • [x] Join button or request flow from discovery page (after reading code of conduct)
  • [x] Breadcrumb navigation: For tree hierarchy display

Related Areas: Search, Recommendations, UI/UX


Group/Channel Visibility, Membership & Participation Settings

Groups can be public, private, or unlisted with fine-grained control over who can see content.

Visibility:

  • [x] Public groups: discoverable, non-members see group info and posts are public by default
  • [x] Private groups: non-members see minimal info and posts are private-to-members by default
  • [ ] Unlisted groups: not listed in directories, minimal info visible if you have the group link

Membership & Participation:

  • [x] Open: anyone can follow, join, and participate
  • [x] Semi-open: anyone can follow, and submit posts to mods. Only members can post directly. (partially implemented)
  • [x] Closed: anyone can follow, but joining and participation requires requesting-to-join and being approved (or being invited)
  • [ ] Invite-only: Following and joining require being invited first

Federation:

  • [ ] Group archipelago: control which remote servers/actors can see/join (blocklists and allowlists)

Related Areas: Permissions, Federation, Database Queries


Implement group-level moderation tools

Admins and moderators can manage content and enforce community standards.

  • [x] Standard content flagging/reporting workflow
  • [ ] User can choose to report to group mods and/or instance admins
  • [ ] Moderators can approve submitted posts
  • [ ] Moderators can hide posts
  • [ ] Moderators can remove members
  • [ ] Moderators can temporarily suspend members (optional)
  • [ ] Moderators can lock discussions
  • [ ] Moderators can pin discussions
  • [ ] Moderation log visible to mods and instance admins
  • [ ] Bulk actions (eg. hide multiple posts)
  • [x] Block users or entire remote instances at group level
  • [ ] Configure keyword filters

Related Areas: Permissions, Notifications, Reporting, Federation


Enable groups to federate with Mastodon and classic platforms (incl ATproto with BridgyFed)

Group posts and activities appear in remote fediverse platforms; remote users can interact at a basic level.

  • [x] Posts in group federate as regular ActivityPub activities (with author as the original creator and group actor "Announces" the post)
  • [x] Remote users can [request to] follow and unfollow groups (follow/unfollow may act as joining/leaving depending on group settings)
  • [x] Remote users can see posts from groups they follow in their feeds
  • [x] Remote users can reply to group posts
  • [x] Remote users can @-mention groups (which gets posted into the group or including in submitted posts queue for moderation, or only shown to mods depending on permissions)
  • [x] Remote users can discover known groups via search

Related Areas: ActivityPub, Federation, Serialization


Implement federated group features compatible with "threadiverse" and Mobilizon/Peertube/etc

Bonfire instances and compatible fediverse apps can participate in supported group features.

  • [ ] Discover and document how existing implementation federate group membership and activities
  • [ ] Test interop with Lemmy, Piefed, Mbin, NodeBB, Discourse, Mobilizon, Peertube, etc
  • [ ] Progressive enhancement: features unsupported by remote apps degrade without breaking

Related Areas: ActivityPub Spec, Standards, Federation Protocol


Implement full federated group features using ActivityPub extensions

Bonfire instances and compatible fediverse apps can participate fully in group features (members from multiple servers, role sync, etc.).

  • [ ] Review, iterate as needed, and implement FEPs (Fediverse Enhancement Proposal) for groups
  • [ ] Participate in groups task force of the Social Web Incubator Community Group (SWICG)
  • [ ] Define and document data types and properties
  • [ ] Remote members join/leaving/suspend
  • [ ] Reporting & escalation in groups (see dedicated issue)
  • [ ] Cross-instance groups moderation (see dedicated issue)
  • [ ] Role and permission changes replicate to remote instances
  • [ ] Membership add/removal federates
  • [ ] Channels federate with full feature support
  • [ ] Test interop with multiple Bonfire instances and any other apps that implement the groups spec
  • [ ] Progressive enhancement: features unsupported by remote apps degrade without breaking

Related Areas: ActivityPub Spec, Standards, Federation Protocol


Implement reporting and escalation for group violations

Members can report content or behavior to group and/or instance moderators.

  • [x] Members can report posts, comments, or other members
  • [ ] Report includes reason and optional description/context (included in federation)
  • [ ] Reports go to group moderators by default (can also go to reporter's instance admins)
  • [x] Group has separate reports queue from instance
  • [ ] Group mods can escalate to instance admins (up to 3 instances: group's home instance, mod's instance, and author's instance)
  • [ ] Report status tracking (new, being-reviewed, being-discussed, waiting-for-response, resolved, dismissed, and the like)
  • [ ] Notifications/reports go to relevant moderators (based on reported reason + keyword filtering?)
  • [ ] Reporter privacy options (anonymous or identified)
  • [ ] Mod privacy options (anonymous or identified)
  • [ ] Report history and patterns visible to mods/admins

Related Areas: Moderation, Notifications, Permissions


Federate moderation decisions across instances

When a moderator removes a post or member on one server, that action is communicated and inherited by other federated servers to avoid duplicated moderation work.

  • [ ] Post removal federates to group members
  • [ ] Member removal federates
  • [ ] Groups can have remote moderators
  • [ ] Moderation log accessible to remote mods
  • [ ] Instance/user blocks by group mods federate appropriately

Related Areas: Federation, Moderation, Conflict Resolution


Implement notification system for group activities

Members receive timely notifications about group events, replies, and administrative changes.

  • [ ] Notify on new post in group (opt-in per group or channel)
  • [ ] Notify on reply to a post
  • [ ] Notify on mod actions (removal, suspension, role changes)
  • [ ] Optional Notify on membership changes (new member joined, member left)
  • [ ] Email digest options (eg. daily, weekly)

Related Areas: Notifications System, User Preferences


Enable groups to move between servers with content and membership intact

Groups and their members can migrate to a different server without losing history or relationships (full portability).

  • [ ] Mods can export group data (posts, members, metadata, settings)
  • [ ] Import group data from another server
  • [ ] Redirect old group to new group on different server
  • [ ] Follows/memberships get moved automatically
  • [ ] If a member moves instance, their membership gets preserved automatically
  • [ ] Document migration process for mods
  • [ ] Optional: Automated migration workflow

Related Areas: Federation, Database, Import/Export


Implement admin and moderation dashboard

Admins and moderators manage group settings, members, content, and moderation from a dedicated interface.

  • [x] Mod dashboard overview (members, pending posts, reports, other events)
  • [x] Member management (invite, remove, role assignment) - partial
  • [x] Reports queue with details and status (approve/remove posts, manage reports)
  • [x] Settings panel (group metadata, privacy, membership, code of conduct)
  • [ ] Moderation log with search and filters, and audit trail (who changed what, when)
  • [ ] Analytics (member growth, activity, discussions)
  • [ ] Bulk actions (ban users, remove content, export data)
  • [ ] Role templates and permission presets

Related Areas: UI/UX, Permissions, Admin Tools


Document federated groups specification and implementation guide

Publish comprehensive documentation for developers and community admins on how groups work, federation, and standards alignment.

  • [ ] User guide (how to join, participate in groups)
  • [ ] Mod guide (create, configuration, moderation)
  • [ ] Developer documentation (API, ActivityPub extensions, data models and extension points)
  • [ ] Interoperability guide (tests with other fediverse apps), FEPs documentation and examples, with example JSON payloads and test fixtures
  • [ ] Migration guide (for existing forum/group communities)
  • [ ] Code of conduct, moderation, and accessibility guidelines for group builders
  • [ ] Troubleshooting and FAQ

Related Areas: Documentation, Standards, Developer Experience


Implement & test robust authorization and security for groups

Ensure permissions, encryption, and access control prevent unauthorized actions and data leaks.

  • [x] Permission inheritance (group -> channel -> discussion level)
  • [ ] Optional: functionality to retroactively change visibility/permissions of group posts when changing group settings
  • [x] Secure remote member/mod authentication (federation) - via ActivityPub signatures
  • [ ] Optional: End-to-end encryption for private group communications
  • [ ] Rate limiting on group actions
  • [ ] Audit logging of security & mod events

Related Areas: Security, Authentication, Permissions


APIs for groups

  • [x] GraphQL API: Full CRUD operations
  • [ ] Mastodon API: add extensions for group/channel properties / endpoints (compatible with Newsmast)

SWICG Groups Taskforce Alignment

This section maps features from the SWICG Groups Taskforce specification to Bonfire's implementation.

User Stories - Full Match

These SWICG user stories match features in Bonfire:

User Stories - Partial Match

These SWICG user stories are partially implemented or need work:

  • [ ] Invite to admin - "As a group owner, I would like to invite a group member to become an admin."

    • Bonfire: Role assignment works via boundaries/ACL, but no dedicated "invite to admin" flow
  • [ ] Expel an admin - "As a group owner, I want to expel an admin."

    • Bonfire: Can change roles via boundaries, but no explicit admin expulsion flow
  • [ ] Add to a group collection - "As a group member, I want to add content to a group collection."

  • [ ] Remove from a group collection - "As a group member, I want to remove content from a group collection."

  • [ ] Transfer group ownership - "As a group owner, I want to transfer ownership to another actor."

    • Bonfire: Not explicitly implemented

Group Representation Properties

Mapping SWICG properties to Bonfire implementation:

SWICG PropertyBonfire EquivalentStatus
idcategory.id (ULID, canonical URL via character)✅ Implemented
type: Groupcategory.type = :group (enum)✅ Implemented
nameprofile.name✅ Implemented
summaryprofile.summary✅ Implemented
imageprofile.image_id (banner)✅ Implemented
iconprofile.icon_id✅ Implemented
members(as circle)✅ Implemented
adminsQueried via :mediate verb in boundaries✅ Implemented (different mechanism)
attributedTo (owner)✅ Implemented
collectionsNot implemented❌ Missing
inboxSubmitted tab / notifications inbox⚠️ Partial (not as AP collection)
pendingMembersJoin requests in membership settings⚠️ Partial (not as AP collection)
inboxCharacter has inbox for federation✅ Implemented
outboxCharacter has outbox for federation✅ Implemented

Protocol Activities

Mapping SWICG protocol activities to Bonfire:

ActivitySWICG UseBonfire Status
Create (Group)Create a groupap_publish_activity/3
Update (Group)Change group info✅ Implemented
Delete (Group)Close a group✅ Soft delete, federation TBD
JoinRequest to join⚠️ Uses Follow instead
LeaveLeave a group⚠️ Uses Undo Follow instead
Accept (Join)Accept join request❌ Not implemented
Reject (Join)Reject join request❌ Not implemented
InviteInvite to group⚠️ Via invite links, not AP Invite
Remove (member)Expel member❌ Not implemented
Create (post)Post to group✅ Implemented
AnnounceRedistribute to members✅ Group actor announces posts
Accept (post)Approve pending post❌ Not implemented
Reject (post)Reject pending post❌ Not implemented
Add (to collection)Add to group collection❌ Not implemented
Remove (from collection)Remove from collection❌ Not implemented

Bonfire Features NOT in SWICG Spec

Features implemented in Bonfire that are not (yet) defined in the SWICG Groups Taskforce:

  • Channels/Subcategories - Hierarchical tree structure + related to links
  • Category types - Distinguish Groups, Channels/Topics, Labels, etc
  • Boundary presets - Open/Visible/Private with fine-grained permission inheritance
  • Channel mentions - mentioning channels submits a post to inbox for possible Announce in outbox
  • Group-scoped flagging - Reports queue separate from instance
  • Remote instance blocking - Block at group level

SWICG Spec - TBD or Undefined

Areas marked as TBD in the SWICG spec that Bonfire may need to track:

  • [ ] Collections protocol - "TBD" - How to Add/Remove from group collections
  • [ ] Admins protocol - "TBD" - Detailed admin management activities
  • [ ] Alternative designs - "TBD" - Different approaches being considered
  • [ ] Open issues - "TBD" - Including:
    • Should Group be an actor with inbox/outbox? (we think yes)
    • Who can invite others? Protocol-defined or implementation-dependent?
    • Who can expel members? Owner, admins, members?
    • Does Delete need boundaries?
    • Do permissions of Note extend to all members or just group actor?
    • Are all activities shared with all members? (Like, Question, etc.)

FEP-1b12: Group Federation Alignment

This section maps features from FEP-1b12: Group federation to Bonfire's implementation. FEP-1b12 describes how to represent and federate Groups in ActivityPub, with a focus on interoperability with Lemmy, Friendica, Hubzilla, Lotide, and PeerTube.

Core Concepts - Match Status

Group Actor

FEP-1b12 RequirementBonfire StatusNotes
Group represented as type: Group actor✅ ImplementedVia character with group category type
Group has inbox✅ ImplementedCharacter-based inbox
Group has outbox✅ ImplementedCharacter-based outbox
Group has followers collection✅ ImplementedMembers as followers
Moderators in attributedTo collection⚠️ PartialMods tracked via boundaries, not attributedTo collection

Following a Group (Membership)

FEP-1b12 RequirementBonfire StatusNotes
User sends Follow to join✅ ImplementedFollow acts as join request
Group sends Accept(Follow) for approval✅ ImplementedFor open groups, automatic accept
Membership = being in followers collection✅ ImplementedMembers tracked as followers
Undo(Follow) to leave group✅ ImplementedUnfollow removes membership

Audience Property

FEP-1b12 RequirementBonfire StatusNotes
Posts use audience property to indicate group⚠️ PartialGroup ID included, but may use context instead of audience
audience contains Group actor ID⚠️ PartialNeed to verify exact property used

Threads and Comments

FEP-1b12 RequirementBonfire StatusNotes
Threads as Page type with name property❌ DifferentBonfire uses standard posts, not Page type
Comments as Note with inReplyTo✅ ImplementedStandard threaded replies
Nested comments via inReplyTo chain✅ ImplementedFull threading support

Announce Activity

FEP-1b12 RequirementBonfire StatusNotes
Group wraps posts in Announce✅ ImplementedGroup actor announces member posts
Announce distributed to followers✅ ImplementedFederation via outbox
Original post preserved in object✅ ImplementedStandard ActivityPub pattern

Moderation

FEP-1b12 RequirementBonfire StatusNotes
Moderators listed in attributedTo❌ DifferentUses boundaries/ACL system
Add activity to add moderator❌ Not implementedRole changes via boundaries UI only
Remove activity to remove moderator❌ Not implementedRole changes via boundaries UI only
Moderation activities validated against attributedTo⚠️ PartialValidated against boundaries instead

Protocol Activities Mapping

FEP-1b12 ActivityPurposeBonfire Status
Follow (to Group)Request membership✅ Implemented
Accept(Follow)Approve membership✅ Implemented
Reject(Follow)Deny membership❌ Not implemented
Undo(Follow)Leave group✅ Implemented
Create(Page)Create thread⚠️ May use Note/Article instead
Create(Note)Create comment✅ Implemented
AnnounceDistribute to members✅ Implemented
Add (moderator)Add moderator❌ Not implemented
Remove (moderator)Remove moderator❌ Not implemented
DeleteRemove content✅ Soft delete implemented
UpdateEdit content/group✅ Implemented

Interoperability Status

FEP-1b12 notes implementations in several platforms. Bonfire's compatibility:

PlatformCompatibility Notes
Lemmy⚠️ Partial - Different thread model (Page vs Note), needs testing
Friendica⚠️ Partial - Should work for basic Follow/Announce, needs testing
Hubzilla⚠️ Partial - Complex permission model, needs testing
Lotide⚠️ Unknown - Needs testing
PeerTube⚠️ Partial - Video focus, channel model differs

Bonfire Features NOT in FEP-1b12

Features implemented in Bonfire not covered by FEP-1b12:

  • Channels/Subcategories - Hierarchical tree structure within groups
  • Boundary-based permissions - Fine-grained ACL system for roles
  • Join request workflow - Pending members queue for non-open groups
  • Post submission queue - Submitted posts for mod approval before Announce
  • Group-scoped flagging - Reports queue at group level
  • Instance blocking - Block remote instances at group level
  • Invites - Invite people to join a group
  • Category types - Distinguish Groups from Topics/Channels/Labels

FEP-1b12 Requirements NOT Met

Key gaps to address for full FEP-1b12 compliance:

  • [ ] audience property - Verify and ensure proper audience property on group posts
  • [ ] Page type for threads - Consider supporting Page type for Lemmy compatibility
  • [ ] attributedTo for moderators - Expose moderators in attributedTo collection
  • [ ] Add/Remove activities - Implement Add/Remove for moderator changes
  • [ ] Reject(Follow) - Implement rejection of join requests via federation
  • [ ] Interop testing - Systematic testing with Lemmy, Friendica, etc.

FEP-400e: Publicly-appendable Collections Alignment

This section maps features from FEP-400e: Publicly-appendable ActivityPub collections to Bonfire's implementation. FEP-400e describes how to handle collections where others can contribute content (like walls, forums, photo albums in groups) while the owner retains authority.

Core Concepts - Match Status

Collection Ownership and Authority

FEP-400e RequirementBonfire StatusNotes
Collection has valid globally-unique id✅ ImplementedCategory/group has canonical URL
Collection owner retains complete authority✅ ImplementedVia boundaries/ACL system
Collection exposed in actor representation⚠️ PartialGroup outbox exposed, but not as named collection field

Using target in Objects

FEP-400e RequirementBonfire StatusNotes
Objects include target field with collection reference⚠️ PartialMay use context instead of target
target contains type, id, attributedTo⚠️ PartialNeed to verify exact structure
Object understood in context of collection✅ ImplementedPosts associated with group/channel

Add/Remove Activities

FEP-400e RequirementBonfire StatusNotes
Server sends Add activity when object added to collection❌ Not implementedUses Announce instead
Server sends Delete activity for removal✅ ImplementedSoft delete federates
Server sends Move activity between collections❌ Not implementedNo cross-collection move

Protocol Activities Mapping

FEP-400e ActivityPurposeBonfire Status
Create with targetCreate object in collection⚠️ Different - uses context or group mention
AddConfirm object added to collection❌ Not implemented (uses Announce)
DeleteRemove object from collection✅ Implemented
MoveMove between collections❌ Not implemented
Reject{Create}Reject submission❌ Not implemented
  • Post submission queue - Aligns with FEP-400e's moderation concept
  • Channel/group posting - Posts belong to collections, but uses different mechanism
  • Group authority - Owner/mod authority over content aligns with FEP-400e intent

FEP-400e Requirements NOT Met

  • [ ] target field usage - Implement proper target field instead of/alongside context
  • [ ] Add activity - Send Add when confirming post to group (currently uses Announce)
  • [ ] Move activity - Support moving posts between channels/groups
  • [ ] Reject{Create} - Federate rejection of submitted posts
  • [ ] Collection endpoints - Expose named collection fields in group actor

FEP-db0e: Non-public Group Authentication Alignment

This section maps features from FEP-db0e: Authentication mechanism for non-public groups to Bonfire's implementation. FEP-db0e defines "actor tokens" for authenticating access to private group content hosted on other servers.

Core Concepts - Match Status

Actor Tokens

FEP-db0e RequirementBonfire StatusNotes
sm:actorToken endpoint in actor❌ Not implementedNo token endpoint
Token with issuer, actor, timestamps❌ Not implementedNo token generation
RSA-SHA256 signed tokens❌ Not implementedNo token signing
Time-limited validity (max 2 hours)❌ Not implementedN/A

Fetching Private Content

FEP-db0e RequirementBonfire StatusNotes
HTTP signature for fetching from group server✅ ImplementedStandard AP signatures
Actor token for fetching from other servers❌ Not implementedNo token-based auth
Authorization: ActivityPubActorToken header❌ Not implementedN/A

Token Verification

FEP-db0e RequirementBonfire StatusNotes
Verify HTTP signature matches token actor❌ Not implementedN/A
Check validity timestamps❌ Not implementedN/A
Verify object belongs to collection owned by issuer❌ Not implementedN/A

Bonfire's Current Approach

Bonfire uses a different approach for private group content:

  • Boundaries system - Fine-grained ACL controls visibility
  • HTTP signatures - Standard ActivityPub authentication
  • Server-side enforcement - Visibility checked on fetch

FEP-db0e Implementation Status

This FEP is largely not implemented in Bonfire. The boundaries system provides local access control, but the federated token mechanism for cross-server private group content verification is not present.

Gaps to Address

  • [ ] Actor token endpoint - Add sm:actorToken endpoint to group actors
  • [ ] Token generation - Implement signed token creation for members
  • [ ] Token verification - Accept and verify tokens on content fetch
  • [ ] Cross-server private groups - Enable private group content to be fetched securely from member's servers

Considerations

  • FEP-db0e is primarily implemented by Smithereen
  • May be needed for full private group interop with Smithereen
  • Bonfire's boundaries system may need adapter layer for this mechanism

Specification Comparison

This section compares the SWICG Groups Taskforce specification with the FEPs to understand their relationships, overlaps, and differences.

Scope and Focus

SpecificationPrimary FocusStatus
SWICG Groups TaskforceComprehensive group protocol with user storiesDraft/In Progress
FEP-1b12Practical group federation (Lemmy-compatible)Final
FEP-400ePublicly-appendable collections (building block)Final
FEP-db0ePrivate group authentication via actor tokensFinal
FEP-044fConsent-based interactions (quotes, replies)Draft
GoToSocial interactionPolicyPost-level interaction controls with approval workflowsImplemented
Pixelfed capabilitiesSimple binary interaction controlsImplemented

Group Actor Representation

AspectSWICGFEP-1b12FEP-400eFEP-db0e
TypeGroupGroupN/A (collection-focused)N/A (auth-focused)
Has inbox/outboxYes (recommended)YesN/AYes (for tokens)
Moderatorsadmins collectionattributedTo collectionattributedTo (owner)N/A
Membersmembers collectionfollowers collectionN/AN/A

Key difference: SWICG uses explicit members/admins collections, while FEP-1b12 repurposes followers for members and attributedTo for moderators (Lemmy compatibility).

Membership Protocol

ActionSWICGFEP-1b12
Request to joinJoin activityFollow activity
Leave groupLeave activityUndo(Follow) activity
Approve joinAccept(Join)Accept(Follow)
Reject joinReject(Join)Reject(Follow)
Remove memberRemove activityNot specified
Invite memberInvite activityNot specified

Key difference: SWICG defines dedicated Join/Leave activities, while FEP-1b12 reuses the existing Follow mechanism. FEP-1b12's approach has wider existing implementation support (Lemmy, Friendica, etc.).

Post Distribution Model

AspectSWICGFEP-1b12FEP-400e
Post targetingNot fully specifiedaudience propertytarget property
DistributionAnnounce (implied)Announce by group actorAdd by collection owner
Moderation queueAccept/Reject postNot specifiedReject{Create}
Content removalNot specifiedDeleteDelete

Key insight: FEP-1b12 and FEP-400e offer complementary approaches:

  • FEP-1b12's Announce model: Group actor redistributes posts to followers
  • FEP-400e's Add model: Collection owner confirms content belongs to collection

These could be used together: Add to confirm membership in collection, Announce to distribute.

Moderation and Roles

AspectSWICGFEP-1b12FEP-400e
Moderator discoveryadmins collectionattributedTo collectionattributedTo (owner only)
Add moderatorTBDAdd activityN/A
Remove moderatorTBDRemove activityN/A
Authority modelOwner + adminsModerators in attributedToSingle owner

Key difference: FEP-400e assumes single owner authority, while SWICG and FEP-1b12 support multiple moderators.

Private/Restricted Groups

AspectSWICGFEP-1b12FEP-db0e
Private contentMentioned (user story)Not addressedPrimary focus
Auth mechanismNot specifiedN/AActor tokens
Cross-server fetchNot specifiedN/AToken in Authorization header

Key insight: FEP-db0e fills a gap left by SWICG and FEP-1b12 - how do federated servers authenticate access to private group content when the content is hosted on a member's server?

Compatibility Matrix

SWICGFEP-1b12FEP-400eFEP-db0eFEP-044fGoToSocialPixelfed
SWICG⚠️ Different membership model✅ Complementary✅ Complementary✅ Complementary✅ Complementary✅ Complementary
FEP-1b12⚠️ Different membership model⚠️ Different distribution model✅ Complementary✅ Complementary✅ Complementary✅ Complementary
FEP-400e✅ Complementary⚠️ Different distribution model✅ Complementary✅ Complementary✅ Complementary✅ Complementary
FEP-db0e✅ Complementary✅ Complementary✅ Complementary✅ Complementary✅ Complementary✅ Complementary
FEP-044f✅ Complementary✅ Complementary✅ Complementary✅ Complementary✅ Same vocabulary⚠️ Simpler model
GoToSocial✅ Complementary✅ Complementary✅ Complementary✅ Complementary✅ Same vocabulary⚠️ Richer model
Pixelfed✅ Complementary✅ Complementary✅ Complementary✅ Complementary⚠️ Simpler model⚠️ Simpler model

Conflicts and Tensions

1. Membership: Join vs Follow

  • FEP-1b12 uses Follow/Undo(Follow) (established practice)
  • SWICG defines Join/Leave as dedicated activities

Resolution: FEP-1b12's approach has wider adoption. SWICG may need to accommodate both or defer to existing practice.

2. Post Distribution: Announce vs Add

  • FEP-1b12 uses Announce (group actor boosts the post)
  • FEP-400e uses Add (post added to collection)

Resolution: Not mutually exclusive. Could use Add for collection semantics and Announce for distribution. However, implementations must agree on which to expect.

3. Moderator Discovery: admins vs attributedTo

  • SWICG proposes admins collection
  • FEP-1b12 uses attributedTo collection

Resolution: attributedTo has existing implementation (Lemmy). SWICG could adopt this or define admins as an alias.


Implementation Comparison

This table compares Bonfire against specifications and other fediverse implementations. Note that some platforms (WordPress, Discourse, NodeBB) have emerging/experimental AP support.

Threadiverse & Social Platforms

FeatureBonfireLemmymbinpiefedFriendicaHubzilla
Group termGroup/ChannelCommunityMagazineCommunityForumForum/Channel
Actor typeGroupGroupGroupGroupGroupGroup
Has inbox/outbox
Group creation
Membership modelFollow/AcceptFollow/AcceptFollow/AcceptFollow/AcceptFollow/AcceptFollow/Accept
Moderators in attributedTo❌ (uses boundaries)Partial
Thread typeNote/ArticlePagePagePageNoteNote
Post distributionAnnounceAnnounceAnnounceAnnounceAnnounceAnnounce
audience propertyPartialPartialPartial
Subcategories/channels✅ (tree hierarchy)✅ (nested forums)
Private groups✅ (boundaries)PartialPartialPartial✅ (permissions)
Actor tokens (FEP-db0e)
Join request approval
Reject(Follow)???
Federated mod actionsPartialPartialPartialPartial
Group-level instance blocks?Partial
Rules/CoC fieldPartial?
FEP-1b12 compliancePartial✅ (origin)✅ (explicit)Partial
Interaction controlsPlanned (interactionPolicy)

Interaction Control Implementations

FeatureBonfireGoToSocialPixelfedMastodon
VocabularyinteractionPolicy (planned)interactionPolicycapabilitiesN/A
ScopeGroup + post levelPost levelPost levelN/A
Approval workflowautomaticApproval/manualApprovalautomaticApproval/manualApprovalBinary (null/Public)N/A
Audience targetingas:Public, followers, actors, collectionsas:Public, followers, actorsas:Public onlyN/A
FEP-044f alignmentPlannedPartialN/A
Group-level controls✅ (planned)❌ (post only)❌ (post only)N/A

Event & Media Platforms

FeatureMobilizonPeerTubeFunkwhale
Group termGroupChannelChannel
Actor typeGroupGroup (for channels)Group
Primary contentEventsVideosAudio
Has inbox/outbox
Membership modelFollow + RSVPFollow onlyFollow only
Is community group?✅ (organizes events)❌ (user-owned channel)❌ (user-owned)
Threaded discussionsEvent commentsVideo commentsTrack comments
Federation with threadiversePartialPartial (videos appear)Limited

Emerging/Experimental

FeatureSmithereenWordPress (AP)DiscourseNodeBB
Group termGroupBlog (as Group)CategoryCategory
Actor typeGroupGroup?Group
Has inbox/outbox?
Membership modelFollow/AcceptFollow?Follow/Accept
Actor tokens (FEP-db0e)
Private groups✅ (tokens)N/ALocal onlyPartial (chat rooms)
Thread typeNoteArticle?Note
Federated groupsPartial (blog-as-group)Planned✅ (FEP-1b12)
MaturityActiveStable pluginIn developmentActive
audience propertyPartial (uses to/cc)??
Resolvable context (FEP-7888)❌ (uses target)?
replies collection (FEP-7458)?Partial
FEP-400e (target/Add)?
Collection query endpoint✅ (sm:collectionSimpleQuery)?
Group invitations✅ (Invite{Group})??

Specification Alignment Summary

FeatureSWICGFEP-1b12FEP-400eFEP-db0eFEP-044fGoToSocialPixelfed
Membership activityJoin/LeaveFollow/Undo(Follow)N/AN/AN/AN/AN/A
Moderator locationadmins collectionattributedToattributedTo (owner)N/AN/AN/AN/A
Post targetingTBDaudiencetargetN/AN/AN/AN/A
Distribution methodAnnounce impliedAnnounceAddN/AN/AN/AN/A
Private authNot specifiedNot specifiedNot specifiedActor tokensN/AN/AN/A
Mod changesTBDAdd/RemoveN/AN/AN/AN/AN/A
Content rejectionRejectNot specifiedReject{Create}N/AAccept/RejectN/AN/A
Interaction controlsNot specifiedNot specifiedNot specifiedN/AinteractionPolicyinteractionPolicycapabilities
Approval workflowNot specifiedNot specifiedNot specifiedN/AautomaticApproval/manualApprovalautomaticApproval/manualApprovalBinary (null/Public)
Consent requestsNot specifiedNot specifiedNot specifiedN/AQuoteRequest/ReplyRequestN/AN/A

Recommendations for Bonfire

Based on this analysis, recommended approach for Bonfire:

Adopt from FEP-1b12 (pragmatic interop)

  • [x] Follow/Undo(Follow) for membership ✅ Already implemented
  • [ ] audience property on group posts
  • [ ] attributedTo for moderators (expose alongside boundaries)
  • [x] Announce for post distribution ✅ Already implemented

Adopt from FEP-400e (collection semantics)

  • [ ] target property on posts (alongside context)
  • [ ] Consider Add activity for explicit collection membership
  • [ ] Reject{Create} for moderation queue rejections

Adopt from FEP-db0e (private groups)

  • [ ] Actor tokens for private group interop (lower priority unless Smithereen interop needed)

Adopt from FEP-044f / GoToSocial (interaction controls)

  • [ ] interactionPolicy property on Group actors to express permissions
  • [ ] automaticApproval/manualApproval arrays for nuanced permission targeting
  • [ ] Map Bonfire boundaries to interactionPolicy for federation discovery
  • [ ] Support canJoin, canPost, canModerate, canGrant etc. action types
  • [ ] Reference parent group collections in channel interactionPolicy for permission inheritance

Adopt from Pixelfed (simple compatibility)

  • [ ] Understand incoming capabilities property on posts
  • [ ] Fall back gracefully when interactionPolicy not present

Keep from SWICG (future-proofing)

  • [ ] Track Join/Leave activity developments
  • [ ] Support admins collection alongside attributedTo
  • [ ] Implement Invite activity when standardized
  • [ ] Track separate members collection (distinct from followers) for subscription vs membership

Bonfire-specific (beyond specs)

  • Boundaries/ACL system provides richer permissions than any spec
  • Channels/subcategories extend group concept
  • Group-scoped flagging for moderation
  • Cross-instance moderation flows using interactionPolicy + Accept/Reject

Proposed: Group-Level Interaction Policy Vocabulary

Inspired by GoToSocial's interactionPolicy and FEP-044f for post-level controls, we propose a similar vocabulary for group-level interaction controls that could express Bonfire's boundaries/ACL system in a federated way.

Rationale

Current specs define what groups can do (FEP-1b12, FEP-400e) but not who can do what within a group. Different platforms implement this differently:

  • Lemmy: hardcoded role system (admin, mod, member)
  • Mastodon: no group support
  • Pixelfed: capabilities property (simple on/off controls)
  • GoToSocial: post-level interactionPolicy (could extend to groups)
  • Bonfire: flexible boundaries/ACL system

A standardized vocabulary would enable:

  1. Federated permission discovery: Remote servers can query what actions are allowed
  2. Interoperability: Different implementations can map their permission systems
  3. Transparency: Users know what they can do before attempting actions

Prior Art: Existing Interaction Control Vocabularies

Pixelfed's capabilities

Pixelfed implements a simple capabilities property for comment controls:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "pixelfed": "http://pixelfed.org/ns#",
      "capabilities": {"@id": "pixelfed:capabilities", "@container": "@set"},
      "announce": {"@id": "pixelfed:canAnnounce", "@type": "@id"},
      "like": {"@id": "pixelfed:canLike", "@type": "@id"},
      "reply": {"@id": "pixelfed:canReply", "@type": "@id"}
    }
  ],
  "type": "Note",
  "id": "https://pixelfed.example/p/user/123",
  "capabilities": {
    "announce": "https://www.w3.org/ns/activitystreams#Public",
    "like": "https://www.w3.org/ns/activitystreams#Public",
    "reply": null
  }
}

Characteristics:

  • Binary control: either null (disabled) or as:Public (enabled for everyone)
  • Simple to implement and understand
  • Limited expressiveness: no audience targeting, no approval workflows
  • Also includes commentsEnabled boolean

GoToSocial's interactionPolicy

GoToSocial implements a richer interactionPolicy for post-level controls:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://gotosocial.org/ns#interactionPolicy"
  ],
  "type": "Note",
  "interactionPolicy": {
    "canReply": {
      "automaticApproval": ["followers"],
      "manualApproval": ["as:Public"]
    },
    "canAnnounce": {
      "automaticApproval": ["followers"],
      "manualApproval": []
    },
    "canLike": {
      "automaticApproval": ["as:Public"],
      "manualApproval": []
    }
  }
}

Characteristics:

  • Audience-based: can target as:Public, followers, specific actors, or collections
  • Two-tier approval: automaticApproval vs manualApproval
  • More complex but more expressive
  • Aligned with FEP-044f consent-based interaction patterns

Comparison

AspectPixelfed capabilitiesGoToSocial interactionPolicy
ComplexitySimpleModerate
Audience targetingPublic onlyPublic, followers, specific actors, collections
Approval workflowNoYes (auto vs manual)
Disable actionnullEmpty arrays
Namespacepixelfed:gotosocial:
ExtensibilityLimitedHigh

Recommendation: We prioritise GoToSocial's interactionPolicy pattern as it:

  • Supports the nuanced permissions Bonfire's boundaries system provides
  • Aligns with FEP-044f's consent vocabulary (as implemented in Mastodon and others)
  • Can degrade gracefully (implementations can ignore manualApproval if unsupported)
  • Is already documented and gaining adoption

Proposed interactionPolicy property on Group actors

A interactionPolicy property on Group actors (and on activities/object related to actors), containing sub-policies for each action type:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://gotosocial.org/ns#interactionPolicy"
  ],
  "type": "Group",
  "id": "https://example.org/groups/1",
  "name": "Example Group",
  "interactionPolicy": {
    "canFollow": {
      "automaticApproval": ["as:Public"],
      "manualApproval": []
    },
    "canJoin": {
      "automaticApproval": ["as:Public"],
      "manualApproval": []
    },
    "canInvite": {
      "automaticApproval": ["followers", "attributedTo"],
      "manualApproval": []
    },
    "canRead": {
      "automaticApproval": ["as:Public"],
      "manualApproval": []
    },
    "canPost": {
      "automaticApproval": ["followers"],
      "manualApproval": ["as:Public"]
    },
    "canReply": {
      "automaticApproval": ["followers"],
      "manualApproval": []
    },
    "canLike": {
      "automaticApproval": ["as:Public"],
      "manualApproval": []
    },
    "canAnnounce": {
      "automaticApproval": ["attributedTo"],
      "manualApproval": ["followers"]
    },
    "canModerate": {
      "automaticApproval": ["attributedTo"],
      "manualApproval": []
    },
    "canCurate": {
      "automaticApproval": ["attributedTo"],
      "manualApproval": ["followers"]
    },
    "canGrant": {
      "automaticApproval": ["attributedTo"],
      "manualApproval": []
    },
    "canEdit": {
      "automaticApproval": ["attributedTo"],
      "manualApproval": []
    },
    "canDelete": {
      "automaticApproval": ["attributedTo"],
      "manualApproval": []
    }
  }
}

Sub-Policy Definitions

PolicyDescriptionTypical Use
canFollowWho can follow the group (receive updates without membership)Usually as:Public
canJoinWho can become a memberOpen groups: as:Public; Closed: manualApproval only
canInviteWho can invite othersMembers (followers) or mods only (attributedTo)
canReadWho can view group contentPublic groups: as:Public; Private: followers only
canPostWho can create new posts/topicsMembers, or moderated (public with manual approval)
canReplyWho can reply to postsUsually same as canPost, or more open
canLikeWho can like/react to postsUsually followers or as:Public
canAnnounceWho can boost/share to the groupOften mod-only for curated groups
canModerateWho can approve/reject content, manage membersMods/admins (attributedTo)
canCurateWho can pin, feature, or organize contentMods or trusted members
canGrantWho can assign roles/permissions to othersUsually owner or attributedTo only
canManageAccessWho can manage access controls (block/allow users/instances), probably needs a better nameUsually attributedTo
canEditWho can edit others' contentUsually mods only
canDeleteWho can delete others' contentUsually mods only

Target Values

Following GoToSocial's pattern:

ValueMeaning
as:PublicAnyone (including non-members, remote actors)
followersGroup members (the group's followers collection)
attributedToModerators/admins (from group's attributedTo property)
Specific actor URIIndividual actors (e.g., "https://example.org/users/alice")
Custom collection URICustom role collections (e.g., "https://example.org/groups/1/curators")
membersGroup members collection (if using SWICG pattern, distinct from followers)

Limitation: followers Conflates Subscription with Membership

FEP-1b12 uses followers as the member collection. This conflates two distinct concepts:

ConceptPurposeUser Intent
Following (subscription)Receive updates in feed"Show me this group's posts"
Membership (permissions)Have permissions within group"I'm part of this community"

This creates problems:

  1. Non-members can't follow: A user might want to see public posts without formally joining
  2. Members can't unfollow: A member might want to stay in the group but mute notifications
  3. Permission confusion: Following a group automatically grants member permissions

Alternative: SWICG's Separate members Collection

The SWICG Groups Taskforce proposes using a dedicated members collection with Join/Leave activities:

{
  "type": "Group",
  "id": "https://example.org/groups/1",
  "followers": "https://example.org/groups/1/followers",
  "members": "https://example.org/groups/1/members"
}

With this pattern:

  • Follow/Unfollow controls subscription (seeing posts)
  • Join/Leave controls membership (having permissions)

In interactionPolicy, this enables:

"interactionPolicy": {
  "canPost": {
    "automaticApproval": ["members"]
  },
  "canRead": {
    "automaticApproval": ["followers", "members"]
  }
}

Compatibility Approach

For maximum compatibility:

  • Use followers as member collection (FEP-1b12 pattern) for basic interoperability
  • Optionally expose a separate members collection for implementations that support it
  • In interactionPolicy, "followers" remains the safe default that all implementations understand

Note: Bonfire's implementation should consider supporting both patterns, using followers for federation compatibility while internally distinguishing between subscription and membership states.

Approval Types

  • automaticApproval: Action succeeds immediately without review
  • manualApproval: Action requires moderator approval (enters queue)

An empty array means the action is not permitted for anyone in that approval type.

Federation Considerations

  1. Discovery: Remote servers can fetch the group actor (or a specific post or other object within a group) and read interactionPolicy to understand permissions before attempting actions

  2. Graceful degradation: Servers not understanding interactionPolicy can fall back to:

    • FEP-1b12's Follow/Accept for membership
    • Standard moderation via attributedTo
    • Attempting an action which the remote server (home of the group) can reject/ignore (meaning any side effects should only be applied locally if the activity was accepted)
  3. Override at post level: Individual posts within a group could override group-level policies using GoToSocial-style interactionPolicy for finer control

  4. Compatibility with existing specs:

    • followers maps to FEP-1b12 member collection
    • attributedTo maps to FEP-1b12 moderator collection
    • manualApproval aligns with moderation queue concepts

Example Scenarios

Open public group (anyone can join and post):

"interactionPolicy": {
  "canJoin": { "automaticApproval": ["as:Public"] },
  "canPost": { "automaticApproval": ["followers"] }
}

Moderated group (anyone can join, posts require approval):

"interactionPolicy": {
  "canJoin": { "automaticApproval": ["as:Public"] },
  "canPost": { "manualApproval": ["followers"] }
}

Private/closed group (invite-only, members can post freely):

"interactionPolicy": {
  "canJoin": { "manualApproval": ["as:Public"] },
  "canInvite": { "automaticApproval": ["attributedTo"] },
  "canPost": { "automaticApproval": ["followers"] }
}

Announcement group (mods post, members read-only):

"interactionPolicy": {
  "canJoin": { "automaticApproval": ["as:Public"] },
  "canPost": { "automaticApproval": ["attributedTo"] },
  "canReply": { "automaticApproval": [] }
}

Proposed: Group Relationships Vocabulary

Groups often have relationships with other groups - as related communities, equivalent representations across instances, or hierarchical parent/child structures (like Bonfire's channels within groups).

"As a fediverse user, I want to discover groups related to one I'm viewing - whether that's a space for same community on a different instance/platform, or a sibling community on a related topic - so I can find the best place to participate or explore further."

"As a group admin, I want to indicate related groups that members might be interested in, to help with discovery and cross-pollination."

"As a group admin, I want to link my group to its mirror or previous identity on another instance, so that members and remote servers can recognize it as the same community."

The existing ActivityStreams property alsoKnownAs can link equivalent or closely related groups.

Use cases:

  • Similar groups on different instances
  • Federated group migration (old → new location)
  • Groups that merge or split (though that could also use parent/child links)
  • Cross-platform equivalents (e.g., a Lemmy community linked to a Mobilizon events group)
{
  "type": "Group",
  "id": "https://instance-a.org/groups/rust-dev",
  "name": "Rust Development",
  "alsoKnownAs": [
    "https://instance-b.org/groups/rust-programming",
    "https://instance-c.org/communities/rustaceans"
  ]
}

Note: should we use something https://schema.org/isRelatedTo to not conflate group migration (i.e. linking two instances of the "same" group) vs linking related but different groups?

Hierarchical Groups: Parent/Child Relationships

For nested structures like Bonfire's channels within groups, we propose using existing and extended properties:

Parent Reference: context

The existing context property can reference a parent group/channel:

{
  "type": "Group",
  "id": "https://example.org/groups/programming/rust",
  "name": "Rust",
  "context": {
    "type": "Group",
    "id": "https://example.org/groups/programming",
    "name": "Programming"
  }
}

Note: context is already used in FEP-7888 for conversation threading. Using it for group hierarchy is consistent with its semantic meaning ("the context in which this exists").

Children Collection: Schema.org hasPart

For discovering child groups/channels, we recommend using Schema.org's established hasPart/isPartOf properties (requires extending the JSON-LD context):

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {"isPartOf": "schema:isPartOf", "hasPart": "schema:hasPart"}
  ],
  "type": "Group",
  "id": "https://example.org/groups/programming",
  "name": "Programming",
  "hasPart": [
    {"type": "Group", "id": "https://example.org/groups/programming/rust", "name": "Rust"},
    {"type": "Group", "id": "https://example.org/groups/programming/python", "name": "Python"},
    {"type": "Group", "id": "https://example.org/groups/programming/go", "name": "Go"}
  ]
}

And the child can then reference the parent with isPartOf:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {"isPartOf": "schema:isPartOf"}
  ],
  "type": "Group",
  "id": "https://example.org/groups/programming/rust",
  "name": "Rust",
  "isPartOf": "https://example.org/groups/programming"
}

Note: Using context (as shown above for parent reference) is also valid and aligns with FEP-7888, but isPartOf is more explicit about the hierarchical relationship, especially if using hasPart too.

Why Schema.org properties?

  • hasPart/isPartOf are well-established with clear semantics
  • Already used in JSON-LD contexts across the web
  • More portable than defining new properties

Inheriting Permissions from Parent Group

A channel can optionally reference the parent group's collections in its interactionPolicy, allowing permission inheritance:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {"isPartOf": "schema:isPartOf"},
    "https://gotosocial.org/ns#interactionPolicy"
  ],
  "type": "Group",
  "id": "https://example.org/groups/programming/rust",
  "name": "Rust Channel",
  "isPartOf": "https://example.org/groups/programming",

  "attributedTo": [
    "https://example.org/groups/programming/attributedTo"
  ],
  "followers": "https://example.org/groups/programming/rust/followers",

  "interactionPolicy": {
    "canJoin": {
      "automaticApproval": ["https://example.org/groups/programming/followers"]
    },
    "canPost": {
      "automaticApproval": ["followers"],
      "manualApproval": ["https://example.org/groups/programming/followers"]
    },
    "canModerate": {
      "automaticApproval": ["https://example.org/groups/programming/attributedTo"]
    }
  }
}

Key patterns:

PatternExampleMeaning
Own members"followers"This channel's followers collection
Parent members"https://example.org/groups/programming/followers"Parent group's members can also interact
Parent mods"https://example.org/groups/programming/attributedTo"Parent group's mods can moderate this channel
Own mods"attributedTo"This channel's own moderators

Note: The attributedTo of a channel can directly reference the parent's attributedTo collection, meaning the channel inherits its moderators from the parent rather than maintaining a separate list.

Use cases:

  • Shared membership: Parent group members automatically gain access to child channels
  • Centralized moderation: Parent group mods can moderate all child channels
  • Mixed model: Channel has own members, but parent mods can still moderate
  • Isolated channel: Channel uses only its own followers/attributedTo (no parent references)

Complete Group Actor Example

Combining interactionPolicy with relationship properties:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://gotosocial.org/ns#interactionPolicy"
  ],
  "type": "Group",
  "id": "https://example.org/groups/programming/rust",
  "name": "Rust Programming",
  "summary": "A channel for Rust developers",
  "attributedTo": ["https://example.org/users/alice"],
  "followers": "https://example.org/groups/programming/rust/followers",
  "inbox": "https://example.org/groups/programming/rust/inbox",
  "outbox": "https://example.org/groups/programming/rust/outbox",

  "context": {
    "type": "Group",
    "id": "https://example.org/groups/programming",
    "name": "Programming"
  },

  "alsoKnownAs": [
    "https://other-instance.org/communities/rust"
  ],

  "interactionPolicy": {
    "canFollow": { "automaticApproval": ["as:Public"] },
    "canJoin": { "automaticApproval": ["as:Public"] },
    "canInvite": { "automaticApproval": ["followers", "attributedTo"] },
    "canRead": { "automaticApproval": ["as:Public"] },
    "canPost": { "automaticApproval": ["followers"], "manualApproval": [] },
    "canReply": { "automaticApproval": ["followers"] },
    "canLike": { "automaticApproval": ["as:Public"] },
    "canAnnounce": { "automaticApproval": ["attributedTo"], "manualApproval": ["followers"] },
    "canModerate": { "automaticApproval": ["attributedTo"] },
    "canGrant": { "automaticApproval": ["attributedTo"] },
    "canManageAccess": { "automaticApproval": ["attributedTo"] }
  }
}

Cross-Instance Moderation Flows

When moderators are distributed across multiple instances, moderation actions require coordination between the remote moderator's instance and the group's home instance. This section documents how interactionPolicy with manualApproval handles these scenarios.

Alignment with FEP-044f

This flow follows FEP-044f's patterns for consent-based interactions:

  • interactionPolicy with automaticApproval/manualApproval arrays (GoToSocial namespace)
  • Accept/Reject responses to requests

However, unlike FEP-044f's QuoteAuthorization stamps, group moderation does not need separate authorization objects because:

  • The group's home instance is the authority - it verifies permissions via interactionPolicy before acting
  • Once the group executes the action (e.g., Undo(Announce)), that federated activity is the proof of authorization
  • Third parties don't need to verify authorization separately - they just process the group's outgoing activities normally

This keeps the flow simpler while maintaining the same interactionPolicy vocabulary.

Scenario: Remote Mod Hides a Post

A moderator (@mod@instance-b.org) wants to hide a post that was shared to a group hosted on instance-a.org. "Hiding" means removing the group's Announce of that post.

Group's interactionPolicy:

{
  "interactionPolicy": {
    "canModerate": {
      "automaticApproval": ["https://instance-a.org/users/admin"],
      "manualApproval": ["https://instance-a.org/groups/cooking/moderators"]
    }
  }
}

The moderators collection includes @mod@instance-b.org.

Flow 1: Remote Mod Requests Content Removal

Step 1: Remote mod sends Delete(Announce) to group inbox

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://instance-b.org/activities/delete-announce-123",
  "type": "Delete",
  "actor": "https://instance-b.org/users/mod",
  "object": {
    "type": "Announce",
    "actor": "https://instance-a.org/groups/cooking",
    "object": "https://instance-c.org/posts/spam-post-456"
  },
  "target": "https://instance-a.org/groups/cooking",
  "to": ["https://instance-a.org/groups/cooking"]
}

Step 2: Group's home instance checks policy

The group server checks if @mod@instance-b.org is in:

  1. automaticApproval for canModerate → No → don't auto-process
  2. manualApproval for canModerate → Yes (via moderators collection) → queue for approval

Step 3: Home instance queues for manual approval

The request is queued. A notification is sent to actors with automatic moderation approval (e.g., the admin).

Step 4a: Approval - Accept activity

If approved by an admin:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://instance-a.org/activities/accept-456",
  "type": "Accept",
  "actor": "https://instance-a.org/groups/cooking",
  "object": "https://instance-b.org/activities/delete-announce-123",
  "to": ["https://instance-b.org/users/mod"]
}

The group then processes the deletion and sends Undo(Announce) to all followers:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://instance-a.org/activities/undo-announce-789",
  "type": "Undo",
  "actor": "https://instance-a.org/groups/cooking",
  "object": {
    "type": "Announce",
    "id": "https://instance-a.org/activities/announce-original",
    "actor": "https://instance-a.org/groups/cooking",
    "object": "https://instance-c.org/posts/spam-post-456"
  },
  "to": ["https://www.w3.org/ns/activitystreams#Public"],
  "cc": ["https://instance-a.org/groups/cooking/followers"]
}

Step 4b: Rejection - Reject activity

If rejected:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://instance-a.org/activities/reject-456",
  "type": "Reject",
  "actor": "https://instance-a.org/groups/cooking",
  "object": "https://instance-b.org/activities/delete-announce-123",
  "summary": "Moderation action not approved",
  "to": ["https://instance-b.org/users/mod"]
}

Flow 2: Using Flag for Content Reports

Alternatively, a remote moderator can use Flag to report content, which may be more appropriate when the mod doesn't have direct moderation rights:

Step 1: Remote mod flags the content

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://instance-b.org/activities/flag-123",
  "type": "Flag",
  "actor": "https://instance-b.org/users/mod",
  "object": [
    "https://instance-c.org/posts/spam-post-456",
    "https://instance-a.org/activities/announce-original"
  ],
  "content": "This post violates group rules: spam/advertising",
  "target": "https://instance-a.org/groups/cooking",
  "to": ["https://instance-a.org/groups/cooking"]
}

Step 2: Group processes Flag based on canFlag policy

The group checks canFlag policy and queues for moderator review if the actor is authorized.

Automatic vs Manual Approval Matrix

Moderator LocationIn automaticApprovalIn manualApprovalResult
Home instance admin-Action processed immediately
Home instance modQueued for admin approval
Remote instance modQueued for admin approval
Remote instance modRejected (unauthorized)
Any member (not mod)Rejected, use Flag instead

Implementation Notes

  1. Pending Queue: The group's home instance should maintain a queue of pending moderation actions awaiting approval.

  2. Notification: When an action is queued, actors in automaticApproval should be notified (via their inbox or a dedicated moderation collection).

  3. Timeout: Consider adding a timeout for pending actions (e.g., 7 days) after which they're auto-rejected.

  4. Audit Trail: Both Accept and Reject activities should be logged for moderation transparency.

  5. Cascading: If the removed content had replies, consider whether to cascade the removal or leave orphaned replies.

  6. Alternative: Direct Undo: If the mod is in automaticApproval, they could send Undo(Announce) directly (though semantically Delete targeting the Announce is clearer for requesting removal of someone else's Announce).

Legend:

  • ✅ = Implemented/supported
  • ⚠️ = Partial/different approach
  • ❌ = Not implemented
  • ? = Unknown/needs research
  • N/A = Not applicable to this spec/platform