Inbox Forwarding

Forwarding to avoid the ghost replies problem
ActivityPub: 7.1.2 Forwarding from Inbox

TLDR; A few questions on current/desired implementations

I am curious to know if any projects have implemented this?

Referring to the Elephant in the room (pun intended), if I understand correctly the reply to my post would be forwarded to my followers, but this doesn’t seem to be the case, my timeline only shows explicitly/manually shared Announce activities.

When Activities are received in the inbox, the server needs to forward these to recipients that the origin was unable to deliver them to.

Are there any use cases where this could be of value? (Ex. Groups)

Or cases in which it should never be used? (Ex: Unlisted posts)

I implemented inbox forwarding in Vervis. I did it a long time ago, so I don’t remember exactly how I came to the decision to implement it. But basically, in Vervis all delivery to remote collections is done via inbox forwarding.

For example, imagine alice@A sends an activity that addresses:

  • Alice’s followers
  • bob@B
  • Bob’s followers

Then server A sends the activity to Bob’s inbox. It doesn’t look at Bob’s followers. It doesn’t deliver the activity to them one by one. It just sends to Bob. There, the implementation of Bob’s inbox post handler sees that the activity addresses Bob’s follower collection. Since Bob owns that collection, the handler knows that it’s up to it, to deliver (or decide not to deliver) the activity to Bob’s followers.

Based on the properties of the activity, the handler decides whether or not to deliver. If it decides to deliver, it inserts the activity to the inboxes of Bob’s followers who are on server B, and inbox-forwards it via HTTP to Bob’s followers who are on other servers.

This does create a potential challenge of spam: If anyone can inbox-forward to me any activity authored by any other actor out there, how do I tell which deliveries to me are intended by the activity’s author, and which are spam?

So, I added a custom mechanism: authorized inbox forwarding. I have it documented somewhere :slight_smile: In that mechanism, actors make a cryptographically signed permit/request for some of the recipients, to inbox-forward the activity. And when those actors inbox-forward it, they add their own signature. With that system, inbox handlers can verify that forwarded activities were sent with consent from the author.

1 Like

The forwarding mechanism can be potentially used to deliver activities to instances which are not directly reachable over the network (e.g. on homeservers behind NAT).
There’s a problem though, because many implementations rely on HTTP signatures for authenticity check and won’t accept forwarded activities. Mastodon adds LD signatures to some of its activities, but I don’t know whether it actually supports any of inbox forwarding use cases.

Meanwhile, W3C develops a standard for signing JSON objects, and I hope it will be adopted by Fediverse platforms: Verifiable Credential Data Integrity 1.0

I think this is worth mentioning that this behaviour refers strictly to a server disseminating an activity to collections which belong to local actors.

For this case, my project FedBOX does so.

For the members of those collections that are not local, the dissemination is being done together with its authorization header so the instance that receives it will probably be able to validate the activity/actor that sent it originally using the normal flow.

The inbox forwarding feature of ActivityPub seems problematic. I have been trying to decide whether to implement it.

The spec (Section 7.1.2) states that it is required (MUST) for a federated server to forward from an inbox, if and only if all the following conditions are met:

  1. The activity is new (not seen before on the server)
  2. The to, cc, or audience fields adddress a Collection owned by the server (e…g followers, but possibly other collections on the server)
  3. The inReplyTo, object, target, or tag properties of the activity are also objects owned by the server.

These aren’t very difficult conditions to satisfy. So, if I want to send a message to any collection on a server, including someone else’s followers, it seems all I need to do is to send it to an inbox on that server, addressed to any actor on that server, with the collection in question also in one of the to, cc, or audience fields. The activity I send needs to be a “reply” to some object on that server, or to have some object on the server as the “object”, “target”, or “tag” of the activity. The server will dutifully “forward from Inbox” the activity to the collection I want to reach, to which I would otherwise not have access. Spam city. This is supposed to be a mitigation of the “ghost replies” problem. But it sure looks like the cure is worse than the disease.

In effect, anybody can send to any collection. Shouldn’t there at least be a requirement that if replying to or otherwise operating on an object lets you address a collection owned by a server, that there should be some relationship between the object being replied to (or operated upon) and the collection? For example, the repliedTo (etc) object addresses that same collection, and that the object is attributedTo the owner of the collection. And that the actor sending the “reply” be an addressee of the activity which is the subject of the reply? A few more constraints that narrow the scope to one where the “ghost replies” problem can arise?

The only saving grace is that the spec says a server MAY filter its delivery targets according to implementation-specific rules. What does the MUST mean for Inbox Forwarding if you MAY filter out as much of the Inbox Forwarding, as you desire, including all of it?

You’re allowed to do spam filtering, there’s some language immediately after in 7.1.2 that provides an “out” from this. The MUST + MAY is how this is communicated.

The real value in inbox forwarding is like any other situation in which you would want forwarding – mailing list use cases come to mind, as does a “comment” system.