Skip to content

Resolve did:key verification methods for Object Integrity Proofs #827

Description

@dahlia

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.

Metadata

Metadata

Assignees

Fields

Priority

High

Effort

Medium

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions