FEP-7952: Roadmap for Actor and Object Portability

Discussion thread for FEP-7952: Roadmap for Actor and Object Portability, which is a normative FEP about how to create and handle Actor-rooted (as opposed to Server-rooted) ids for objects, based on self-hosted/independently-hosted, and long-lived (migration-aware, migration-suriving) Actor objects.

Sound complicated? It’s not, I just really wanted to fit all the spicy stuff into one long sentence. Give it a read!


we believe crypto is too much of a barrier to both implementation and use, and while it does solve some issues of threat model, it also introduces different issues - particularly of key management.

in the other thread we were bringing up the idea of multihoming which we believe is a better solution to avoid these caveats. after all, you can add as much crypto as you want but ultimately if you’re on a single instance, then that one instance has full control over everything you do.

but, we’re most concerned about actor-relative URIs…

these are fundamentally incompatible with existing systems, so whatever we do with them doesn’t really matter that much. regardless of them being “http-based”, the proposed fetching and dereferencing algorithm requires changes to existing systems, and they can’t use the URIs as-is anymore. as such, we strongly recommend against misusing/overloading the fragment identifier for this purpose, not in alignment with the relevant IETF RFCs. instead, consider doing something with pseudo-URIs (like webfinger’s acct) or composable URIs (like our proposed-elsewhere auth URI, which we still need to finish writing a proper document about…).

Well, if we dropped the static-server/codeberg-pages self-hosting option, and specified dynamic-server only, any “indirect URLs” (the ? kind) wouldn’t require changes to existing systems, would they? This is one of my problems with the current spec.

More generally, though, could you say more about fragment identifiers? The LinkedData world uses fragment identifiers a lot, and they’re pretty integral to the key handling and controller docs used by the W3C Data Integrity signing mechanism that many recent FEPs are based on…

No prob, the # based / static hosting part is a minor detail, i’ll move it to a future separate fep.

fragment identifiers for posts should probably reference data inside posts, just like it does for webpages. as per URI RFC, they’re supposed to follow the content-type, but here they’re following the context they’re being presented in.

(yes there is something to be said about how they interact badly with content negotiation, but we digress)

the W3C not following the RFCs wouldn’t surprise us tho…

Ok, fragment-based relative URLs removed. Now we’re just talking about plain 302 http redirects.

To be clear, this is not a W3C effort, just a FEP.

1 Like

To be clear, I just meant that there is open-source tooling for this kinda stuff, and that using fragment identifiers within JSON-LD documents to navigate the graph was a pattern already baked in to lots of the LD tooling people use for AP already. I would be making different recommendations if i was optimizing for “where the W3C puck is headed,” as Wayne Gretzky would say.

For anyone else like me who struggled to find the full proposal text, here it is:

And the prime objective of the FEP is summed up pretty well here:

Unbundle the services and concerns of a typical instance

  1. Sign everything: Recognize client-side cryptographic signatures as proof of authorship (by implementing FEP-8b32: Object Integrity Proofs), in addition to the current practice of relying solely on the instance URL.
  2. B.Y.O. Actor ID: Using Object Integrity proofs enables Identity Hosting to be separated from the other instance concerns. Actor profiles can now be hosted separately from the instance (including as a static JSON object on a personal website), which in turn enables service providers to offer their users a “BYO (Bring Your Own) domain name” feature.
  3. Separate Inbox/Outbox: (Optional) The previous steps enable message transfer and Inbox/Outbox hosting to be outsourced to separate service providers (the Actor profile links to these in the usual manner).
  4. Separate Object and Collection hosting: (Optional) Similarly, AP Objects and Collections can now be stored on domains separate from the Actor’s domain (since authorship and controller-ship can be proven cryptographically, in a domain-independent way). This enables the user to migrate storage service providers without having to change their Actor ID.

‘B.Y.O. Actor ID’ seems like a game-changer. If I understand it correctly, it’s really all I ever needed from the notion of a ‘single-user instance’. All I want to manage on my own is my identity; I don’t want to take on the full burden of managing a whole AP server.

In this paradigm, someone’s WordPress site could also be their Actor-ID Provider, and nothing more. That ID could in turn be used to as a (reasonably nomadic) account on any FEP-7952 compatible instance. Right?


Sure, the idea is to detach the Actor object (which could be operated by a microserver that consumes almost zero resources, and basically just operates a big redirect table like a link-shortener) from the Service Provider, to be a little more like email (in the use case where you point a domain that you own and configure at protonmail or mailgun or some other provider) or SMS service (in that regulation enables you to keep your number when you switch phone co’s).

We will prototype the micro-Actor in the coming months, but we have no idea how long it would take for implementations like WordPress or forks of Mastodon/Misskey/Pleroma to offer support for this kind of externalized/self-managed Actor. We are hoping existing servers will find it interesting to offer a “service-provider mode” for the nomadic/domain-owning user class, for many reasons. In the meantime, we might also prototype a Fedify-powered server that only allows external Actors to create accounts :sweat_smile:

1 Like

I can’t say I love this design choice:


it’s basically a one-file PR! I feel like codeberg shouldn’t suppress huge diffs for files introduced in that PR! anyone who knows whom to tag at Codeberg HQ feel free to do so, I’m too lazy to find the appropriate place to file a feature request :sweat_smile:

I love this :heavy_heart_exclamation:

1 Like

(for context, here is draft-soni-auth-uri-00 - The auth URI scheme , tho we’ve taken to calling these “meta-URIs” instead of “composable URIs”…)

Reposting some chat comments from @aumetra:

Well, if I kinda conceptualize that in my head… doesn’t seem too hard to retrofit into current systems?

Everything will stay more-or-less the same. That’s good, because if it would require major refactors of subsystems (database, fetching logic, etc.) then it’s unlikely to be adopted at all

It’s an additional system slapped on the fetcher for the B.Y.O Actor ID thing, and some additional signing for the object proofs

The biggest issue I see with self-authenticating objects is the key management perspective

Mastodon tried something similar with JWS (or its predecessor; can’t remember. Something with attaching signatures to objects)

The irrevocability of these keys is an issue. If you don’t have a well-defined PKI, you can’t really do key rotation if your key gets compromised. And anything that was posted between the compromisation point and the revocation point is irrevocably linked to your identity

And that also leaves the point of the following issue: If you don’t want to give your key to instances, which you shouldn’t due to reasons stated above, you would need to sign it locally

But there is just no standard API for communication from Client-to-Server in ActivityPub that has any meaningful adoption

something similar…
Towards Federated Key Transparency - Dhole Moments

It’s from the perspective of E2E chat encryption, but you could co-opt the PKI solution… kinda

If you have these key directories, backwards recovability becomes possible because you could store additional attributes such as “invalid since [earlier point]” and therefore invalidate any forged stuff

I’m on the road and I haven’t yet deeply studied the family or FEPs related to this proposal, but I have a few questions.

How are multiple clients supported? For example, I frequently switch between a mobile (phone and tablet) and desktop browser clients.

What happens with the client keys and existing signed material cached in remote instances if I change my client devices (buy a new phone or laptop, for example)?

Will this approach work if any of the multiple client software implementations don’t support the features described in this proposal, or do they all need to support it for it to work effectively? I’m guessing the latter, unless I want to have multiple identities (I don’t)? On that topic, will I be able to migrate my existing AP actor URI (it uses my own DNS domain) to this approach?


1 Like

as the issue of URIs appears to be resolved, we would like to re-raise the issue of key management, and what we think would be a better long-term approach:

So, I don’t want to answer for Dmitri, but for me personally, I would hope key management at this layer of design is out of scope and still open to multiple configurations. The way I see it, a separately-hosted Actor object that sits in a little redirecting microservice could defer to a client that signs every new object and Activity at origination with a key it holds, OR the microservice could hold keys and [counter]sign things itself, OR it could defer to a service provider (say, today’s Mastodon slightly tweaked to be aware of this indirection service perhaps) who ignores that external actor’s public key except, say, for authenticating migration requests.

Ideally, all that matters at the Portable Objects/Identity Proofs layer is that each object is signed by a key that is resolvable from the Actor anytime a consumer wants to check those signatures-- so if clients want to sync/transfer a private key between them, OR if some service registers each client’s unique key and checks THOSE signatures before stripping them and replacing them with the signature corresponding to the Actor-published public key OR if a backing client uses fancy MPC or Schnorr signatures, all of that should be invisible to the verifying consumer, which only has to worry about the current public key they can easily resolve.

1 Like

Again, maybe Dmitri can think of counterexamples or reasons this wouldn’t work, but if the “underlying server” (say, Mastodon or *key or *oma) supports a given client and/or multiple clients, that/those client(s) might not necessarily need to know anything about the “redirection Actor”, they could just point to the legacy Actor object (at the “direct” URL) managed by the service provider.

In this sense, if the legacy server is taking in content directly from 7952-unaware clients that only know the “direct Actor id”, the problem arises of how the “indirect Actor” service finds out about these additional objects that it should be tracking and redirecting-- but perhaps I’m out on a limb here and missing something.

  • New issue: should indirect Actor microservice pull or should legacy server push if legacy server is still accepting new content after a copiedTo? Note: this may remain out of scope and just be an implementation choice, or a non-normative suggestion if included.

I’ve been trying to think through a few different configurations of movedTo and copiedTo for use-cases like this. For example:

IF a server is currently on a legacy server with no awareness of 7952-style Actors but WITH migration capabilities (including the ability to add a copiedTo value that is a 7952 actor), then an “independent actor” could serve as an “archival” indexer and manage a huge redirect table for every activity and object. This end-user could register their independent Actor in the copiedTo property of their legacy server, which consuming implementations unaware of ALL these FEPs can still safely ignore and just interface with the legacy server as primary/only server.

Then, down the road, this user can EITHER (A) migrate to a “7952”-style “headless” server that is fully aware of independent actors, OR (b)it can migrate to another conventional server and keep using the archival node as a fallback/backup tool, still listed in the new copiedTo.

In the former case, (A) that copiedTo value (the independent Actor URL) would be replaced with a movedTo property holding the same value on the old legacy server. in the latter case, (B) the new value of movedTo would be the legacy URL at the new legacy server.

  • New issue: how does a migration process from Legacy Server A to Legacy Server B work, if Archival Actor-rooted Service C were indexing both? Here we are definitely in implementation-specific terrain, but maybe there is a follow-up FEP worth writing about how Server A and/or server B signals to Actor service C that all those activities and objects need to be remapped.

Thank YOU for hard questions! I’ll probably have to circle back to these later, there’s a lot here to double-check and think through.