FEP-ae0c: Fediverse Relay Protocols: Mastodon and LitePub
Summary
Relays are important components within the decentralized Fediverse architecture. They act as intermediary servers that facilitate communication between different instances, enabling users on Fediverse platforms to share public content without requiring actor following relationships.
These relays benefit small instances by enabling them to effectively participate in the federated social network, both as consumers and producers of Fediverse content.
Several styles of relays existing in the Activity Fediverse. This FEP describe two popular styles of relays:
NOTE: This is an informational FEP documenting the current status quo. It uses RFC-2119 requirements keywords only as a convenience. Also, these are not standardized protocols. They will generally not be conformant with the ActivityPub standard although they use some concepts from it.
Terminology
For the purposes of this document, the following terminology will be used:
Term | Description |
---|---|
relay client actor | An actor in a server that is a Relay Server subscriber. May also be referred to as a client actor. |
relay client server | A server hosting one or more Relay Client Actors. May also be referred to as a client server. |
relay subscription | A relationship established between a Relay Client Actor and a Relay Server using an ActivityPub Follow activity. |
relay server actor | An actor in a server that provides relaying of messages between Relay Client Actors. May also be referred to as a relay actor. |
relay server | A server hosting one or more Relay Server Actors. May also be referred to as a relay server or a relay. |
HTTP Signature | HTTP-based signature (Cavage) used to verify message sender and contents. |
LD Signature | JSON-LD signature used to verify messages regardless of transport. |
Mastodon Relay Protocol
The Mastodon relay protocol relies on LD Signatures to verify relayed messages. This allows Mastodon to verify the relayed message although it is being sent by a different actor (the relay server actor).
Relay Client Actor
A Relay Client Actor establishes following relationship with a relay server actor and then processes relayed messages sent to the actor's ActivityPub inbox. The relay client server will add the relay inboxes to the delivery target for content with public visibility.
Relay Subscription
Mastodon will POST an ActivityPub Follow
request to the relay ActivityPub inbox
URI. The object
of the Follow
request MUST be the fully expanded URI of the Public pseudo-collection (https://www.w3.org/ns/activitystreams#Public
). The relay then responds to the Follow
request with an Accept
or Reject
activity. The response time for the acknowledgement can be arbitrarily long since the subscription MAY require manual approval.
The request MUST be signed using the same HTTP Signature (Cavage) algorithms that Mastodon uses for ActivityPub federation. The relay will fetch the relay client actor document to obtain the actor's public key. For best interoperability, the actor ActivityPub document SHOULD be Mastodon-compatible. For example, preferredUsername
SHOULD be provided in addition to all actor fields required by ActivityPub and the actor SHOULD provide a sharedInbox
endpoint URL.
The relay client actor type SHOULD accurately reflect the actor type. However, note that some relay server implementations constrain the ActivityPub type of a client actor. For example, the relay server implementation might require the client actor to be an Application
type and reject other types.
Example Follow Request
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "https://client.example/6ae15297",
"type": "Follow",
"actor": "https://client.example/actor",
"object": "https://www.w3.org/ns/activitystreams#Public"
}
Example Follow Accept Response
The Accept
activity MAY respond with the accepted Follow
activity URI as the object
or it may embed a copy of the original Follow
activity. A Reject
activity will have a similar structure.
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "https://relay.example/15c0b99f-23d4-4488-ba9d-d0c7bc2876a5",
"type": "Accept",
"actor": "https://relay.example/actor",
"object": {
"@context": "https://www.w3.org/ns/activitystreams",
"id": "https://client.example/6ae15297",
"type": "Follow",
"actor": "https://client.example/actor",
"object": "https://www.w3.org/ns/activitystreams#Public"
}
}
Relay Unsubscription
To unsubscribe from a relay send an Undo
with the original Follow
activity (embedded, or the URI) as the object
. There is typically no response to the Undo
.
Example Undo/Follow Request
{
"@context": "https: //www.w3.org/ns/activitystreams",
"id": "https://client.example/3f5ebd6d",
"type": "Undo",
"actor": "https://client.example/actor",
"published": "2024-10-14T14:42:17.650139+00:00",
"object": "https://client.example/6ae15297"
}
Publishing Messages to a Relay
To publish an activity to a Mastodon-style relay, the publisher MUST sign the message using the Mastodon-specific LD Signature algorithm. The benefit of using LD Signatures is that the receiving servers can verify the message content without refetching from the client server. This lowers the server load on the client server.
The disadvantage is that the LD Signatures are not easy to implement and Mastodon uses an outdated nonstandard form of the algorithm. The Mastodon documentation recommends not supporting LD Signatures for these reasons. Furthermore, the Mastodon documentation does not accurately describe the LD Signature algorithm it implements. For more details, see the additional information about Mastodon LD Signatures in this document.
The posted activity MUST be signed with a Mastodon-compatible HTTP Signature.
Mastodon will relay the following activity types: Create
, Update
, Delete
, Move
. A relay actor MAY only forward those types although Mastodon will accept other relayed activities, such as Announce
, without an LD Signature. In the Announce
case, it will fetch the announced object
.
Receiving Messages from Relays
Relayed messages are posted to the relay client actor's inbox
. Relayed messages MUST have an HTTP Signature signed by the Relay Actor.
Messages received from Relay Server Actors MAY have an LD Signature. If the HTTP Signature and the LD Signature are both present, the activity actor
becomes the effective sender after LD Signature verification.
If no LD Signature is present and the received message is an Announce
activity, then a relay client MUST ensure the content is legitimate (not spoofed). This may be done by fetching the announced activity from the originating server or using remote content from a local cache. However, if the announced activity is already locally cached, then there would typically be no processing to be done with it since it is already known to the client server.
A client server receiving a relayed message MAY also deliver the messages to local recipients based on the ActivityPub audience targeting properties.
Relay Server Actor
The following behaviors describe the typical implementation of a Mastodon-style relay server actor.
Follow
Ensure that https://www.w3.org/ns/activitystreams#Public
is in the object
property. Use the actor
as the relay client actor URI and save the information about the subscriber. The relay server MAY decide to deny access based on factors like the signer's domain.
Undo/Follow
Verify that the actor
is a known relay client and, if so, remove the client actor from the set of relay actor followers.
Activity Relaying
When a message is received from a client actor, the relay MUST verify the HTTP Signature of the activity and identify the originating actor. If the message is valid, it is then posted (with the relay actor's HTTP Signature) to the inboxes of the relay's followers. No delivery is performed based on the ActivityPub audience targeting properties. The relay MUST not send the relayed message to the originating relay client actor.
Typically a message is forwarded unchanged. However, a relay MAY do other processing on the message, such as wrapping a message without an LD Signature using an ActivityPub Announce
activity before forwarding it (See pub-relay). Extended behaviors like this are not described in this FEP.
A relay actor SHOULD only relay messages from followers. A relay actor SHOULD only relay activities that it hasn't already relayed. Addressing properties, like to
, MUST be in a list even for a single URI.
Mastodon LD Signatures
Note that the Mastodon documentation for their LD Signatures is incomplete and inaccurate. This section provides more details, but it may be necessary to review the Mastodon source code for additional clarification.
An activity signed with a Mastodon LD Signature will have a signature document in the activity (using the signature
property).
Example Signature Document
{
"@context": [
"https: //www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"id": "https://client.example/3f5ebd6d",
# ...
"signature": {
"type": "RsaSignature2017",
"creator": "https://client.example/actor#main-key",
"created": "2024-12-08T03:48:33.901Z",
"signatureValue": "s69F3mfddd99dGjmvjdjjs81e12jn121Gkm1"
}
}
The https://w3id.org/security/v1
JSON-LD context defines the signature
and related properties, but is not used by Mastodon for LD Signature processing.
When performing signature operations the signature document and the activity (without the signature document) are initially processed (hashed) separately. The SHA256 hash digests are concatenated that string is then signed.
Signing a JSON-LD Activity
- Create a signature document with only the
creator
andcreated
properties. Set the@context
tohttps://w3id.org/identity/v1
. (Note that this context doesn't appear to be accessible on the web any more. You may need a local copy with a custom JSON-LD context loader.) - Create a canonical RDF representation of the signature document. This requires JSON-LD expansion using standard algorithms (JSON-LD-ALGO) and conversion to RDF using the Universal RDF Dataset Canonicalization Algorithm 2015 (RDF-CANON). The serialized RDF is then hashed using SHA256 and a hexdigest is created.
- Create a SHA256 hex digest for the activity document (without the signature document) using a similar procedure.
- Concatenate the SHA256 hex digests for the signature and activity documents and sign the result using SHA256 and the client actor's private key.
- Encode the signature using Base64 and set the
signatureValue
of the signature document to the result. - Set the signature document
type
to "RsaSignature2017". - Set the
signature
property of the activity to the signature document.
Verifying a JSON-LD Signature
- The signature document is retrieved from the activity and the type is checked to be the nonstandard "RsaSignature2017". If not, verification fails.
- Save the
signatureValue
from the signature document. - Remove the
type
andid
andsignatureValue
properties from the signature document and generate a SHA256 hex digest for the modified signature document using the procedure described for signing documents. - Remove the
signature
from the activity and generate a SHA256 hex digest for it. - Concatenate the hex digests for the modified signature and activity documents.
- Use the client's public key to verify the signature using SHA256.
LitePub Relay Protocol
The LitePub protocol is based on ActivityPub and is used in Pleroma-compatible servers. The reference implementation is the Pleroma Relay.
Relay Client
A LitePub relay client actor must have a type of Application
and an actor ID ending with /relay
. For best interoperability, it should be compatible with Mastodon actor documents and have WebFinger support. Other implementations may use different actor ID structures (e.g., AodeRelay apparently uses /actor
and works with Pleroma). General relay interoperability of these LitePub variants is not known.
Relay Subscription
The client relay actor will send a Follow
to the relay server. The Follow
object
is the relay server actor URI.
The relay server MUST respond to the Follow
request with an Accept
or Reject
. If accepted, the relay server sends a reciprocal Follow
request for the LitePub client actor. The client server SHOULD respond with Accept
or Reject
activity. A relay server MAY decide to ignore the subscription if no acknowledgement is received within a reasonable time interval.
Example Relay Follow Request
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://pleroma.example/schemas/litepub-0.1.jsonld",
{
"@language": "und"
}
],
"actor": "https://pleroma.example/relay",
"bcc": [],
"bto": [],
"cc": [],
"id": "https://pleroma.example/activities/3fe13910-73f4-4cdc-9c84-ec7013a3e764",
"object": "https://relay.example/actor",
"state": "pending",
"to": [
"https://relay.example/actor"
],
"type": "Follow"
}
Notes:
1. The JSON-LD context is not valid for JSON-LD processing. The litepub-0.1.jsonld document contains an invalid WebFinger-related context URL.
2. The state
property is not defined in the JSON-LD context.
Relay Unsubscription
To unsubscribe from a relay send an Undo
with the original Follow
activity as the object
. There is typically no response to the Undo
.
Example Undo/Follow Request
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://pleroma.example/schemas/litepub-0.1.jsonld",
{
"@language": "und"
}
],
"id": "https://pleroma.example/activities/cf9c85e9-f83f-4a02-b598-880f15423f68",
"object": {
"actor": "https://pleroma.example/relay",
"bcc": [],
"bto": [],
"cc": [],
"context": "https://pleroma.example/contexts/d493d02b-7cc9-49dc-995c-d949af0b5417",
"id": "https://pleroma.example/activities/3fe13910-73f4-4cdc-9c84-ec7013a3e764",
"object": "https://relay.example/actor",
"published": "2024-10-18T14:04:11.029802Z",
"state": "cancelled",
"to": [
"https://relay.example/actor"
],
"type": "Follow"
},
"published": "2024-10-18T14:04:11.029791Z",
"to": [ "https://relay.example/actor" ],
"cc": [],
"type": "Undo",
"actor": "https://pleroma.example/relay",
"context": "https://pleroma.example/contexts/d493d02b-7cc9-49dc-995c-d949af0b5417"
}
Publishing Messages to a Relay
A LitePub relay client actor will send an Announce
for a relayed object (like a Note
). For best interoperability Announce
should refer to the announced object using an URI (instead of embedding the object).
The Announce
activity MUST be address to the relay server actor's followers collection. (TODO it's not known if the admin addressing is also required). The published
property should be included since some relay server will reject activities without it.
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://pleroma.example/schemas/litepub-0.1.jsonld",
{
"@language": "und"
}
],
"actor": "https://pleroma.example/relay",
"to": [
"https://pleroma.example/relay/followers",
"https://pleroma.example/users/admin"
],
"bto": [],
"cc": [],
"context": "https://pleroma.example/contexts/a59117d9-7f7c-48ec-83b4-5e183e7179b5",
"id": "https://pleroma.example/activities/e24e46a2-8926-4a20-9f5f-638e06102159",
"object": "https://pleroma.example/objects/c13bba3c-e7c1-45ac-939f-aa292d23ee8c",
"published": "2024-10-18T14:06:37.736295Z",
"type": "Announce"
}
Receiving Messages from a Relay
Messages received from a relay are typically wrapped in an Announce
activity. AFter the object
of the announce is fetched and validated, it is displayed on the federated timeline. It appears that Pleroma
will accept a relayed Create
activity (for Mastodon compatibility), but will refetch the Create
object
since the LD Signature isn't processed. (TODO verify this behavior.)
Other Relay Server Considerations
The relay server hosting relay actors will have other functionality other than activity relaying.
WebFinger
A relay server MUST implement WebFinger support for relay actors. This is necessary because of Mastodon's actor fetching implementation. It's possible that it's not required for LitePub-only relay servers.
NodeInfo
A relay server MAY implement NodeInfo to advertise server activity and metadata.
Optional Relay Server Behaviors
A relay server MAY support multiple relay protocols. However, there is no standard way to advertise those capabilities.
A relay server often hosts a single actor, but any number of relay actors may be hosted. For example, a relay server may have a relay actor for specific topics, hashtags, or moderation categories. A relay client can subscribe to any number of relay actors in a given server.
Some servers implement dynamic relay actor creation. A relay actor's inbox
URI might be based on a hashtag or a topic name. When a client actor subscribes to this kind of inbox URI, the relay actor is created automatically. Obviously, there are risks to this approach when used by misbehaved clients.
参考文献
- Christine Lemmer Webber, Jessica Tallon, ActivityPub, 2018
- James M Snell, Evan Prodromou, Activity Vocabulary, 2017
- Mastodon Documentation, LD Signatures, HTTP Signatures
- S. Bradner, Key words for use in RFCs to Indicate Requirement Levels, RFC-2119, 1997
- Matthew Sporny, Dave Longley, JSON-LD 1.1, JSON-LD, 2020
- Dave Longley, Gregg Kellogg, JSON-LD 1.1 Processing Algorithms and API, JSON-LD-ALGO, 2018
- Graham Klyne, Jeremy J. Carroll, RDF 1.1 Concepts and Abstract Syntax, RDF, 2014
- Dave Longley, RDF Dataset Canonicalization, (URDNA2015) RDF-CANON, 2022
- NIST, Secure Hash Standard (SHS), SHA256, 2015
- Wikipedia, Base64
- P. Jones, WebFinger, RFC-7033 WebFinger, 2013
- Jonne Haß, NodeInfo, GitHub
- Pleroma Relay, pleroma-relay
- LitePub Protocol Suite, litepub
- Takeshi Umeda, pub-relay pub-relay
著作権
CC0 1.0 ユニバーサル (CC0 1.0) パブリック ドメイン
法律で認められる範囲において、この Fediverse 拡張提案の著者は、この作品に対するすべての著作権および関連する権利または隣接する権利を放棄しています。