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:
- Two context namespace entries:
cid → https://www.w3.org/ns/cid/v1#, lws → https://www.w3.org/ns/lws#.
- Two context term aliases:
service → cid:service, serviceEndpoint → cid:serviceEndpoint.
- One new field in the output: a
service[] array with a single lws:OpenIdProvider entry.
- 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
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#OpenIdProviderwhoseserviceEndpointmatches the token'sissclaim.JSS profiles today expose the same information via the
solid:oidcIssuerpredicate. That works for existing Solid clients but not for LWS-aware verifiers, which look for the CIDservice[]shape.Scope
Emit one CID
service[]entry in the generated WebID profile, mirroring the already-presentoidcIssuervalue. Nothing else moves.lws:OpenIdProvideris the only servicetypenormatively 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 togenerateProfileJsonLd:cid→https://www.w3.org/ns/cid/v1#,lws→https://www.w3.org/ns/lws#.service→cid:service,serviceEndpoint→cid:serviceEndpoint.service[]array with a singlelws:OpenIdProviderentry.#mefragment fromwebIdto derive the document URL for the service entry's fragment id.Nested service entries use the JSON-LD keywords
@idand@typedirectly. CID 1.0's own context URL (https://www.w3.org/ns/cid/v1) providesid/typealiases 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
After
Properties
#oidc) resolves against the document URL — idiomatic JSON-LD and matches CID examples.Ship-it criteria
src/webid/profile.jsemits the CIDservice[]entry.test/webid.test.jsasserts the entry is present with the correct@typeandserviceEndpointmirroringoidcIssuer.