FEP-fffd: Proxy Objects


Please use this thread to discuss FEP-fffd and any potential problems or improvements that can be addressed.

A proxy object is an [ActivityPub] object that is semantically identical to an entity on another, non-ActivityPub protocol. For example, an ActivityPub-to-Nostr bridge creates Actors and Notes that are proxies for Nostr users and notes.

This document describes a data format to identify proxy objects and to describe the non-ActivityPub entities that they are equivalent to, with the intention that multi-protocol clients will automatically merge objects with their proxies, hiding the implementation details of bridges and cross-protocol publishing from users.

Full text: FEP-fffd: Proxy Objects

1 Like

Copied from the Codeberg pull request, in reply to @silverpill asking if RSS/Atom would work as protocols:

They might. Certainly it would fit with the original use case for this FEP (Tapir, which will support following RSS feeds).

My main concern with RSS/Atom, ironically, is how universal it is: most AP servers also publish an RSS feed, and it’s unlikely that all of them will implement FEP-fffd and mark all of their posts as proxies of their RSS feed entries, resulting in inconsistent behavior.

Actually, as I think about it more, RSS/Atom may not be a good fit for this proposal for another reason: it has no interactivity. The main use case for FEP-fffd is merging interactions (replies, likes, boosts) to both an original post and its proxies. RSS feed entries don’t publish any information about interactions with them, so there would be nothing to merge.

I can think of one use case right now: a user follows an RSS feed of a Fediverse user rather than the user themselves (as a “stealth follow”?), someone else interacts with one of the followed user’s posts, and FEP-fffd allows the interactions to show up on the RSS feed entry in the following user’s timeline. Maybe that’s a compelling enough reason to support it.

We’d also need a way to uniquely identify an RSS feed entry in the proxied field. [RSS feed URL]#[Feed entry <guid> value], maybe?

1 Like

Copied from the Codeberg pull request:

This proposal defines protocol entries for Diaspora and Nostr. Ideally, it should also include entries for Zot, AT, OStatus, and maybe Secure Scuttlebutt.

Another possibility is including chat protocols, like Matrix, to make it easier to bridge chatroom conversations and AP servers.

But, in order to add these entries, for each one I’d need to decide on:

  1. A protocol IRI that uniquely identifies the protocol (I had a particularly hard time finding one for Zot)
  2. A proxied format that can address both posts/objects and users.

I’m open to suggestions for these protocols and others.

1 Like

Thanks @arnelson for the FEP and for adding the above discussion. Those can also be found as comments on the FEP’s introductory pull request here: #94 - WIP: FEP-fffd: Proxy Objects - fep - Codeberg.org


Congratulations to writing a FEP :partying_face:

I actually think this proposal lacks a clear requirement on what defines a protocol and how to add a new one.

Thinking of the element it might also be useful to define a way to track other protocols.

A protocol definition is just a unique IRI for protocol and a format for proxied, with the assumption that implementors will understand what the proxied format means, because proxyOf entries are only meant to be used by applications that also speak the proxied object’s protocol.

If you think it needs a more rigorous definition, I’m open to suggestions, but I don’t have one at the moment.

New protocols would have to be added in this document or in other FEPs. They have to be standardized, because otherwise there’s a possibility of implementors independently deciding on different proxied formats for the same IRI. (e.g., if I hadn’t defined https://nostr.com as a protocol in this document, one implementor might have defined the Nostr proxied field to use a nostr:// prefix and another might have defined it to use hex addresses instead of bech32).

I actually don’t know. Your thoughts about if this FEP should cover RSS sound like a more rigorous definition might be beneficial. Similarly, I personally consider an Email to ActivityPub bridge more natural than say Nostr to ActivityPub. Does that use fall under your FEP?

I’m not entirely convinced that we need so many properties here – is there anything you can’t do with a Link to the original resource? Because it seems like you could replace authoritative with rel=canonical, and you could replace proxied with href. Additionally, you might also use rel=convertedfrom and/or rel=external and/or rel=via?

EDIT: I also noticed that you used actor on a Note in the examples, which is inappropriate – you use attributedTo on objects, as actor is only valid on Activity


That’s a good point, I didn’t think about using Link. The Link would need some additional property to mark the proxied protocol, probably still protocol. My only concern is that href is an IRI, and I didn’t want to require proxied values to be IRIs, in case we define a protocol whose identifiers aren’t valid IRIs.

That said, I can’t think of any protocol examples that wouldn’t be IRIs (Nostr could just use nostr://). So it could work.

Do you even need a dedicated protocol signifier? Can the proxied target not be known by well-known URI scheme, mime type, or (for centralised services) hostname?

The IndieWeb people handle this with rel=canonical for the original post, and rel=syndication for downstream bridged duplicates iirc.

So in other words, I don’t think this proposal needs to be anything complicated; just some very light-weight conventions :slight_smile:

1 Like

Cool idea. I’m still trying to understand it.

Slight nit: https://nostr.com/ is an informational site, the protocol is at: GitHub - nostr-protocol/nostr: a truly censorship-resistant alternative to Twitter that has a chance of working

Nostr doesnt have a URI scheme registered with IANA yet, though nostr:npub is common on clients. Npub is a quite cool bech32 human readable string. But the canonical form in the back end is a 64 character lower case hex string. So nostr:pubkey: or nostr:event: might be easier. Bech32 has good libraries but is insanely difficult to implement from scratch.

We recently started a small W3C CG and github area, where webby things can be discussed: GitHub - nostr-protocol/nostr: a truly censorship-resistant alternative to Twitter that has a chance of working. I could open a repo about bridges if there’s interest.

Back to the FEP. What are the fields that we can fill in?

Related: sockethub, the polyglot approach to social networks: GitHub - sockethub/sockethub: A multi-protocol gateway for the Web using ActivityStream messages.

1 Like

Question, can an actor be a URI? This would allow true cross protocol interop.

Perhaps this is better:

  "id": "http://fediverse.example/status/1234",
  "type": "Note",
  "actor": "http://fediverse.example/@alice",
  "content": "Hello, world!",
  "proxyOf": [{
    "protocol": "https://github.com/nostr-protocol/nostr",
    "proxied": "nostr:event:0b397859053cd247025c693202f38eab0c0c1994183bd075e6b3ba0f127dce5b"

Original Event

  "id": "0b397859053cd247025c693202f38eab0c0c1994183bd075e6b3ba0f127dce5b",
  "kind": 1,
  "pubkey": "de7ecd1e2976a6adb2ffa5f4db81a7d812c8bb6698aa00dcf1e76adb55efd645",
  "created_at": 1683273692,
  "content": "https://void.cat/d/AkTjRf6KxyQgyMv4jigomy.webp",
  "tags": [],
  "sig": "1d3c93e8bc9e5ec83c995e3459d8c00b9d2acb0a1d9a23f59618434485d9c8e8491f45178199d7b5df0a6a5cf20d5298d6113a7f1284d0b89ae8ce357a196f0d",

Regarding this part:

if you have

"id": "nostr:event:0b397859053cd247025c693202f38eab0c0c1994183bd075e6b3ba0f127dce5b"

The protocol can be implied at from the scheme, in this case. Which is the whole intention of URIs.

I’d like to get rid of protocol if we could, and it might be possible… it just depends on how many protocols we want to support. As soon as we have to support multiple protocols that both use https: URIs, though, protocol becomes necessary again.

I’ve been looking into some of the protocols I talked about supporting. Here’s what it looks like:

  • Nostr: has its own URI schene
  • AT: has its own URI scheme
  • Diaspora: has its own URI scheme
  • Secure Scuttlebutt: has its own URI scheme
  • Zot: Zot actually uses ActivityPub messages with its own custom wrapper, so it still uses AP URIs to identify actors and objects. There’s probably no need to bridge Zot and AP.
  • OStatus: Likewise, OStatus uses URIs for posts and users. I haven’t looked into how OStatus+AP servers work, but I’d guess they share the same URIs so it knows to combine them, FEP-fffd probably doesn’t add anything here.

We could get pretty far with just these, but there are a few other possible features, all of which use https: URIs, that would collide unless we had a way to distinguish protocols separate from the URI:

  1. Proxying non-federated sites, like Twitter. I’d prefer to keep this functionality, since Twitter bridges are common and FEP-fffd makes it easier both to interact with Twitter bridges and to identify/block them if you don’t like them.
  2. Proxying RSS/Atom feeds. As I mentioned before, this would require some custom way to identify an item in an RSS feed, probably using the URI fragment.
  3. Proxying other ActivityPub objects. I didn’t mention this in the draft (and I’d have to change the wording a lot, since it mentions “non-ActivityPub protocols”), but it’s an obvious use case. For example: a bridge from Tor AP servers to the clearnet.

If we’ve settled on using Links, then we could use mediaType to distinguish these cases: application/activity+json (or application/ld+json; profile="https://www.w3.org/ns/activitystreams") for ActivityPub objects, application/rss+xml for RSS feeds, and, if no mediaType is present, it’s assumed to be a non-federated URL with application-specific meaning, like Twitter.

Also, what’s the process for submitting a new draft? Just another pull request?


After looking over the ActivityStreams spec, I have a few more thoughts about changed to FEP-fffd:

  • proxyOf is very close to the semantic meaning of url: “Identifies one or more links to representations of the object”. Perhaps the most idiomatic way to express proxy Links would be to include them as additional url entries, with rel=alternate or rel=canonical to denote the proxy role, and mediaType as needed.

    But there’s one major problem with this approach: it will almost certainly break existing software that doesn’t expect url to be an array. So perhaps a new vocabulary entry like proxyOf is still needed.

  • If proxyOf isn’t used, it might be useful to define Proxy as a new subtype of Link, to make the intended use of these links clear. This could allow inserting proxies in tag instead of url (less semantically correct, but less likely to break existing software). It could also allow inserting proxies in replies, shares, or likes, or even in followers or following, so that multi-protocol servers can communicate, for example, that they have likes or follows from other protocols, without having to create proxy objects for those followers or likes.

    (though, as I think about this more, this really muddies the meaning of “proxy” or even inverts it and maybe isn’t a good idea)

  • It would be nice to add Webmention support to this proposal. For example, a Fediverse server could receive Webmentions for its posts, then create proxy likes or replies for them, with a proxy link pointing to the source of the Webmention. This gets complicated, though, because there’s no mediaType for Webmention. rel=webmention could work, though it’s stretching the meaning of that attribute.

not a blocker imo. we shouldn’t make concessions to wrong assumptions; broken code should be fixed.

things like this make me wish that Mention was defined to be like a webmention instead of specifically calling out @ mentions. in much the same way i wish Article was defined to be like html .

1 Like

I wish things could be done that way, but in web protocols backwards compatibility always wins. If the cost of using FEP-fffd is “Mastodon can’t read your app’s activities anymore”, then no one will implement it.

Though it might be possible to split the different and provide an upgrade path: still define proxyOf, and say that proxy links are either Links in proxyOf or Links in url with rel=alternate/rel=canonical.

why not use tag instead of multiple url? that should preserve mastodon compatibility for now… although i still disagree that we should restrict ourselves to this mindset. implementing the change would incentivize mastodon et al to handle it. in the same way mastodon adding something would incentivize others to consider also adding it. (of course, there is also not caring for mastodon compat in cases where they are “wrong” – bear in mind that mastodon is not a standard… at least not at this time.)

In PeerTube videos, the value of url property is an array of Links. I think other major platforms already support this kind of value because they federate with PeerTube.

Furthermore, we can see that PeerTube uses Links to bridge BitTorrent and ActivityPub:

      "type": "Link",
      "mediaType": "application/x-bittorrent;x-scheme-handler/magnet",
      "href": "magnet:?xs=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Ftorrents%2F969bf103-7818-43b5-94a0-de159e13de50-536.torrent&xt=urn:btih:673aaa764ad4ba61aa5b50306a5fd77fdbd4e78e&dn=HLS+test+1&tr=wss%3A%2F%2Fpeertube2.cpy.re%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube2.cpy.re%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Fwebseed%2F969bf103-7818-43b5-94a0-de159e13de50-536.mp4",
      "height": 536