Skip to content

ActivityPub Integration

Bryan Ashby edited this page Jan 24, 2023 · 30 revisions

Overview

Discussion and design of ActivityPub / Mastodon with ENiGMA½. See also ActivityPub / Mastodon #459.

Desired Integrations

  • Act as both a server and a client
    • On behalf of users (client)
    • AP server-to-server (Federated)
    • As the BBS itself (bot)
  • Feed views
    • Local
    • Federated
    • Following
  • Inbox
  • Message Areas
    • Ability to map a message area to a ActivityPub 'group'
    • Read and reply in message base
    • Similar to EchoMail
    • Bridged/mapped message areas, such as FTN (non-Mastodon node) <-> Local (Mastodon) <-> Fediverse
  • Users
    • Users should be aware of any Mastodon bridged message networks or any time their messages land on Mastodon in general

Questions

  • Q: A reply in a mapped area may land in both the inbox and said area?
  • Should we create a more generalized ActivityPub support/module/classes that Mastodon then extends?
    • We have been building our own
  • How are we going to deal with profile pictures and banners? Have users upload them to the BBS? Add URLs on account creation? Both?
    • Two main properties in actor: image and icon
  • Is the web part of this big enough that we should look into using something like express.js and a module like activitypub-express instead of rolling our own implementation - ANSWER: not at this time, we are going to try to create our own first
  • How to allow users to choose to use real vs username for Mastodon specific browse/follow/reply/etc.
    • Note: Message areas have the ability to control this currently
    • Part of ActivityPub config mod
  • How to handle follower approval (manuallyApprovesFollowers actor property)
    • See other properties to be user controlled also; perhaps with +op defaults
    • Similar to above, allow users to control if they are discoverable (actor property)

MVP Laundry List

  • Looks like Mastodon is adding some Group functionality that might make my suggested workaround for message areas unnecessary (depends on timing, I see anything about when it will be released though it does look like it is funded work): https://github.com/mastodon/mastodon/pull/19059
  • Research user private key storage; this seems like a major security issue
  • We need to delete from private_mail at some point, specifically the sent messages
    • What frequency for messages in outbox? How many to keep? When to remove?
    • trimExternalPrivateSentMail() does this for messages with the exported flag, but we may need a diff freq for AP
    • Note also: Exported is only a single flag, so does not account for e.g. FTN and ActivityPub
  • maxMessageLength
    • Per mapped area configuration
    • When sending from private mail to a ActivityPub address
      • Perhaps addition to address info?
    • Use Mastodon defualt length 500
  • Determine how groups are to work
    • A post to areaTag should go to a "group" on Mastodon
    • Incoming messages map to areaTag
    • areaTag mapping ala FTN
    • maxMessageLength optionally configured (overridden from def)
  • Replies
    • Incoming: inReplyTo -> ID in local Activities / Message meta
    • Outgoing: message.replyToMsgId -> AP ID -> inReplyto
  • Move Web server to it's own log
    • Same setup - rotation/etc.
  • Default config with overrides available to +op
    • Settings
  • Determine exactly how "private" (user-to-user only) are to work
  • Implement followers
    • Track who is following each account
    • On export, export to all followers if not a direct message

Mastodon

First class Mastodon support

Design

Mapping

Federated (Fediverse Support / Server to Server)

  • Send POST to remote inbox
    • Private user-to-user
    • Via local mail to/from @user@host
  • Receive POST to local inbox:
    • Remote user places items in local user's inbox
  • Receive GET of local inbox
    • Clients: Fetch new inbox items Not required for initial offering
      • Support for alt/non-BBS client interaction
      • Items POSTed from other federated servers
    • BBS: no GET request, interaction is within BBS
      • Read and respond via private mail box (ala local, NetMail, ...)
  • GET of remote outbox to see new messages
    • Fetching new posts

Client to Server (BBS User to Server)

  • POST to local outbox
    • Stored locally
    • Public
      • In "groups" mapped to local areaTag
      • To local activityPub area tag for both Federated and Local views
      • No POST / endpoint actually used within BBS
    • External Clients
      • Actual POST to outbox
      • Stored locally
  • GET of remote outbox to see new messages
    • External clients

Overview

ActivityPub Objects Hieararchy

Object/

  • id
  • Actor/
    • Provides information about an Actor (user's in our case)
    • static fromLocalUser(userId, ...)
  • Activity/
    • Can wrap other Objects -- static wrapObject(obj)
  • Collection/
    • Fetching and building of various collections
    • inbox, outbox, followers, following, likes, ...
    • static get(...)

Source Layout

core/
  servers/
    content/
      web.js
      web_handlers/
        webfinger.js
        activitypub.js
  • webfinger.js
    • Handles standard WebFinger requests via acct:
    • Handles standard profile request associated with WebFinger
    • Includes additional rel and aliases if an ActivityPub system is also enabled, such as Mastodon
      • It would be nice if these could be 'injected' by mastdon.js
      • Perhaps at least only if +op has enabled activitypub
  • activitypub.js

Security

  • In order to interoperate with Mastodon, we need to implement HTTP Signatures. More info at: https://docs.joinmastodon.org/spec/security/
    • Implementation in activitypub-express
    • Based on node-http-signature - probably a good idea for us to use as well
    • Private / Public keypairs are generated with the Node.JS crypto library.
    • Notes on approach:
      1. Need to create a new public / private keypair and store in the db on account creation (or one-time during migration)
      2. As subscribe requests occur or lookups to other servers, the Actor object needs to be stored into the database
      3. On outbound requests from the the BBS that involve an actor, the private key is used to sign the requests
      4. On incoming requests that involve a remote actor, the public key stored for the actor is used to verify the signature
  • With increased usage of HTTP with ActivityPub/Mastodon support, we should look at additional security testing as well. See: Free for Open-Source App Security Tools for some tools that are free for Open Source projects.

Federated Private Key Storage

These certificates are used for server-to-server only, not e.g. message encryption; mostly non-issue: https://github.com/mastodon/mastodon/discussions/18669

References

Implementations

Approach for web components

  • Build our own (maybe using https://github.com/jakelazaroff/dumbo as a guide)
    • Advantages
      1. No rework required, extending what we already have
      2. Can build it up a little at a time
    • Disadvantages
      1. We are totally on the hook for interoperability
      2. Maybe more work overall when some of it has already been done for us
  • Use existing activitypub-express module - https://github.com/immers-space/activitypub-express
    • Advantages
      1. Very complete
      2. Popular
      3. Interchangeable storage (that we would have to swap out)
      4. Active (last update Nov 11)
    • Disadvantages
      1. The completeness might lead to additional time to understand the full codebase
      2. Although storage is interchangeable, it is centered around ActivityPub, decent amount of work there to interface