FEP-c390: Identity Proofs

I think that I don’t have a technical issue, but a usability one. I was scanning the did-core closed issues and found the following:

Because developers will end up doing horrible things if we put a bucket called encryption in the DID Document… where they will store their symmetric encryption keys and dump them to a ledger, pwn’ing data that they encrypt using that same key.

This is to say, I don’t know what exactly a good answer to is

However, I can describe my personal non-expert opinion. Key pairs will will have at least three duties:

  1. A user “Alice”, i.e. a physical human being, holds a EdDSA private key and uses a did document attached to the actor “@Alice” to indicate: “Yes, this is Alice’s account”.
  2. The server the Actor @Alice is on, holds a EdDSA private key and uses a did document attached to the actor for
    2.1. Yes, this key identifies the Actor @Alice
    2.2. Authenticate communications with other servers.
  3. The user Alice holds a private RSA key, and attaches it to the actor @Alice. Now, Bob can encrypt a message using the public key, and send it to @Alice via @Bob without the servers in the middle being able to read the message.

I would be less confused by the three attached keys to an account and their usage if they had dedicated types. Also one might want to consider easier to use short hands for the keys, e.g. refer to the key in 2 as “@Alice’s id#serverPublicKey”.

I’m no expert on cryptography or attack vectors on public/private key infrastructure. One should probably ask one, before deciding to propose something akin to the above.

Additional thought. I might want to automatically rotate the key in 2. This has all kinds of consequences for using it for signing documents. I’m not comfortable enough on the subject to draft a best practice on how to do this.


This is a technical point. In the json document, one should use https://example.com/users/alice#did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK as id for the Identity object, e.g.

            "type": "Identity",
            "id": "https://example.com/users/alice#did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
            "alsoKnownAs": "https://example.com/users/alice",
            "proof": {
                "type": "JcsEd25519Signature2022",
                "created": "2022-11-12T00:00:00Z",
                "verificationMethod": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
                "proofPurpose": "assertionMethod",
                "proofValue": "<proof-value>"

The reason for this, is that we want an id to identity its document. Using this fragment notation makes it clear that the Identity document is meant to be a part of the Alice Person document.

Furthermore, the json with id did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK should be the corresponding did document, that is

  "@context": [
      "Ed25519VerificationKey2018": "https://w3id.org/security#Ed25519VerificationKey2018",
      "publicKeyJwk": {
        "@id": "https://w3id.org/security#publicKeyJwk",
        "@type": "@json"
  "id": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
  "verificationMethod": [
      "id": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
      "type": "Ed25519VerificationKey2018",
      "controller": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
      "publicKeyJwk": {
        "kty": "OKP",
        "crv": "Ed25519",
        "x": "Lm_M42cB3HkUiODQsXRcweM6TByfzEHGO9ND274JcOY"
  "authentication": [
  "assertionMethod": [

as computed via https://resolver.identity.foundation/

1 Like

This is already indicated by Identity document being an attachment of actor object. Also, Identity is semantically similar to a Link type.

Yes, the consuming implementation should resolve the DID in order to verify the proof, if that is what you mean.

using a fragment should correlate to when the identity document is actually a part of the document. if the document is to be fetched separately, it should have its own path element

1 Like

The main point is: Don’t use the id of the verification document, i.e. the document with keys “verificationMethod”, “authentication”, and “assertionMethod” for the document with type “Identity”.

See Activity Vocabulary

id Provides the globally unique identifier for an Object or Link.

If you don’t want to give it an id with a fragment, then drop the id property or name it something else.

Another possible name is issuer, which is used in Verifiable Credentials spec: Verifiable Credentials Data Model v1.1.

Identity document is actually a trimmed down verifiable credential. At the moment I don’t want to complicate FEP-c390 further by adding credentialSubject and issuanceDate properties required by VC spec. However, in the next edition of FEP-c390 I’m going to drop this line:

The document MUST not contain any additional properties.

Just in case.

I’ll think I’ll refrain on further comments until the next version. I would have encouraged dropping this line anyway, as I feel like there should be an expires property associated to the credentials.

Here’s the next version: #69 - FEP-c390: Update proposal - fep - Codeberg.org

I’m considering making the following changes:

  • Rename id to subject to make it clear that entity denoted by this property is not an ActivityPub object. The term “subject” is also used in Verifiable Credentials Data Model v1.1 spec.
  • Rename Identity to LinkedIdentityProof because “identity subject” doesn’t make sense. The IdentityProof name would be more appropriate but it is already used for Mastodon-style identity proofs.
  • Maybe rename alsoKnownAs to sameAs or aliasOf. This depends on the outcome of this discussion: Defining alsoKnownAs - #30 by trwnh

which namespace or vocab is subject coming from?

i don’t think mastodon plans to reimplement identity proofs, so it might be okay to consider? or otherwise, you could define the same term in a different namespace.

unfortunately i don’t yet know enough to comment further.

i am inclined to say you could either reuse alsoKnownAs or perhaps eliminate its usage entirely depending on how you structure this “identity proof” node. but again, i don’t yet know enough to comment further.

1 Like

I think the change idsubject is good.

I just looked through it, and I noticed the discrepancy between JcsEd25519Signature2022 and the document https://identity.foundation/JcsEd25519Signature2020/

Upon reading it, I think, we do not want to use JcsEd25519Signature2020 as

Base58 encode the result and set it as the signatureValue on the document

seems bad. I would prefer to use Multibase to encode the signatureValue, i.e. do exactly the same but add a z at the beginning. This makes the entire thing less ambiguous. This would lead to the algorithm

  1. Take the input document, i.e. the subobject of type LinkedIdentityProof without adding a @context property, embeded with a proof block containing all values except the signatureValue
  2. Canonicalize the document using JCS
  3. Apply the SHA-256 Hash Algorithm.
  4. Sign the result with the private key
  5. Multibase encode the result and set it as the signatureValue on the document
1 Like

It’s a new property. Verifiable Credentials vocabulary contains credentialSubject term, but identity proof is not a verifiable credential (yet) so I would prefer to use another name.

Mastodon still attaches legacy identity proofs to actors. I assume a different namespace would work for JSON-LD aware implementations but others will have difficulties.

Actor ID should be signed too, otherwise identity proof would be incomplete. Someone could attach such proof to an actor that subject doesn’t control.

JcsEd25519Signature2022 type is a placeholder. Currently, there’s no such cryptosuite.

https://identity.foundation/JcsEd25519Signature2020/ exists but I believe it is deprecated. Data Integrity spec now uses proofValue instead of signatureValue, and in the future it will recommend using type: DataIntegrityProof along with cryptosuite property.

W3C-VC workgroup is already working on modernized JCS+EdDSA cryptosuite, here’s a pull request: https://github.com/w3c/vc-di-eddsa/pull/26

1 Like

What is the best way to register new vocabulary terms for a FEP?
There are two related proposals, FEP-2e40 and FEP-cb76. I’m leaning towards FEP-2e40 but it seems to be WIP so I’m not sure what to do.

@helge @trwnh

i’m in the process of writing up a more fleshed-out version of / alternative to 2e40, and i may withdraw cb76 if no interest (or otherwise rework it, idk)

currently the “best” way is to use your own domain, but 2e40 or my rewrite would propose using w3id.org/fep to point toward the fediverse/fep repo on codeberg (although the documentation host can be swapped later). where my rewrite differs is mainly in making each fep self-contained instead of having a “common” context that is prone to write conflicts.

the more cb76 route (using a urn) would involve urn:publicid:fep:xxxx:term or urn:sha256:… as currently described. this is not “wrong” per se but it is not favoured among the w3c/jsonld/rdf people, who tend to prefer http(s) uris over urns for ideological reasons (and some practical onces, albeit imo shortsighted)


I think me and @trwnh are in agreement on the process, i.e. the format for adding a term will be as shown in Example “Create FEP term: eventSource”.

The disagreement is about how to store the information afterwards. I’m not 100% certain how @trwnh envisions his solution, so I asked him to work out the details. I’m probably still too stuck in my thinking to see it (or judge if it can be better).

The basic result should be hopefully the same, use:

"@context": "https://www.w3id.org/fep"

then json-ld magic, then all ActivityStreams 2.0 + FEP terms available.


Is there any utility to redundant @context terms?

the most recently defined term wins out. so whatever is at the end of the list is what gets used. you can also define @context for a specific node, not just at the top level.

What do you mean by “redundant”? I really cannot place how it relates to the discussion here.

My personal opinion is that it is too hard to create @context terms at the moment. Otherwise, we would not have the mess of Mastodon abusing summary as a content warning. If Mastodon at least used the name property, the usage of content warnings of titles, would reflect my interpretation of what the property does according to ActivityStreams.

this is definitely offtopic yeah but mastodon uses summary because the cw is more like a subject than a title. also the name must be plain-text iirc