Nomadic identity for the fediverse?

regarding DID, for alternatives to blockchain have a look at this method

1 Like

I’ve started to do this in my project, where profiles can have verifiable links to blockchain addresses. These links are represented as attachments of Actor object, similarly to how Keybase identity proofs were done in Mastodon:

"attachment": [
    "name": "did:pkh:eip155:1:<address>",
    "type": "IdentityProof",
    "signatureAlgorithm": "<proof-type>",
    "signatureValue": "<proof-value>"

The digital signature proves that actor ID and DID belong to the same person.

To solve my specific problem I used did:pkh identifiers, but I think this approach could be used for all kinds of DIDs.


Gravatar is basically a tracker. Just for that reason I avoid it everywhere I can.

1 Like

For my own project I was also very enthusiastic for did.

We do not even need a blockchain cause many different did-methods were registered and some of them even make use of ActivityPub, e.g. The did:orb Method v0.2

The problem arised when Google and Apple raised “formal objections” against did and used their superpowers in the W3C. Then it became clear that did will not become a standard and I doubt anyone else in fedi will use it.
It is good to see people using it.
cc @steffen


a nice idea for the keys that you mention… why not use PGP for this? (lots of federated projects a.k.a. Matrix, are particularly good at requiring separate keys, rather than riding on the ones you have already.) thoughts?

Using PGP is a good idea indeed.

I’d like to support identity proofs based on GPG keys in addition to wallet-based proofs I mentioned earlier in this thread.

My general plan is to use Move() activity for account migrations, but let people sign this activity with their own key. If I understand correctly, implementation of Move() in Mastodon requires a cooperating server. If your old server is offline or if admin banned you, there’s no way to move your followers. But if user-signed activities are allowed, you can simply register new account on another server, import your follower list and send them a command to un-follow your old account and follow your new account.

To make user-signed activities possible on Fediverse, I’m working on two protocol extensions:

  • Embedded signatures. Mastodon can create them, but their implementation is outdated and not portable. There should be a clean and simple way to sign JSON object, otherwise embedded signatures will never be adopted in Fediverse. I’ve implemented JSON signing according to Verifiable Credential Data Integrity 1.0 standard (which replaces old LD signatures spec), using JCS algorithm, which is much simpler than RDF canonicalization. It has implementations in several languages and for signing simple JSON objects people can even use ordinary JSON serialization libraries that can produce compact JSON with sorted keys because the output will be the same.
  • Identity proofs. This is a verifiable link between domain-based account and user’s public key identity. When server receives activity signed by user-owned key, it can verify its authenticity just like it does when activity is signed by server-owned key.

That doesn’t solve the problem of data ownership, but I think my solution is compatible with any data migration mechanism: manual export/import, backing up on IPFS, Solid, or mirroring to multiple servers.

In the future, I want to create FEPs for both of these extensions. Feedback is welcome!


That sounds amazing… I will be keeping an eye on this.


I decided to use Minisign instead of PGP. Its signature format is simpler than PGP data format, and its public keys can be represented as did:key identifiers, while PGP keys would need a custom DID method.

I also implemented activity signing and verification using Ethereum and Minisign keys. Unfortunately there’s no browser extension that can create Minisign signatures, there are only command line tools, so this signing method is not suitable for everyone. (On the other hand, browser wallets are bad for privacy because they connect to 3rd party API providers and often contain trackers.)

In other news, Data Integrity spec was promoted to W3C Working Draft.

1 Like

Here’s my embedded signatures proposal: #21 - Add FEP-8b32: Object Integrity Proofs - fep -

I’m just learning ActivityPub, but isn’t this already possible at some level? Because ActivityPub identity files contain your public key, which can be used to verify messages in other servers.

Suppose John Doe owns he could store his identity in his own server but set outbox and inbox to some other server.

This way if he ever wants to change server to something else he just changes outbox and inbox addresses?


	"id": "",

    // Inbox/outbox points to different server
	"inbox": "",
	"outbox": "",

    // private key is in
	"publicKey": {
		"id": ",
		"owner": "",
		"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0At35owb...\n-----END PUBLIC KEY-----\n"

Ideally you could have multiple private/public key pairs, one for each client. In this case is only one, but if you had multiple you’d need multiple pairs.

If he owns the domain and the server, why would he put his inbox and outbox on some other server? I don’t see any benefit in that.
Also, in your example the identity is still linked to domain name. If the identity server is not available, other actors will be unable to fetch the key.

1 Like

It would make adoption easier if one could just put static file on own server, and let Mastodon or other server handle the dynamic parts i.e. outbox and inbox, and following etc.

(Kind of like email, you just point MX to someone who hosts the server, but you hold the identity.)

Yes it would link identity to domain, but that would be still better than putting identity files on random servers.

I know what you are after, something like in Bluesky, which has ephemeral identities with did but it also has domain specific ones.

1 Like

Yes, you’re right. Actually, I just published a FEP about that: #33 - Add FEP-c390: Identity Proofs - fep -

It’s like ATP identity but fully backwards-compatible with existing Fediverse software, and without any vendor lock-in.


Turns out FEP-8b32 is not required for migrations, and FEP-c390 should be enough to implement them. Here’s an example of Move activity:

  "@context": [
  "actor": "",
  "id": "",
  "object": "",
  "target": "",
  "to": [
  "type": "Move"
  • object is the old account
  • target is the new account (which initiates the migration)

This activity could be sent by the server even without FEP-8b32 integrity proof. Actors identified by object and target properties must have at least one FEP-c390 identity key in common to be considered aliases.


Yeah, this is looking promising. There’s a huge gulf between linking identities and having actual nomadic identities you can switch to at any time with all your content intact. I’m really not looking forward to implementing that again (it took a number of years of mind-numbing effort to make it all work smoothly under Zot/Nomad ), but the journey of a thousand miles always begins with a single step.


How it works in Zot/Nomad? (and Streams?)
Perhaps there’s a way to adapt it to ActivityPub without a complete re-write?

What we do here is send ‘sync packets’ to our clones when we change data locally on one instance. Currently this is pretty platform specific. I’ll probably create a ‘nomad:Sync’ activity type on the short term. It’s also too bad ActivityPub doesn’t provide any decent payload encryption because some of this data is sensitive, but that comes with the territory. To be fair I suppose we can just change the mediaType and send opaque encrypted blobs like we do for E2EE. So it’s still platform specific, but it would provide a way to use ActivityPub as a transport.

1 Like

I might be interested in creating interoperable implementation. The need to create clone in advance is not good from a user experience perspective (most people won’t bother until it’s too late), but I’m not sure if there’s a better way. I thought about automatically backing up content to some external storage system like IPFS: when you create a post, the server encrypts it with your public key and adds it to your personal repository which is automatically synced to your local IPFS node. Here you have full ownership of the data, but this is even more complicated than setting up a clone.

Sounds good. How nomadic identities are represented at the protocol level? Are they based on public keys?

Is TLS not enough? Is there a chance that sync activity would go through an untrusted server?


We are facing the same issue here in our project, and one idea we have is to store user data with IPNS hashes. The server can update it easily on behave of the user, and the user can migrate it to other servers easily as well.


It might be time to start giving fediverse users their own public/private key pair where they can control their private key as part of a nomadic identity

In the nostr project this is starting to work really well

It’s possible to add nomadic identity to fediverse profiles (or even solid profiles) using the following vocab:

To date I’ve added two identies

But it would be possible to add more.

The magic sauce here is the owl InverseFunctionalProperty. What it means is that anyone with a certain public key has the same identity (owl sameAs) as any other profile. So you can have two different instances and the model knows you are the same. You move from one place to another and the underlying model knows it’s the same person. Further more with a nostr key you can sign something to prove that.

Aside: A side effect of using this would be that it could bring certain projects together and allow the user more functionality. e.g. fediverse for micro blogging etc., nostr for social communication and zaps etc., solid for cloud storage etc. matrix for chat etc. with an intersection of tooling where people from different platforms can converse

There would need to be a bit of integration into different fediverse software to make it a good UX. If at some point there’s a bit of demand for this I could write up an FEP