profile: emit CID v1 controller + prep verificationMethod context (#386 Phase A)#388
Conversation
…, #386 Phase A) Smallest delta toward LWS-CID conformance for new pod profiles. New pods now declare themselves as W3C Controlled Identifier documents so a future Phase B "add-keys" app (a standalone tool that PATCHes the profile after authentication) can drop verificationMethod entries in without rewriting the @context. Two changes in src/webid/profile.js: 1. Add `controller: <webId>` triple to every new profile. Per CID v1 self-control: the WebID is its own controller. The triple itself is meaningful even with no keys yet. 2. Extend the @context with the six CID v1 terms a key-emitting profile will need (controller, verificationMethod, authentication, assertionMethod, publicKeyJwk, publicKeyMultibase). Declared inline (rather than via the cid/v1 imported-context URL) because JSS's JSON-LD → Turtle conneg layer can't resolve external context URLs; the IRIs each term expands to are identical either way. Explicitly out of scope for Phase A: - No verificationMethod data (the standalone Phase B app populates these per-key) - No migration of existing pods (they keep their current profiles until a user opts in via Phase B) - No verifier-side changes (#386 Phase 3, separate) - No new dependencies Tests: two new assertions in test/webid.test.js — `controller` is defined in @context and expands to the CID v1 namespace, and controller === @id at the data layer. Existing profile / Turtle conneg / OIDC discovery / Solid client tests continue to pass. 619/619 tests pass.
There was a problem hiding this comment.
Pull request overview
This PR updates newly generated WebID profiles to be structurally compatible with W3C Controlled Identifiers (CID) v1 (as part of LWS/CID alignment), by emitting a self-controller statement and pre-declaring CID terms in the JSON-LD @context to support later key material PATCHing.
Changes:
- Extend WebID profile
@contextwith six CID v1 terms needed for Phase B key injection (controller,verificationMethod,authentication,assertionMethod,publicKeyJwk,publicKeyMultibase). - Emit
controller: <webId>in new pod profiles to declare CID “self-control”. - Add tests asserting the new
controllertriple and presence of CID terms in@context.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/webid/profile.js | Adds CID v1 term mappings to @context and emits controller on generated profiles. |
| test/webid.test.js | Adds assertions for CID term declarations and controller === @id on the profile. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 'verificationMethod': { '@id': 'cid:verificationMethod', '@type': '@id' }, | ||
| 'authentication': { '@id': 'cid:authentication', '@type': '@id' }, | ||
| 'assertionMethod': { '@id': 'cid:assertionMethod', '@type': '@id' }, |
There was a problem hiding this comment.
Fixed in 5c9ba93: dropped `@type:'@id'` from `verificationMethod` (its values are inline objects, not IRI references) and added `@container:'@set'` to all three of verificationMethod / authentication / assertionMethod for proper array semantics. authentication and assertionMethod keep `@type:'@id'` since their values are IRI references back into verificationMethod.
| 'verificationMethod': { '@id': 'cid:verificationMethod', '@type': '@id' }, | ||
| 'authentication': { '@id': 'cid:authentication', '@type': '@id' }, | ||
| 'assertionMethod': { '@id': 'cid:assertionMethod', '@type': '@id' }, | ||
| 'publicKeyJwk': { '@id': 'cid:publicKeyJwk' }, |
There was a problem hiding this comment.
Real concern, fixed in 5c9ba93: `publicKeyJwk` now declares `@type:'@JSON'` per JSON-LD 1.1 §4.2.2. The JWK becomes an rdf:JSON literal — the spec-correct shape.\n\nThe matching turtle.js work (extending `valueToTerm` to emit @type:@JSON literals) is filed as #390 — separate from this PR's scope, but a real Phase B blocker. Declaring the context entry here is forward-looking and spec-correct; #390 is the remaining server-side glue.
| // Both 'controller' and 'verificationMethod' must expand to the | ||
| // CID v1 namespace. Inline form: '@id': 'cid:controller' or | ||
| // '@id': 'https://www.w3.org/ns/cid/v1#controller'. | ||
| const controllerMapping = ctx.controller; | ||
| assert.ok(controllerMapping, '@context must define `controller`'); | ||
| const id = typeof controllerMapping === 'string' ? controllerMapping : controllerMapping['@id']; | ||
| assert.match(id, /^(cid:controller|https:\/\/www\.w3\.org\/ns\/cid\/v1#controller)$/, | ||
| 'controller must map to the CID v1 namespace'); | ||
| assert.ok(ctx.verificationMethod, '@context must define `verificationMethod` for Phase B'); | ||
| assert.ok(ctx.authentication, '@context must define `authentication` for Phase B'); |
There was a problem hiding this comment.
Fixed in 5c9ba93: test now iterates all six CID terms (controller, verificationMethod, authentication, assertionMethod, publicKeyJwk, publicKeyMultibase) and asserts each maps to the CID v1 namespace. Also strengthened to verify the per-term `@container` / `@type` flags Phase B relies on — namely that verificationMethod is NOT @type:@id but IS @container:@set, that authentication/assertionMethod are @type:@id, and that publicKeyJwk is @type:@JSON.
…Phase B Three fixes per the review: 1. verificationMethod no longer marked @type:@id. Its values are inline verification method objects (id/type/controller/public-key…), not IRI references, so @type:@id was semantically wrong. Added @container:@set so a single-entry list is still an array. 2. authentication / assertionMethod KEEP @type:@id (they reference verificationMethod entries by IRI) but get @container:@set added too for proper array semantics. 3. publicKeyJwk now declares @type:@JSON. JWK is a literal JSON object (rdf:JSON datatype per JSON-LD 1.1). JSS's Turtle conneg layer doesn't yet emit @type:@JSON literals — filed #390 as a separate Phase B blocker. Declaring it here is the spec-correct shape. Test strengthened to cover all six CID terms mapping to the CID v1 namespace, plus the container/type flags Phase B will rely on: - verificationMethod NOT @type:@id, has @container:@set - authentication / assertionMethod have @type:@id - publicKeyJwk has @type:@JSON 17/17 webid tests pass (control: full Turtle conneg #320 still green).
JSS pod profiles became structurally W3C Controlled Identifier documents in 0.0.174 (#388, Phase A of #386). Capture that honestly in two places: 1. README — one-line bullet under Features pointing at the new doc and the W3C specs. 2. docs/lws.md — skeleton page with the three-level compatibility model (profile shape ✅ / keys ❌ / verifier ❌), what Phase A actually does (with a sample profile JSON-LD), what Phase B (the standalone "doctor / add-keys" app) will add, what Phase 3 (the server-side LWS-CID JWT verifier) will add, and spec references. Companion docs-site page (Docusaurus at jss.live/docs/features/lws) will land in a separate PR against the docs repo.
) Phase A doc was framed around things forthcoming. Reality moved: - Phase B (profile carries keys) shipped via doctor B.2 + B.3 - Phase 3 (LWS-CID JWT verifier) shipped in v0.0.177 via #398 - Bonus path: NIP-98 → WebID via VM lookup shipped in v0.0.178 (#400) Updated the compatibility table to ✅ everywhere, retitled the "What X will add" sections to describe what's deployed, added a new section for the NIP-98 upgrade, refreshed the related-links list with the doctor repo and the post-#388 PRs. Closes #401 (JSS half — companion docs-repo PR follows).
Closes #387. First phase of #386.
Summary
controller: <webId>per W3C CID v1's self-control contract.@contextextended with the six CID v1 terms (controller,verificationMethod,authentication,assertionMethod,publicKeyJwk,publicKeyMultibase) so a standalone Phase B "add-keys" app can PATCH inverificationMethodentries without touching the context.https://www.w3.org/ns/cid/v1imported-context URL, because JSS's JSON-LD → Turtle conneg layer can't resolve external context URLs (caught by the#320Turtle conformance test). The IRIs each term expands to are identical either way.Out of scope (deferred)
verificationMethoddata emitted yet — Phase B (a separate standalone app) populates per-user keys via PATCH after the user authenticates.Files
src/webid/profile.js— +21 lines (addcontrollertriple + 6 CID v1 context entries)test/webid.test.js— +24 lines (two new assertions: context defines CID terms;controller === @id)Verification
npm test)controllerpredicate, when emitted alongside the existingoidcIssuer/storage/inboxpredicates, expands correctly through the JSON-LD → Turtle pathTest plan
curl -H 'Accept: application/ld+json' <pod>/profile/card.jsonldshowscontrollerfield equal to the WebIDcurlwithAccept: text/turtleshows thecid:controllerpredicate (or expanded full URI form)https://melvin.solid.social/profile/card.jsonld) are unchanged — only NEW pod creation triggers the new shapeRefs