Background
FEP-ef61 introduces portable ActivityPub object identifiers using ap URIs, and the spec notes that the scheme may change to ap+ef61 in a future revision. Since Fedify represents IRIs/URLs as JavaScript URL objects throughout the vocabulary layer, we need vocabulary codecs to accept these URI schemes before we can implement the rest of FEP-ef61.
There is one awkward detail: the FEP says that ap URIs are constructed according to RFC 3986, but treats identifiers such as ap://did:key:.../actor as canonical even though reserved characters in the authority component are not percent-encoded. JavaScript URL rejects that form, but accepts the encoded form, for example ap://did%3Akey%3A.../actor.
For Fedify, we should treat ap+ef61: as the canonical portable-object scheme going forward, while still accepting ap: for compatibility with the current FEP text.
Proposed work
Add a small URI normalization and serialization layer in @fedify/vocab-runtime so generated vocabulary codecs can safely handle portable ActivityPub URI schemes.
The helper should:
- accept both
ap: and ap+ef61: URI strings;
- accept both decoded DID authority forms, such as
ap+ef61://did:key:.../actor, and URL-safe encoded forms, such as ap+ef61://did%3Akey%3A.../actor;
- store the value internally as a JavaScript
URL object using the URL-safe encoded authority form;
- serialize portable URIs back to the canonical external form, using the decoded DID authority;
- normalize
ap: input to ap+ef61: when producing canonical output;
- expose a canonicalization helper suitable for comparisons, including the FEP-ef61 rule that query components are ignored.
Update @fedify/vocab-tools so generated codecs use this runtime helper instead of calling new URL(value) directly for IRI-valued fields, and use the matching serializer instead of emitting URL.href directly.
Scope
This issue is only about carrying portable URI identifiers through the vocabulary layer without corrupting their canonical form.
It does not include:
- gateway dereferencing;
- compatible HTTP identifier conversion;
- DID document resolution;
- FEP-8b32 proof verification rules for portable objects;
- FEP-fe34 cryptographic origin checks;
- FEP-ae97 client-side signing or gateway registration.
Those should be handled in follow-up issues under #288.
Tests
Add regression tests showing that generated vocabulary classes can parse and serialize portable URI values in common IRI-valued properties, including at least:
- object
id;
- activity
actor;
- object
attributedTo;
- actor
inbox and outbox;
- collection pagination links if they are handled by the same generated URL codec.
The tests should cover:
- decoded
ap: input;
- encoded
ap: input;
- decoded
ap+ef61: input;
- encoded
ap+ef61: input;
- canonical output using
ap+ef61: with a decoded DID authority;
- comparison canonicalization that ignores the query component.
Background
FEP-ef61 introduces portable ActivityPub object identifiers using
apURIs, and the spec notes that the scheme may change toap+ef61in a future revision. Since Fedify represents IRIs/URLs as JavaScriptURLobjects throughout the vocabulary layer, we need vocabulary codecs to accept these URI schemes before we can implement the rest of FEP-ef61.There is one awkward detail: the FEP says that
apURIs are constructed according to RFC 3986, but treats identifiers such asap://did:key:.../actoras canonical even though reserved characters in the authority component are not percent-encoded. JavaScriptURLrejects that form, but accepts the encoded form, for exampleap://did%3Akey%3A.../actor.For Fedify, we should treat
ap+ef61:as the canonical portable-object scheme going forward, while still acceptingap:for compatibility with the current FEP text.Proposed work
Add a small URI normalization and serialization layer in
@fedify/vocab-runtimeso generated vocabulary codecs can safely handle portable ActivityPub URI schemes.The helper should:
ap:andap+ef61:URI strings;ap+ef61://did:key:.../actor, and URL-safe encoded forms, such asap+ef61://did%3Akey%3A.../actor;URLobject using the URL-safe encoded authority form;ap:input toap+ef61:when producing canonical output;Update
@fedify/vocab-toolsso generated codecs use this runtime helper instead of callingnew URL(value)directly for IRI-valued fields, and use the matching serializer instead of emittingURL.hrefdirectly.Scope
This issue is only about carrying portable URI identifiers through the vocabulary layer without corrupting their canonical form.
It does not include:
Those should be handled in follow-up issues under #288.
Tests
Add regression tests showing that generated vocabulary classes can parse and serialize portable URI values in common IRI-valued properties, including at least:
id;actor;attributedTo;inboxandoutbox;The tests should cover:
ap:input;ap:input;ap+ef61:input;ap+ef61:input;ap+ef61:with a decoded DID authority;