Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@[email protected]

A Call for Better Activity Signatures in the Fediverse

Why Major ActivityPub Implementations Should Adopt Object Integrity Proofs

Let's say you have accounts named alice@bar and bob@baz that don't follow each other, but they both follow john@foo. When alice@bar replies to john@foo's post, how can bob@baz see this reply?

This problem applies not only to replies, but also to things like likes and emoji reactions. One of the ways that ActivityPub implementations solve this problem is through inbox forwarding. The idea is to forward the reply received by john@foo to bob@baz as well.

Fedify makes inbox forwarding easy and convenient with its forwardActivity() method. But the question is, can bob@baz trust the activity forwarded by john@foo?

Because HTTP Signatures sign the HTTP request that contains the activity, not the activity itself, john@foo can't sign an activity created by alice@bar when it's forwarded by him, because forwarding requires creating a new HTTP request. (The HTTP request includes things like the Host header, so a new signature is required for each new recipient.)

So, alice@bar needs to sign her activity in a way that allows john@foo to forward it. In the fediverse, there are two ways to do this: Linked Data Signatures and Object Integrity Proofs. Fedify automatically attaches all three types of signatures (HTTP Signatures, Linked Data Signatures, and Object Integrity Proofs) to every activity it sends, so activities are free to be forwarded between ActivityPub software created with Fedify.

However, major ActivityPub implementations such as Mastodon and Misskey still sign activities with HTTP Signatures only, or only some activities with Linked Data Signatures. (Note that Linked Data Signatures is an outdated standard, and Object Integrity Proofs are recommended.)

So, why are we talking about this at length? We strongly urge major ActivityPub implementations to adopt Object Integrity Proofs, or at minimum Linked Data Signatures, for activity signing!

kopper [according to whom?] :colon_three:'s avatar
kopper [according to whom?] :colon_three:

@[email protected] · Reply to Fedify: an ActivityPub server framework's post

@fedify While all this is true and forwardable signatures do allow for a lot of other useful features (IIRC conversation containers rely on them? not exactly sure), if you're not careful with how you format your activities you can lose the benefits of authorized fetch. (Well, what little we have anyway given how trivial they are to bypass)

If you have an
as:Create where the as:object is inlined instead of just being an id reference, then any remote that has access to the activity can forward it onwards potentially to instances you do not want that object to reach to, and have it be cryptographically validated to not be a forgery. (When it's a reference instead of being inlined, you can enforce authorized fetch at the dereference step, so only the notification that the object exists can be forwarded)

Similarly, if you don't rotate your keys (and even if you do, if a malicious instance just archives all historic keys it knows of), then you have basically no plausible deniability on if wrote that post or not.

I'd say that
validating integrity proofs should be implemented, as if someone does sign their objects then there's no real harm in making use of that signature (and so Ed25519 keys become more widely implemented and we can ditch RSA even for HTTP signatures), but producing integrity proofs may be an issue depending on what kind of privacy characteristics you expect out of your instance.

Hypolite Petovan's avatar
Hypolite Petovan

@[email protected] · Reply to Fedify: an ActivityPub server framework's post

@fedify cc @heluecht 👀
silverpill's avatar
silverpill

@[email protected] · Reply to Fedify: an ActivityPub server framework's post

@fedify

I am going to implement Conversation Containers instead of inbox forwarding. This mechanism keeps conversations synchronized, but also enables backfilling and moderation of replies.

əlemi's avatar
əlemi

@[email protected] · Reply to Fedify: an ActivityPub server framework's post

this is a good example and the value proposition is clear however I'm not sure I'm going to implement signatures as I have some concerns. Hoping my thoughts can be valuable, here are some of them:


The main reason for me is loss of plausible deniability: if I post something wrong and want to retract it, copies of it signed by me could still circulate as other instances cache and relay it. This forces my instance to make sure the Delete activity reaches everyone, and trust every remote to respect it.

Differently, current no-signature approach makes me (well my instance) the single authority on my post: if I delete it, nobody can verify it again, as they can't fetch it. As long as I'm ok with it being fetchable, remotes can verify it by asking me (/my instance).


Another concern is server load: currently Lemmy forwards activities for a group/community to each instance hosting an actor which follows such group/community. This generates a lot of traffic and work for a bunch of activities nobody will ever see!

I also think remotes should always check the real source for relayed objects, and because this means doubling the requests, we should keep relaying to a minimum.

I think an on-demand approach is better than a preemptive one: my FE has a "fetch" button, and when opening a post, (logged-in) users can check if remote instance has replies we don't know of, and fetch them. It's not as good as having them already, but allows servers to cache more precisely what their users really want to see (what their follows generate + what they actually fetch), rather than everything anyone might want to see.

(Also replies could be fetched as user views the post and new objects could appear as they are fetched, sky is the limit for UX!)

Note that instances need to offer the replies collection for this to work. AFAIK Mastodon,Iceshrimp.NET and Mitra do, but *omas, *keys, Lemmy and Friendica don't!