FEP-0499: Delivering to multiple inboxes with a multibox endpoint
Summary
This FEP introduces a server-wide endpoint for delivering activities to multiple inboxes. sharedInbox currently allows for doing this, but it requires the remote server to know how to deliver the activity based on its addressing properties. However, the remote server might not know how to deliver the activity to private recipients, or recipients within a collection. The multibox endpoint removes this knowledge requirement from the receiving server and instead makes the sending server responsible for marking inboxes to explicitly deliver to.
Motivation
(このセクションは非規範的です。)
sharedInbox allows servers to reduce network traffic when delivering Public activities to multiple recipients, but it doesn't work when delivering to collections of actors, or when delivering to private audiences using bto or bcc. If an activity is addressed to a collection and that activity is delivered to a remote sharedInbox endpoint, then this introduces a requirement for the remote server to know the contents of the collection (or at least the local subset of its contents). In the common case of delivering activities addressing followers collections to a sharedInbox endpoint, then the remote server must first recognize that this collection id is specifically a followers collection, and then guess which local actors are following that activity's actor. This is prone to issues and can also have disastrous outcomes when follower state drifts out of sync.
We can eliminate the dependency on shared follower state and allow for delivery of non-Public activities by introducing a new endpoint that likewise allows delivering to multiple inboxes, but without requiring the remote server to know anything. This enables addressing arbitrary collections as well as the use of bto
and bcc
more efficiently.
Prior art
(このセクションは非規範的です。)
There are various advantages described in the original multibox proposal:
Shared Inbox provides the ability for server to server communication traffic to be reduced from R requests, where R is the number of recipients, to a single HTTP request. This is a desirable property as it reduces the amount of HTTP round trips for both the sender and receiver. Unfortunately the design of Shared Inboxes as described in the ActivityPub specification makes it very easy for a spammer to abuse the system by not requiring explicit delivery recipients. We propose an alternative to Shared Inbox called MultiBox that keeps the desirable properties of Shared Inbox while protecting against scenarios in which the sender uses Shared Inbox to "spam" a server.
Like Shared Inbox, MultiBox consists of a single HTTP endpoint for multiple Actors. Unlike Shared Inbox, in a MultiBox request, each recipient is explicitly listed by Inbox, requiring both the knowledge of the Actor and a corresponding Inbox for that actor. This information is transmitted through the use of an HTTP header Audience where each Inbox is listed using comma separated values.
This has two advantages over Shared Inbox. Used on its own, it eliminates the vulnerability mentioned previously whereby recipients to a message do not need to be listed. If this proposal is adopted alongside the Object-Capabilities Based Inbox proposal (4.5), the advantages multiply as we also gain the ability to appropriately filter incoming messages according to the criteria set out by the specific Inboxes, as well as letting us know the origin of each Inbox.
For the sender, the additional computing resources required to send a MultiBox request are minimal, but doing so would make mass-messages expensive for senders wishing to abuse the system.
One open question on this proposal is that if we use the HTTP header Audience to store the list of recipients, this may result in a limitation. HTTP header sizes are not explicitly capped at the protocol level but implementations often cap them at different lengths- 4Kb for the Nginx web server or 8Kb for Apache.
This would limit the number of per message recipients, though this limitation would rarely be reached. An alternative to this proposal would be a new MultiBox object encapsulating the Audience field and the ~Activity.
Proposal
(このセクションは非規範的です。)
This FEP uses the "alternative" approach of putting inboxes in the body of the POST request, instead of using an HTTP header. Whereas headers are limited to possibly as low as 4Kb by default, the limit on POST request bodies is usually much higher; Nginx by default uses a 1MB limit for POST requests. This is the difference between 4000 characters versus 1 million characters.
Specification
Actors MAY have a multibox
endpoint which is available for efficient delivery of activities to multiple inboxes on the same domain.
A server MAY reduce the number of delivery requests by identifying all recipients which share the same multibox
who would otherwise be delivered to individually, and deliver an activity of the following form to their shared multibox
endpoint:
- The type MUST be
Add
. - The
object
MUST be the activity being delivered. - The
target
MUST be all inboxes being delivered to.
Upon receipt of such an activity, the receiving server MUST add the activity in object
into all local inboxes specified in target
, although it MAY filter delivery to certain inboxes according to implementation-specific rules (for example, spam filtering).
例
(このセクションは非規範的です。)
Discovering the multibox endpoint:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/fep/0499"
],
"id": "https://remote.example/actors/af4c8205cd81",
"type": "Person",
"name": "Alice P. Hacker",
"inbox": "https://remote.example/inboxes/fbb433c8e6c4",
"endpoints": {
"multibox": "https://remote.example/multibox"
}
}
Alternatively, without a context declaration:
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "https://remote.example/actors/af4c8205cd81",
"type": "Person",
"name": "Alice P. Hacker",
"inbox": "https://remote.example/inboxes/fbb433c8e6c4",
"endpoints": {
"https://w3id.org/fep/0499/multibox": {"id": "https://remote.example/multibox"}
}
}
Delivering to the multibox endpoint:
POST /multibox HTTP/1.1
Host: remote.example
Content-Type: application/ld+json; profile="https://www.w3.org/ns/activitystreams"
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Add",
"object": "https://example.com/some-activity",
"target": [
"https://remote.example/inboxes/fbb433c8e6c4",
"https://remote.example/inboxes/d21f509146e5",
"https://remote.example/inboxes/68a7453f79e4",
"https://remote.example/inboxes/655216a0be07",
"https://remote.example/inboxes/84907eff485d",
]
}
For transient activities or for cases not requiring a fetch (e.g. no access control), you can embed the activity inline:
POST /multibox HTTP/1.1
Host: remote.example
Content-Type: application/ld+json; profile="https://www.w3.org/ns/activitystreams"
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Add",
"object": {
"@context": "https://context.example"
"actor": "https://example.com/some-actor",
"type": "InGameNotification",
"content": "The payload is nearing the checkpoint!",
"generator": "https://game.example"
},
"target": [
"https://remote.example/inboxes/fbb433c8e6c4",
"https://remote.example/inboxes/d21f509146e5",
"https://remote.example/inboxes/68a7453f79e4",
"https://remote.example/inboxes/655216a0be07",
"https://remote.example/inboxes/84907eff485d",
]
}
Terms defined
multibox
- URI
https://w3id.org/fep/0499/multibox
- Label
- multibox endpoint
- Comment
- An optional endpoint used for wide delivery of activities to multiple inboxes. POST an Add activity where the object is at least one activity to be delivered, and the target is at least one inbox to deliver to.
- Domain
- A map of
endpoints
- Range
- The endpoint (@id)
- Required
- No
- Functional
- Yes
- Is defined by
- FEP-0499
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/fep/0499"
],
"id": "https://remote.example/actors/af4c8205cd81",
"type": "Person",
"name": "Alice P. Hacker",
"inbox": "https://remote.example/inboxes/fbb433c8e6c4",
"endpoints": {
"multibox": "https://remote.example/multibox"
}
}
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "https://remote.example/actors/af4c8205cd81",
"type": "Person",
"name": "Alice P. Hacker",
"inbox": "https://remote.example/inboxes/fbb433c8e6c4",
"endpoints": {
"https://w3id.org/fep/0499/multibox": {"id": "https://remote.example/multibox"}
}
}
POST /multibox HTTP/1.1
Host: remote.example
Content-Type: application/ld+json; profile="https://www.w3.org/ns/activitystreams"
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Add",
"object": "https://example.com/some-activity",
"target": [
"https://remote.example/inboxes/fbb433c8e6c4",
"https://remote.example/inboxes/d21f509146e5",
"https://remote.example/inboxes/68a7453f79e4",
"https://remote.example/inboxes/655216a0be07",
"https://remote.example/inboxes/84907eff485d",
]
}
参考文献
- Christine Lemmer Webber, Jessica Tallon, ActivityPub, 2018
- Christine Lemmer Webber, Rebooting the Web of Trust 9: Keeping Unwanted Messages off the Fediverse > Proposed Suggestions > MultiBox, 2020
著作権
CC0 1.0 ユニバーサル (CC0 1.0) パブリック ドメイン
法律で認められる範囲において、この Fediverse 拡張提案の著者は、この作品に対するすべての著作権および関連する権利または隣接する権利を放棄しています。