Skip to content

Align WebID profile emission with LWS 1.0 (dual-write CID service[]) #320

Description

@melvincarvalho

Part of #319 (LWS 1.0 Auth Suite alignment). Scoped as a small, low-risk first step.

Why

The LWS 1.0 OpenID Connect FPWD specifies that a verifier looks up trust via a service object in the user's Controlled Identifier v1.0 document — specifically an entry with type: https://www.w3.org/ns/lws#OpenIdProvider whose serviceEndpoint matches the token's iss claim.

JSS profiles today expose the same information via the solid:oidcIssuer predicate. That works for existing Solid clients but not for LWS-aware verifiers, which look for the CID service[] shape.

Scope

Emit one CID service[] entry in the generated WebID profile, mirroring the already-present oidcIssuer value. Nothing else moves.

  • lws:OpenIdProvider is the only service type normatively defined in the four LWS10 FPWDs. pim:storage, ldp:inbox, etc. are not yet spec'd under LWS — leaving them alone until the vocabulary stabilizes.
  • verificationMethod[] is explicitly out of scope. Publishing public keys in a user's profile is a security-model change (the profile becomes authoritative for which keys can act for them). Tracking separately.

What changes

src/webid/profile.js — four small additions to generateProfileJsonLd:

  1. Two context namespace entries: cidhttps://www.w3.org/ns/cid/v1#, lwshttps://www.w3.org/ns/lws#.
  2. Two context term aliases: servicecid:service, serviceEndpointcid:serviceEndpoint.
  3. One new field in the output: a service[] array with a single lws:OpenIdProvider entry.
  4. Strip the #me fragment from webId to derive the document URL for the service entry's fragment id.

Nested service entries use the JSON-LD keywords @id and @type directly. CID 1.0's own context URL (https://www.w3.org/ns/cid/v1) provides id/type aliases for authors who prefer the shorter form, but since this profile uses inline term definitions rather than a context URL, we stick with the keywords — they're JSON-LD-native and don't depend on an out-of-band context fetch. A verifier that runs a JSON-LD processor (the expected behaviour for CID-conformant tooling) expands both forms identically.

Shape

Before

{
  "@context": {
    "foaf": "http://xmlns.com/foaf/0.1/",
    "solid": "http://www.w3.org/ns/solid/terms#",
    "schema": "http://schema.org/",
    "pim": "http://www.w3.org/ns/pim/space#",
    "ldp": "http://www.w3.org/ns/ldp#",
    "inbox": { "@id": "ldp:inbox", "@type": "@id" },
    "storage": { "@id": "pim:storage", "@type": "@id" },
    "oidcIssuer": { "@id": "solid:oidcIssuer", "@type": "@id" },
    ...
  },
  "@id": "https://test2.solidweb.app/profile/card.jsonld#me",
  "@type": ["foaf:Person", "schema:Person"],
  "foaf:name": "test2",
  "inbox": "https://test2.solidweb.app/inbox/",
  "storage": "https://test2.solidweb.app/",
  "oidcIssuer": "https://solidweb.app/",
  ...
}

After

{
  "@context": {
    "foaf": "http://xmlns.com/foaf/0.1/",
    "solid": "http://www.w3.org/ns/solid/terms#",
    "schema": "http://schema.org/",
    "pim": "http://www.w3.org/ns/pim/space#",
    "ldp": "http://www.w3.org/ns/ldp#",
    "cid": "https://www.w3.org/ns/cid/v1#",
    "lws": "https://www.w3.org/ns/lws#",
    "inbox": { "@id": "ldp:inbox", "@type": "@id" },
    "storage": { "@id": "pim:storage", "@type": "@id" },
    "oidcIssuer": { "@id": "solid:oidcIssuer", "@type": "@id" },
    "service": { "@id": "cid:service", "@container": "@set" },
    "serviceEndpoint": { "@id": "cid:serviceEndpoint", "@type": "@id" },
    ...
  },
  "@id": "https://test2.solidweb.app/profile/card.jsonld#me",
  "@type": ["foaf:Person", "schema:Person"],
  "foaf:name": "test2",
  "inbox": "https://test2.solidweb.app/inbox/",
  "storage": "https://test2.solidweb.app/",
  "oidcIssuer": "https://solidweb.app/",
  "service": [
    {
      "@id": "https://test2.solidweb.app/profile/card.jsonld#oidc",
      "@type": "lws:OpenIdProvider",
      "serviceEndpoint": "https://solidweb.app/"
    }
  ],
  ...
}

Properties

  • Zero removals. Every existing WebID predicate stays as-is, so Mashlib, solid-client-authn, rdflib.js etc. keep seeing the profile they see today.
  • Additive ~200 bytes on the wire per profile.
  • Fragment id (#oidc) resolves against the document URL — idiomatic JSON-LD and matches CID examples.
  • Existing pods are unaffected unless regenerated; new pods get the new shape on first creation.

Ship-it criteria

  • src/webid/profile.js emits the CID service[] entry.
  • New test in test/webid.test.js asserts the entry is present with the correct @type and serviceEndpoint mirroring oidcIssuer.
  • Full suite still green.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions