Reuse of Identity Channel Addresses & Revocation/Reissue of Keys

A simple question on the Hubzilla Support Forum turned into a fascinating discussion about how you can’t reuse channel addresses ( ever again because some clients/instances will treat it as a forged identity if a new set of keys are issued.

One of many example scenarios given were a university screwing up their fediverse instance/hub and having to reinstall it, only to find out that they can’t use ever again because other instances will silently ban or ignore it (treat it as forged).

I can understand why this would be done, but I don’t believe that is a sustainable policy in the long run as the fediverse grows. You also have situations where it is desirable or even necessary to change keys, perhaps because a private key was leaked.

Perhaps it could be handled the following way:

  • If the keys are different for a channel address (channel@example.tld), then treat it as if it was a new channel. Have some standard or recommended way of indicating that the old ID and new ID may not be the same person.

  • If the identity provider declares that a key change has been made, and can verify that both the old key and the new key both belong to the same identity, then treat the new key as the correct one, and reject the old key as being forged for all future correspondence.

This would handle both lost keys (with account recreation being treated as a separate new account) and key revocation/reissue.

How do you think key changes should be handled via ActivityPub?

The conversation, for reference:


While I am thinking about it, there would have to be a way to indicate to the public that a channel address ( has a different key and therefore may be a different person or actor.

If the instance/client does not know about the old identity:

  • Display the identity normally, since they don’t even know an older version of the identity existed.

If the instance/client has already encountered the old ID (key) and is sent a new ID (key) with the same channel address, then:

  1. Check back with the identity provider and have them clarify which ID (key) is the correct one for the channel address.

    • Is this a key revocation/reissue situation?
    • Does the identity provider claim that only one of the IDs (keys) are currently valid?
  2. Update the local security settings based on what the identity provider states.

    • If this is a revocation/reissue situation, only accept the new ID (key) and reject the old ID (key) as forged. No need to display any notice to users or the public since the actor would be considered the same actor.

    • If the old ID (key) is reported by the identity provider as invalid (and not a revoke/reissue), indicate this change to users.

      • Treat the old ID (key) and the new ID (key) as if they were different actors.
      • Reject any ID (keys) the identity provider says are invalid.
      • Display “ (old)” next to old posts with the old ID (key).
      • Display “ (recreated 2023-01-14)” next to new posts with the new ID (key) if the change was made less than a year ago.
      • Display “ (new)” next to new posts with the new ID (key) if the key change was made over a year ago.

This would provide public notice that the channel address may or may not be the same person or entity.

This is where Spritely prefers a petname system. See Implementation of a petnames system in an existing chat application and Petname Systems -- Spritely

Petnames look interesting, and it seems to mirror the ability to create your own display name, but it does not seem to address situations where your cryptographic public and private key changes.

The problem is that behind the scenes, ActivityPub, Zot, and Nomad all use cryptographic keys to verify that you are who you say you are. This becomes a problem when you change your keys.

For example, if you reinstalled Hubzilla and no longer had access to your identity’s private key, you could recreate the same exact account, with the same exact display name (petname) and same exact address (, but it would have a different private and public key now.

For a user perspective, the account looks identical. From a security standpoint, the old account and new account are not the same account because they have different keys.


Your handle couldn’t be found, but I tooted this.

1 Like

Sorry, I updated my handle but hadn’t changed my profile here yet. I just updated my profile with the correct handle:


Which ones? Name and shame them. Ultimately, whoever controls controls what user resolves to, and half measures like preventing key rotation are only harmful in the long run.

My understanding is that right now if a key change is detected, Mastodon will resend the follow requests associated with the old profile, on the assumption that the new server has lost its database and needs to be repopulated. The Follower Collection Synchronization FEP was intended to replace some of this logic and make it more robust


Interesting. So Mastodon assumes that the old identity and new identity are the same person?

That would provide some security issues and weird consequences. For example:

Situation: Different person takes over an old handle

  • If the person who registered the new identity is not the same person, they will wind up being followed by the old person’s followers on Mastodon.
  • The new person can impersonate the old person, since there is no way to visibly tell the difference, unless the new person uses a different display name.

Situation: Accessing platforms that determine permissions by identity

  • If you have permissions set up so that a specific identity (person) can view certain posts, files, direct messages, etc., if you incorrectly assume the old identity and the new identity are the same person, the new person with the same handle will have access to those posts and files too. If a domain name changed hands, the new owner can basically spoof everyone that was ever on that server.

    Some platforms determine security by identity. For example, in Hubzilla, you can give specific identities permission to view certain content and send direct messages. So knowing whether an identity is the same person becomes important.

1 Like

Most AP implementations use HTTPS for server-to-server communication so domain owner is a trusted entity. I think if you trust the domain, then you should trust any server-owned key too, and if the key has changed, you should accept it.
But if the key is not controlled by server (e.g. FEP-c390), everything becomes more complicated because there’s no clear authority. The DID standard comes to the rescue: if the key has a corresponding DID, we can look at DID method specification to see how key rotation/revocation works for a particular identifier (“update DID document”, in their parlance). Still, key revocation is difficult to do in a completely decentralized way. Many DID methods either don’t provide the way to update document or rely on some centralized service. The only solution I’m aware of is to use blockchain for key management. A good explanation of key revocation problem and potential solutions can be found here: Where to use a blockchain in non-financial applications?.


This is up to to handle internally. There is no way for Mastodon to tell the difference between a new person taking over an old handle and the same person continuing to use the handle. The primarily identifier for all ActivityPub accounts is their id. as long as the ID is the same, the follows are still valid. I don’t see any other way to interpret the spec. Public keys aren’t even required by the ActivityPub spec, they’re an extension to prevent having to refetch posts all of the time.

That said, if a person deletes their account, that also deletes all of the following relationships. I believe Mastodon will keep that account around as a tombstone to stop it being reused in the future after being deleted for exactly this reason.


Yes, we are talking about keys that are tied to a person or channel’s identity, and not the server key here. The server would be the custodian of the person or channel’s key, so the server still is a trusted source, at least on platforms where the server manages user keys.

So FEP-c390 would be related to this discussion.

1 Like

One thing to consider is that there are three types of identity proofs:

  1. Decentralized Identities (DIDs)
  2. Identities managed by an Identity Provider (i.e. the server)
  3. Nomadic identities that are managed by the server, but may exist on multiple servers or be moved.

All use cryptographic keys, but we might want to handle them differently.

Either way, there has to be some protocol for handling situations where the key changes. I opened this discussion to discuss options.

1 Like

I suggest the following:

  1. Trust on first use. Accept new key only if replacement is performed according to some pre-determined procedure (for example, if a DID document was updated). Reject new key otherwise.
  2. Trust identity provider, always accept new key.
  3. Depends on the implementation, but I think regardless of implementation there should be a single authority. In (1) the authority is the owner of a DID document. In (2) authority is identity provider.

Re: Nomadic Identites:

Very few systems implement nomadic identity currently. How the Hubzilla / Streams family of servers handle it is unique.

When communicating via the Zot or Nomad protocols, an identity is defined by its cryptographic key, not its handle. This means that a person’s identity can exist on multiple servers with multiple handles. There is always a primary handle, and all of the rest are secondary handles (i.e. clones). But a person can change any of their handles to be the primary one at any time. All of these clones are synced, and they can use any of them to communicate with any Zot of Nomad compatible system.

When communicating via ActivityPub, this is no longer the case, and the identity is no longer nomadic (as far as ActivityPub is concerned). According to ActivityPub, your identity is related to your handle, and it treats each clone as a different identity.

If FEP-c390 were to be made compatible with nomadic identities, it would have to be able to list multiple alsoKnownAs entries.

All of the clones know about all of the other clones, so you could query any of them to get the list of valid clones and which is considered primary.

Note: This is a very simplified explanation of how it works.

We should still distinguish between a revoke/reissue situation and a reinstall situation.

  • Revoke/reissue = same identity
  • Reinstall = identities may be different, treat as different identities

Because for systems that define access via identity, this has security implications.

1 Like

FEP-c390 identity proofs are bi-directional. The user attests that he controls the given actor by signing the Identity object containing actor ID (alsoKnownAs). The server attests the same by serving the actor object with identity proof attached.
If we require user to include other actor IDs in alsoKnownAs array, then everyone would need to fetch listed actors to verify that they are actually controlled by the same person. Identity proofs would also need to be re-generated every time a new clone is created.

I don’t think this is necessary. If two actors have identity proofs generated with the same key, FEP-c390-aware servers should treat them as clones/aliases. I have a working implementation of “weak” nomadic identity where you can move followers from one clone to another (but not data), which is based on this idea.


That sounds similar to how Hubzilla works. Your access is determined by your identity proof, not your handle. This model has been tested for awhile and seems to work well.

The only difference is that Hubzilla will know which one is primary or not, and displays the primary handle next to your posts, regardless of which clone you post from. I think this is important because it provides a consistent handle to people viewing the posts. It also directs any follow requests and direct messages to the primary instance.

That is a good start. They are not truly clones if you don’t move the content as well, but at least it makes migration easy.

One thing to consider is that the GDPR requires data portability, so you probably already have a way to for users to download their own content. If that is the case, the next logical step would be to make it easy to migrate that content to a new clone/instance.

1 Like

TOFU makes sense but imo all this cryptographic stuff is being done at the wrong layer. if the actor’s identity is owned by DNS (as activitypub uses https IRIs in the current network), and an actor is managed by some “instance” software running on that domain, then the actor keys don’t matter. at all. the keys belong to the server, so they should actually be owned by and attributed to the server. i’d much rather see the “instance actor” idea expanded upon such that you TOFU the instance and then if the keys get changed for whatever reason, you have to confirm it’s still the same instance in your admin dashboard. having keys on each actor is fine but they should probably be signed by the instance actor at least, or otherwise managed on an activitypub client (which may itself be an app-server or a monolithic implementation).


Yes, this seems to be an optimal solution (for domain-bound identities). To make it possible there should be a way to auto-discover instance actors. For example, we can agree to place instance actor at domain root, as was suggested in this thread: Activities for Federation Application?

Trust On First Use (TOFU) is a good way of identifying a new identity, but there are challenges with decentralized identities (DIDs) and nomadic identities, which can change server.

A nomadic identity can exist on multiple servers at the same time. For example, in Hubzilla, you can clone your identity onto another server, and your contacts, followers, posts, content, etc. sync automatically. This means that if one server goes down or you are unable to log in to one server, you are able to log into your identity on a different server and not lose any anything.

Also, for nomadic identity, the actor’s identity is not at the DNS level, it is managed by the servers. (This is why ActivityPub considers each clone to be a separate identity. It doesn’t understand what a clone is.)

Because of this unique functionality, Hubzilla has to use the Zot protocol instead of ActivityPub when talking to other instances compatible with Nomadic identity. Via the Zot protocol, an identity comes with a unique identifier that can be verified by cryptographic key, its primary address (, and a list of all of its known clones.

So for nomadic identities, you are dealing with the server, not DNS, when validating identities. And, at least in the Zot protocol, each server is able to tell you where all the valid clones are for a specific identity. The server is still the identity provider, even if the identity itself is nomadic.

Decentralized identities (DIDs), on the other hand, have a completely different way of handling identities.