Skip to content

Context helpers for FEP-ef61 portable IDs #841

Description

@dahlia

Background

FEP-ef61 identifies portable actors and objects with ap: URIs whose authority component is a DID. Fedify plans to use ap+ef61: as its canonical portable-object scheme while still accepting ap: where needed.

Applications should not have to hand-build these identifiers by string concatenation. Fedify already provides context helpers such as Context.getActorUri() and Context.getObjectUri() for ordinary ActivityPub IDs. Portable objects need the same kind of ergonomic and consistent API, especially once object dispatchers, inbox delivery, gateway serving, compatible identifiers, and proof generation all need to agree on the same IDs.

This issue is about adding Context-level helpers for constructing FEP-ef61 portable IDs, backed by lower-level DID and portable URI helpers where needed.

Proposed work

Add public helpers for constructing portable actor and object IDs from Fedify context.

The exact API should be decided during implementation, but likely candidates include:

ctx.getPortableActorUri(identifier);
ctx.getPortableObjectUri(Note, {
  userId: "alice",
  noteId: "123",
});

or, if the FEP number should be explicit in the API:

ctx.getEf61ActorUri(identifier);
ctx.getEf61ObjectUri(Note, {
  userId: "alice",
  noteId: "123",
});

The work should include:

  • deciding the public helper names and return types;
  • returning URL objects, consistent with Fedify's existing URI APIs;
  • generating canonical ap+ef61: IDs;
  • accepting or deriving the DID authority used for the portable actor or object;
  • making sure the internal representation remains compatible with JavaScript's URL class even when the canonical serialized form contains an unescaped DID authority;
  • reusing the same URI Template paths as existing actor and object dispatchers where possible;
  • making the helpers usable from ordinary request contexts and from FEP-ef61 gateway request contexts;
  • defining how these helpers relate to Context.getActorUri() and Context.getObjectUri();
  • providing lower-level helpers for converting an Ed25519 public key to a did:key identifier if that is needed for the Context API;
  • using base58-btc did:key identifiers and the correct multicodec prefix for Ed25519 keys;
  • avoiding base64url did:key generation for portable actors;
  • integrating with compatible FEP-ef61 identifier conversion.

These helpers should produce portable IDs only. Conversion to gateway-compatible HTTP(S) identifiers should remain part of the compatible identifier helpers.

Design questions

The implementation should settle these API details before finalizing the code path:

  • Should the public API use Portable names or Ef61 names?
  • Should actor helpers accept an actor identifier, a DID authority, a public key, or some combination of these?
  • Should object helpers require an explicit DID authority outside an FEP-ef61 gateway request?
  • How should the current portable DID authority be exposed inside gateway request contexts?
  • Should helper output serialize as canonical ap+ef61://did:key:.../... when converted to a string, even if the internal URL representation percent-encodes the DID authority?
  • Should low-level did:key generation live in @fedify/vocab-runtime, @fedify/fedify, or both with different API layers?
  • How should these helpers interact with Object Integrity Proof generation so the proof verificationMethod matches the portable ID authority?
  • Should compatible IDs be opt-in at serialization time, or should applications call a separate helper from Compatible FEP-ef61 identifiers for portable objects #833?

Scope

This issue is only about constructing portable actor and object IDs from Fedify APIs.

It does not include:

  • parsing and canonical comparison of arbitrary portable URIs;
  • dereferencing portable objects through gateways;
  • serving portable objects through gateway endpoints;
  • inbox or outbox delivery;
  • WebFinger adaptation;
  • Object Integrity Proof signing itself;
  • automatic actor registration;
  • storage for portable actor keys or DID documents.

Dependencies

This should depend on the lower-level portable URI and compatible identifier work under #288:

It should also inform #835, because object gateway serving should use the same portable object ID construction rules.

Tests

Add regression tests for FEP-ef61 portable ID helpers.

The tests should cover:

  • constructing a portable actor ID with the canonical ap+ef61: scheme;
  • constructing a portable object ID using an existing object dispatcher path;
  • returning URL objects from the public helpers;
  • serializing portable IDs in canonical FEP-ef61 form where required;
  • preserving JavaScript URL compatibility for DID authorities containing reserved characters;
  • deriving a did:key identifier from an Ed25519 public key if that helper is included;
  • using base58-btc and the Ed25519 multicodec prefix for generated did:key identifiers;
  • rejecting or avoiding base64url did:key generation;
  • requiring an explicit DID authority when no gateway/request context provides one;
  • preserving existing Context.getActorUri() and Context.getObjectUri() behavior.

This should be added as a sub-issue of #288.

Metadata

Metadata

Assignees

Priority

High

Effort

Medium

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions