Skip to content

Profile emits bare 'Multikey' type — resolves to <pod>/profile/Multikey instead of cid:Multikey #417

Description

@melvincarvalho

Surfaced after #416 fixed the JSON-LD → Turtle conversion to actually emit nested verificationMethod resources. Now that the VM block IS in the Turtle output, the bug in how the type is authored becomes visible.

Symptom

The on-disk profile (e.g. test.solid.social/profile/card.jsonld) declares the verificationMethod's class as a bare "Multikey" string:

"verificationMethod": [{
  "id": ".../card.jsonld#nostr-key-1",
  "type": "Multikey",
  "controller": ".../card.jsonld#me",
  "publicKeyMultibase": "fe70102de7ec..."
}]

The profile's @context defines verificationMethod, publicKeyMultibase, controller, etc. as terms — but NOT Multikey. So the converter (src/rdf/turtle.js) can't expand "Multikey" to a full IRI; it emits a relative IRI:

<.../card.jsonld#nostr-key-1> a <Multikey>;
    cid:controller <.../card.jsonld#me>;
    cid:publicKeyMultibase "fe70102de7ec...".

Resolution

Per RFC 3986, a Turtle parser with no @base directive uses the document's request URL as the base. <Multikey> relative to https://test.solid.social/profile/card.jsonld resolves to:

https://test.solid.social/profile/Multikey

(verified: new URL('Multikey', 'https://test.solid.social/profile/card.jsonld').href)

Intended IRI: https://www.w3.org/ns/cid/v1#Multikey.

Consequences

  • Type queries miss: VC validators / SPARQL endpoints querying ?s a cid:Multikey will not find this key. The triple is <#nostr-key-1> rdf:type <https://test.solid.social/profile/Multikey> — a fictional class on the pod's own host.
  • Cross-pod inconsistency: the same key on alice.example.com vs bob.example.com would emit different "class" IRIs (alice.example.com/profile/Multikey vs bob.example.com/profile/Multikey) — same key, two classes, no interop.
  • Surface noise: a generic crawler dereferencing the Multikey IRI hits the pod's /profile/Multikey (404, but logged).
  • Spec non-compliance: W3C CID v1 + LWS 1.0 (FPWDs 2026-04-23) require the type be the canonical https://www.w3.org/ns/cid/v1#Multikey. Same gap for JsonWebKey if/when those VMs ship.

Cause

The profile emitter (probably src/webid/profile.js and the seed code in src/handlers/container.js / src/server.js) writes type: "Multikey" as a bare term, expecting context expansion that the context doesn't provide.

Fix options

A. Emit pre-prefixed CURIE in the JSON-LD source:

"type": "cid:Multikey"

Smallest change. Works because the @context already maps cid: https://www.w3.org/ns/cid/v1#. Equally readable to humans.

B. Add Multikey (and JsonWebKey) as terms in the @context:

"@context": {
  ...,
  "Multikey": "cid:Multikey",
  "JsonWebKey": "cid:JsonWebKey"
}

Lets future profile-writers keep using the bare class names. More verbose context.

C. Both — emit CURIE AND map the term, so any consumer (RDF parser via Turtle, JSON-LD processor) sees a clean class IRI regardless of which path it takes.

(A) is the cheapest correct fix. (C) is the most defensive.

Acceptance test

After the fix:

curl -s -H 'Accept: text/turtle' https://test.solid.social/profile/card.jsonld

must contain:

<.../card.jsonld#nostr-key-1> a cid:Multikey;
    ...

— with cid: (or full <https://www.w3.org/ns/cid/v1#Multikey>) — never a bare <Multikey>.

Refs

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingnostrNostr relay, did:nostr auth, NIP-related

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions