Representing digital events external to ActivityPub

(Posted this on SocialHub and posting it here too)

Before the specific example, I’m starting with a general description. If it sounds too vague, skip to the example :slight_smile:

Some activities trigger action, for example Follow (it’s a request to follow someone). Some activities report things that already happened (for example Read, Eat, Travel). And some activities may describe something that just happened, digitally, but using a protocol external to ActivityPub.

Representing those isn’t as obvious, if you want to have some proof that the activity really happened in the external protocol and isn’t fake. That the actor really sent what they claim, and that the recipient/object/target approves they received that same thing. In a federated situation, where an activity made on one server affects a resource hosted on another server, things get more complicated than in a centralized system.

Here’s an example I’m facing in ForgeFed. A person alice@A does a git push to a repo myproject@B. So Alice and myproject are on different servers. I’d like to have an ActivityPub representation of that git push, so that:

  • People following Alice or browsing her activity can see she pushed to myproject
  • People following myproject or browsing its activity can see it got a push from Alice

If Alice publishes a Push activity, we can interpret that as “as far as Alice knows, the push succeeded”, but there’s nothing proving myproject got such a push. We’d need myproject to somehow sign that push, e.g. by publishing an Accept activity, and only then we can treat those Push activities as authentic.

If myproject publishes some BePushed activity, stating that Alice pushed such and such commits, we can’t be sure myproject isn’t just advertising fake things Alice never did. We’d need some signature from Alice, e.g. via an Announce activity, to be sure Alice really made that push. But how can software automatically examine the activity and verify it matches VCS data? I have ideas but leaving that to a separate thread.

There’s another option: in VCSs the pushes are often not recorded at all; only the actual commits are. So instead of a Push activity, we could have an activity called e.g. Patch (or Record or Commit etc.) where the actor isn’t the person pushing, but the person who wrote the commit. That makes it trivial to verify authenticity but there’s a problem: If you push a commit written by someone else, e.g. because you applied and reviewed their patch, how can you publish an activity while they are the actor? Possible mitigation: If ALL patch sending and merge requesting happens via ActivityPub, then the author sends a Patch activity or RequestMerge or Create or whatever we call it, and then a repo collaborator sends a Merge/Apply activity, and finally the repo (which is an actor too) sends an Accept, and we have a complete chain of authentic activities. So since all merge requests happen via AP, never email and such, when Alice pushes directly to myproject we can require that she is the author of all the commits, and then there’s never a need for Alice to publish commits made by others. Problem with this mitigation: All collaboration has to happen via the fediverse.

Hmm that’s a lot of prose surely exhausting to read :stuck_out_tongue: here’s the bottom line. 2 options of representing those git pushes:

  1. Push activities published by people and BePushed activities published by repos are entirely separate. If you want to verify authenticity, you need to dig in the outbox, find the matching activity, make sure the exact same commit hashes are listed.
  2. Since VCSs like git don’t record the identity of the pusher (AFAIK), the workflow with verified activities would be quite integrated: When you push, in the pre-push hook you publish a Push activity. Then, on the repo’s server, in the pre-receive and post-receive hooks, the server finds your Push activity, verifies the hashes match, publishes an Accept and the push is accepted in git. But this works only if the pusher has the tech to publish that Push activity. Just installing git alone on one’s laptop wouldn’t be enough. An alternative scheme is that the repo first publishes a BePushed activity, and

Also, there are 2 options for collaboration:

  • You can push a commit with any author. To verify author authenticity, use gpg. Additionally, patches/MRs/commits for whom the actor is also the author and were made via AP, you can verify authenticity via HTTP sigs or LD Sigs etc.
  • You can push only commits written by you, and the only way to insert a commit by someone else is to accept a patch or Merge Request via ActivityPub, so all commits’ authors can be authenticated in the AP way, and in addition you have the good old gpg

Thank you for reading my rambling ^ _ ^

I’d love to hear:

  1. Thoughts on this specific example and the ideas I described
  2. Insights about the general case of AP activities that describe computer transactions happening externally to AP

I am unsure if it’s relevant wether the push suceeded.

I view this Activities as informational, “Look, I did $thing”, Activities without side-effects. Because I don’t think we want to do SCM transfer via AP*.

Maybe have just an “$user pushed $commits” Activity in the Repository and if the user wants to show off, s/he can just Announce that Activity.

If a repo allows anonymous pushes, then the activity is missing the attributedTo and just contains the commits pushed.

Regarding wether the user really pushed that commits to that repo, I don’t think we need to care about this.
Like, if you AP Visit a place, nobody verifies that you really where present, right?

* If you have read the patchset-vs-fetch discussion in the GitLab issue tracker I was part of; that was a slightly different basis for scm transfer via AP and relies on specific Activities for that mode.