Background
FEP-ef61 uses FEP-8b32 Object Integrity Proofs as the main authentication mechanism for portable objects. In FEP-ef61 examples, the proof's verificationMethod is a DID URL such as did:key:z6Mkr...#z6Mkr..., not an HTTP(S) URL.
Fedify already supports Object Integrity Proofs and FEP-521a Multikey verification methods, but the current verification path assumes that the verification method can be fetched as a JSON-LD document. verifyProof() calls fetchKey(proof.verificationMethodId, Multikey, ...), and fetchKey() currently goes through the normal cache/fetch/parse path for CryptographicKey or Multikey documents.
That does not work for did:key: the verification method is self-certifying and should be resolved from the DID itself, without calling the document loader.
This is a prerequisite for verifying portable objects whose identifiers use ap: or ap+ef61: URI schemes.
Proposed work
Add support for resolving did:key verification methods used by Object Integrity Proofs.
In @fedify/vocab-runtime, add helper functions for Ed25519 did:key handling:
- convert an Ed25519 public
CryptoKey to a did:key DID using base58-btc multibase encoding;
- convert a supported
did:key DID back to an Ed25519 public CryptoKey;
- parse DID URLs of the form
did:key:z...#z...;
- validate the multicodec prefix and reject unsupported key types;
- check that the DID URL fragment identifies the same key material as the DID.
These helpers should build on the existing multibase/multicodec key code in @fedify/vocab-runtime, including importMultibaseKey() and exportMultibaseKey(), rather than adding another encoding implementation.
In @fedify/fedify, update the key lookup path used by Object Integrity Proofs:
- detect
did:key verification method IDs before the normal remote fetch path in fetchKeyDetailed() or the lower-level helper it delegates to;
- when the requested class is
Multikey, resolve the DID locally and return a Multikey instance with the DID URL as its id, the DID as its controller, and the decoded Ed25519 public key as publicKey;
- do not call
documentLoader for this path;
- preserve existing key cache behavior where it makes sense, but avoid caching malformed or unsupported DID values as remote fetch failures;
- keep existing HTTP(S)
CryptographicKey and Multikey lookup behavior unchanged.
The intended result is that verifyProof() can verify an eddsa-jcs-2022 proof whose verificationMethod is a did:key DID URL, without any network access for the verification method.
Scope
This issue is only about resolving did:key verification methods for Object Integrity Proof key lookup.
It does not include:
- full DID document resolution;
- support for DID methods other than
did:key;
- support for key types other than Ed25519;
- enforcing FEP-ef61's rule that the proof
verificationMethod DID must match the portable object's ap:/ap+ef61: authority;
- gateway dereferencing;
- compatible HTTP identifier conversion.
Those should be handled in follow-up issues under #288.
Tests
Add regression tests for both the runtime helpers and proof verification path.
The tests should cover:
- exporting an Ed25519 public key to a
did:key DID;
- importing the same
did:key DID back to an equivalent Ed25519 public key;
- rejecting unsupported or malformed
did:key values;
- resolving
did:key:z...#z... as a Multikey verification method without calling the document loader;
- verifying a FEP-8b32 proof whose
verificationMethod is a did:key DID URL;
- confirming that existing HTTP(S) key lookup still uses the current cache/fetch/parse path.
Background
FEP-ef61 uses FEP-8b32 Object Integrity Proofs as the main authentication mechanism for portable objects. In FEP-ef61 examples, the proof's
verificationMethodis a DID URL such asdid:key:z6Mkr...#z6Mkr..., not an HTTP(S) URL.Fedify already supports Object Integrity Proofs and FEP-521a
Multikeyverification methods, but the current verification path assumes that the verification method can be fetched as a JSON-LD document.verifyProof()callsfetchKey(proof.verificationMethodId, Multikey, ...), andfetchKey()currently goes through the normal cache/fetch/parse path forCryptographicKeyorMultikeydocuments.That does not work for
did:key: the verification method is self-certifying and should be resolved from the DID itself, without calling the document loader.This is a prerequisite for verifying portable objects whose identifiers use
ap:orap+ef61:URI schemes.Proposed work
Add support for resolving
did:keyverification methods used by Object Integrity Proofs.In
@fedify/vocab-runtime, add helper functions for Ed25519did:keyhandling:CryptoKeyto adid:keyDID using base58-btc multibase encoding;did:keyDID back to an Ed25519 publicCryptoKey;did:key:z...#z...;These helpers should build on the existing multibase/multicodec key code in
@fedify/vocab-runtime, includingimportMultibaseKey()andexportMultibaseKey(), rather than adding another encoding implementation.In
@fedify/fedify, update the key lookup path used by Object Integrity Proofs:did:keyverification method IDs before the normal remote fetch path infetchKeyDetailed()or the lower-level helper it delegates to;Multikey, resolve the DID locally and return aMultikeyinstance with the DID URL as itsid, the DID as itscontroller, and the decoded Ed25519 public key aspublicKey;documentLoaderfor this path;CryptographicKeyandMultikeylookup behavior unchanged.The intended result is that
verifyProof()can verify aneddsa-jcs-2022proof whoseverificationMethodis adid:keyDID URL, without any network access for the verification method.Scope
This issue is only about resolving
did:keyverification methods for Object Integrity Proof key lookup.It does not include:
did:key;verificationMethodDID must match the portable object'sap:/ap+ef61:authority;Those should be handled in follow-up issues under #288.
Tests
Add regression tests for both the runtime helpers and proof verification path.
The tests should cover:
did:keyDID;did:keyDID back to an equivalent Ed25519 public key;did:keyvalues;did:key:z...#z...as aMultikeyverification method without calling the document loader;verificationMethodis adid:keyDID URL;