Background
FEP-ef61 uses FEP-8b32 Object Integrity Proofs as the main authentication mechanism for portable objects. Fedify already has lower-level proof verification for eddsa-jcs-2022, but FEP-ef61 requires additional policy checks.
For a portable actor, activity, or object identified by an ap: or ap+ef61: URI, it is not enough for the proof signature to be cryptographically valid. The proof's verificationMethod must be a DID URL, and the DID must match the authority component of the portable object's canonical URI.
For example, a Note with this ID:
ap+ef61://did:key:z6MkAlice/objects/1
must not be accepted as a valid portable object if its proof is signed by:
did:key:z6MkMallory#z6MkMallory
even if the signature itself is valid for Mallory's key.
This issue is about adding the policy layer above the existing Object Integrity Proof verifier. It depends on the did:key verification method resolver and FEP-fe34 cryptographic origin work under #288.
Proposed work
Add a helper in @fedify/fedify for validating the FEP-ef61 proof policy for portable objects.
The helper should:
- detect whether an actor, activity, object, or collection is identified by an
ap: or ap+ef61: URI;
- require actors, activities, and non-collection objects identified by portable URIs to contain a FEP-8b32 integrity proof;
- verify the proof using the existing
verifyProof() path;
- require the proof's
verificationMethod to be a DID URL;
- compare the DID from
verificationMethod with the decoded DID authority of the portable object ID;
- reject proofs where the DID does not match the portable object authority;
- use the shared FEP-fe34 origin helper where appropriate, so the comparison stays consistent with cryptographic origin handling;
- keep lower-level
verifyProof() focused on cryptographic signature verification rather than FEP-ef61 policy enforcement.
The intended API can be decided during implementation, but it could look roughly like:
verifyPortableObjectProof(
jsonLd: unknown,
options?: VerifyPortableObjectProofOptions,
): Promise<PortableObjectProofResult>;
The result type should make it possible to distinguish common outcomes, such as:
- not a portable object;
- missing proof;
- invalid proof;
- unsupported verification method;
- verification method DID mismatch;
- verified.
Scope
This issue is only about enforcing the FEP-ef61 proof policy for portable actors, activities, and objects.
It does not include:
- implementing
did:key resolution itself;
- implementing portable URI canonicalization;
- implementing FEP-fe34 cryptographic origin helpers;
- gateway dereferencing;
- compatible HTTP identifier conversion;
- inbox or outbox forwarding;
- FEP-ae97 client-side signing;
- collection trust policy for unsecured portable collections.
Collection handling should be designed separately because FEP-ef61 allows portable collections to be served without integrity proofs when they are retrieved from a trusted gateway.
Tests
Add regression tests for the policy helper.
The tests should cover:
- a portable object with a valid proof whose
verificationMethod DID matches the object ID authority;
- a portable actor with a valid matching proof;
- a portable activity with a valid matching proof;
- a portable object with no proof;
- a portable object with an invalid proof;
- a portable object whose proof is signed by a different DID;
- a portable object whose
verificationMethod is not a DID URL;
- non-portable HTTP(S) objects being reported as outside this policy rather than rejected;
- collection objects being treated according to the scoped behavior chosen for this issue.
This should be added as a sub-issue of #288.
Background
FEP-ef61 uses FEP-8b32 Object Integrity Proofs as the main authentication mechanism for portable objects. Fedify already has lower-level proof verification for
eddsa-jcs-2022, but FEP-ef61 requires additional policy checks.For a portable actor, activity, or object identified by an
ap:orap+ef61:URI, it is not enough for the proof signature to be cryptographically valid. The proof'sverificationMethodmust be a DID URL, and the DID must match the authority component of the portable object's canonical URI.For example, a
Notewith this ID:must not be accepted as a valid portable object if its proof is signed by:
even if the signature itself is valid for Mallory's key.
This issue is about adding the policy layer above the existing Object Integrity Proof verifier. It depends on the
did:keyverification method resolver and FEP-fe34 cryptographic origin work under #288.Proposed work
Add a helper in
@fedify/fedifyfor validating the FEP-ef61 proof policy for portable objects.The helper should:
ap:orap+ef61:URI;verifyProof()path;verificationMethodto be a DID URL;verificationMethodwith the decoded DID authority of the portable object ID;verifyProof()focused on cryptographic signature verification rather than FEP-ef61 policy enforcement.The intended API can be decided during implementation, but it could look roughly like:
The result type should make it possible to distinguish common outcomes, such as:
Scope
This issue is only about enforcing the FEP-ef61 proof policy for portable actors, activities, and objects.
It does not include:
did:keyresolution itself;Collection handling should be designed separately because FEP-ef61 allows portable collections to be served without integrity proofs when they are retrieved from a trusted gateway.
Tests
Add regression tests for the policy helper.
The tests should cover:
verificationMethodDID matches the object ID authority;verificationMethodis not a DID URL;This should be added as a sub-issue of #288.