I often work on connecting things that don’t automatically connect but should, like Bridgy for IndieWeb and social networks. Federated social networks like GNU Social and Mastodon have been hot recently, so I’m thinking about them too.
ActivityPub is the new W3C standard for federated social networking. It’s the successor to OStatus. Here’s background and a straw man design for a bridge between ActivityPub and IndieWeb’s Webmention, which would let users on both sides follow, reply, like, RSVP, and otherwise interact with each other’s posts. (Also see my design for an OStatus bridge.)
First, some links:
Implementation support is still nascent:
- pump.io (issue) and MediaGoblin (issue) are the closest. They both currently support the pump.io API, which is similar to AP proper.
- Mastodon (issue) is getting there, slowly. So far they’ve added ActivityStreams 2 support.
- GNU Social (issue) doesn’t show any signs of moving beyond OStatus. They adopted StatusNet’s code in 2013, and commits and mailing list have been slow since then. (Another data point: when the web site’s SSL cert expired recently, it was down for almost a week.)
- Same with Diaspora (issue, discussion). Friendica and Hubzilla don’t even have issues filed.
ActivityPub leans heavily on HTTP
Content-Type and content negotiation for discovery and serving AS2 data. It prefers first
application/ld+json; profile="https://www.w3.org/ns/activitystreams" and then
application/activity+json. Details in discussions on discovery, WebFinger, and link relations.
ActivityPub also has explicit support for public posts and addressing.
First, some simplifying assumptions and non-goals:
- Don’t translate AS2 to microformats2 HTML. Most of the big existing projects already include mf2 in their HTML: Mastodon, GNU Social, pump.io, and Friendica (but not Diaspora). We’ll just use that in place.
(This may not hold for non-text interactions, e.g. likes, so we may need to revisit those. Also, it may only works well for public data, so…)
- Only public posts and interactions. I’m not sure any project has truly robust, mature support for private or semi-private interactions right now, so they’re not a high priority.
- No user registration. The bridge is mostly stateless, modulo discovery caching and keypairs, and we don’t need to do an OAuth-style user approval dance on either end…so let’s not!
Next, a major design decision. Choose one of:
- Proxy all domains. Say the bridge’s domain is
bridge.example. If IW user
alice.exampleand AP user
@email@example.com to interact, they’d do so via wrapped identifiers like
bob.ap.example.bridge.example, respectively. Pro: no changes needed on IW or AP sites. Con: bad UX.
- Require sites to point to bridge. If IW sites support AP content negotiation discovery and redirect to the bridge, and AP sites add a
<link rel="webmention'>that points to the bridge, the normal
@firstname.lastname@example.org will work automatically. Pro: Good UX. Con: depends on support in each individual project.
Proxying is a non-trivial amount of work, and we can always add it later, so we’ll start without it.
For AP to discover IW users, the bridge generates and serves Actor objects with at least the
inbox field pointing to an AP inbox endpoint on the bridge, e.g.
IW sites will need to handle content negotiation, detect HTTP requests asking for AP content types, and redirect to their Actor URL on the bridge, e.g.
For IW to discover AP users, AP projects will need to advertize the bridge’s webmention endpoint in their HTML, e.g.
<link rel="webmention' href="https://bridge.example/webmention>.
To convert a webmention to AP:
- Accept incoming webmention.
- Fetch source page. Translate it to AS2.
- Fetch target page. Determine author’s URL.
- Fetch author’s Actor with con-neg, extract their inbox endpoint.
- POST AS2 object to inbox.
To convert an AP interaction to webmention:
- Accept incoming POST to IW user’s AP inbox endpoint.
- Parse AS2 object in body, determine target URL (reply to, like of, etc). Reject POST if no target is found.
- Fetch target URL, discover webmention endpoint.
- Send webmention with AP source and IW target.
- Authentication and authorization. The AP spec is unfortunately non-normative on this. The server-to-server options are either OAuth 2 + JSON Web Signatures or Linked Data Signatures (more).
I haven’t found any mention of pump.io’s or MediaGoblin’s plans, but Mastodon seems to be heading toward LDS, so maybe we’ll start there.
Concretely, we’d generate and store a key pair for each IndieWeb user when we first see them, on the fly. We’d then serve it in their AS2 Actor’s
signClientKeyfield, and sign their AS2 objects with it before POSTing them to an AP inbox.
- Store users and interactions and render user pages with recent interactions, a la Bridgy.
- Support more sophisticated interactions, e.g. Update, Delete, Undo, Add, Remove, Block.
- Deliver posts to followers. The existing AP projects’ mf2 support also includes
h-feed, so IW readers should already handle AP users. To deliver IW posts to AP users, we’d need to:
- Accept Follow POST to an IW user’s AP inbox.
- Discover the IW user’s WebSub endpoint. Subscribe to it if it exists, otherwise reject the Follow POST.
- Accept WebSub pings.
- Convert each new IW post to an AS2 objects and POST it to the IW user’s AP followers’ inboxes.