IndieWeb ActivityPub bridge

I’ve launched this as Bridgy Fed!

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:

ActivityPub leans heavily on HTTP Content-Type and content negotiation for discovery and serving AS2 data. It prefers first application/ld+json; profile="" and then application/activity+json. Details in discussions on discovery, WebFinger, and link relations.

ActivityPub also has explicit support for public posts and addressing.

Bridge design

The bridge needs to translate a few high-level things: data (probably via granary), discovery, and interaction protocols.

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,, 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.example and AP user @bob@ap.example want to interact, they’d do so via wrapped identifiers like @alice.example@bridge.example and 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 alice.example and @bob@ap.example identifiers 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. https://bridge.example/alice.example/inbox.

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. https://bridge.example/alice.example.

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>.

Interaction protocols

To convert a webmention to AP:

  1. Accept incoming webmention.
  2. Fetch source page. Translate it to AS2.
  3. Fetch target page. Determine author’s URL.
  4. Fetch author’s Actor with con-neg, extract their inbox endpoint.
  5. POST AS2 object to inbox.

To convert an AP interaction to webmention:

  1. Accept incoming POST to IW user’s AP inbox endpoint.
  2. Parse AS2 object in body, determine target URL (reply to, like of, etc). Reject POST if no target is found.
  3. Fetch target URL, discover webmention endpoint.
  4. Send webmention with AP source and IW target.

Stretch goals

  • 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’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 signClientKey field, 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:
    1. Accept Follow POST to an IW user’s AP inbox.
    2. Discover the IW user’s WebSub endpoint. Subscribe to it if it exists, otherwise reject the Follow POST.
    3. Accept WebSub pings.
    4. Convert each new IW post to an AS2 objects and POST it to the IW user’s AP followers’ inboxes.


  • 🔖 Ricardo Mendes

Leave a Reply

Your email address will not be published. Required fields are marked *