Change proposal: Update Smart Trust DID trustlist to JSON‑LD v2 hybrid {code} objects for coded fields
Summary
This change updates the Smart Trust DID trustlist document (did.json) so that the coded fields:
domain
participant
keyusage
are represented as compact objects:
instead of plain strings. A new JSON‑LD context version (tng-additional-context/v2) is introduced so that these compact tokens deterministically expand to globally unique IRIs in the correct CodeSystem namespaces.
This is a breaking representation change.
Motivation / justification
Why change the instance representation?
Coded fields currently appear as bare strings:
Bare strings are compact, but they are not self-describing in JSON. Their meaning depends entirely on external knowledge of which code system applies.
By switching to an object form:
"domain": { "code": "PH4H" }
we gain:
- an explicit, uniform “coded value” structure that can be validated consistently,
- a clearer boundary between a code token and other string fields,
- room for future extension (e.g., optional
display) without changing the overall pattern.
Why change the JSON‑LD preamble/context?
Once the fields become objects, the existing JSON‑LD context must be updated so that:
domain.code, participant.code, keyusage.code are interpreted as identifiers (IRIs), not string literals
- each field expands using the correct CodeSystem namespace
Without updating the context, JSON‑LD expansion would not produce the desired CodeSystem IRIs, and the compact tokens would not resolve semantically.
CodeSystem namespaces (authoritative meaning)
The following CodeSystem namespaces are used to interpret each code token (expanded with #<code>):
- Domains:
http://smart.who.int/trust/CodeSystem/Domains
- Key usage:
http://smart.who.int/trust/CodeSystem/KeyUsage
- Participants:
http://smart.who.int/trust/CodeSystem/Participants
Expected expansions:
domain.code = "PH4H" → http://smart.who.int/trust/CodeSystem/Domains#PH4H
keyusage.code = "DSC" → http://smart.who.int/trust/CodeSystem/KeyUsage#DSC
participant.code = "CHL" → http://smart.who.int/trust/CodeSystem/Participants#CHL
Proposed DID (did.json) changes
1) Change the context list to reference the new v2 context
Before:
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/jws-2020/v1",
"https://worldhealthorganization.github.io/smart-trust/tng-additional-context/v1"
]
After:
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/jws-2020/v1",
"https://worldhealthorganization.github.io/smart-trust/tng-additional-context/v2"
]
2) Update each verificationMethod entry to use { "code": ... } objects
Before (excerpt from verificationMethod[]):
{
"id": "did:web:tng-cdn-dev.who.int:v2:trustlist:PH4H:CHL:DSC#+kGpHsnSCAg=",
"type": "JsonWebKey2020",
"controller": "did:web:tng-cdn-dev.who.int:v2:trustlist",
"publicKeyJwk": {
"kty": "EC",
"kid": "+kGpHsnSCAg="
},
"domain": "PH4H",
"participant": "CHL",
"keyusage": "DSC"
}
After:
{
"id": "did:web:tng-cdn-dev.who.int:v2:trustlist:PH4H:CHL:DSC#+kGpHsnSCAg=",
"type": "JsonWebKey2020",
"controller": "did:web:tng-cdn-dev.who.int:v2:trustlist",
"publicKeyJwk": {
"kty": "EC",
"kid": "+kGpHsnSCAg="
},
"domain": { "code": "PH4H" },
"participant": { "code": "CHL" },
"keyusage": { "code": "DSC" }
}
Proposed JSON‑LD context changes (tng-additional-context/v2)
The v2 context must ensure:
domain, participant, keyusage are treated as objects with scoped rules
code is treated as an IRI (@type: "@id")
- code tokens expand using the correct CodeSystem base via scoped
@vocab
v2 context (illustrative)
{
"@context": {
"@version": 1.1,
"@protected": true,
"domain": {
"@context": {
"@protected": true,
"@vocab": "http://smart.who.int/trust/CodeSystem/Domains#",
"code": { "@type": "@id" }
}
},
"participant": {
"@context": {
"@protected": true,
"@vocab": "http://smart.who.int/trust/CodeSystem/Participants#",
"code": { "@type": "@id" }
}
},
"keyusage": {
"@context": {
"@protected": true,
"@vocab": "http://smart.who.int/trust/CodeSystem/KeyUsage#",
"code": { "@type": "@id" }
}
}
}
}
Why scoped @vocab is used
To keep instances compact, we want code values to be short tokens ("PH4H", "CHL", "DSC"). JSON‑LD needs a rule to expand those tokens into IRIs. The scoped @vocab provides that rule per field, so each coded field expands into the correct CodeSystem namespace.
Resulting behavior (sanity check)
With the new did.json + tng-additional-context/v2:
domain: { code: "PH4H" } expands to http://smart.who.int/trust/CodeSystem/Domains#PH4H
participant: { code: "CHL" } expands to http://smart.who.int/trust/CodeSystem/Participants#CHL
keyusage: { code: "DSC" } expands to http://smart.who.int/trust/CodeSystem/KeyUsage#DSC
Scope / impact
Implementation checklist
- Publish
https://worldhealthorganization.github.io/smart-trust/tng-additional-context/v2 implementing the scoped-context pattern above.
- Update the trustlist generator to emit
{ "code": "<token>" } for:
domain
participant
keyusage
- Update documentation and examples that show trustlist contents.
- Validate expansion output against expected CodeSystem IRIs.
Change proposal: Update Smart Trust DID trustlist to JSON‑LD v2 hybrid
{code}objects for coded fieldsSummary
This change updates the Smart Trust DID trustlist document (
did.json) so that the coded fields:domainparticipantkeyusageare represented as compact objects:
{ "code": "<token>" }instead of plain strings. A new JSON‑LD context version (
tng-additional-context/v2) is introduced so that these compact tokens deterministically expand to globally unique IRIs in the correct CodeSystem namespaces.This is a breaking representation change.
Motivation / justification
Why change the instance representation?
Coded fields currently appear as bare strings:
Bare strings are compact, but they are not self-describing in JSON. Their meaning depends entirely on external knowledge of which code system applies.
By switching to an object form:
we gain:
display) without changing the overall pattern.Why change the JSON‑LD preamble/context?
Once the fields become objects, the existing JSON‑LD context must be updated so that:
domain.code,participant.code,keyusage.codeare interpreted as identifiers (IRIs), not string literalsWithout updating the context, JSON‑LD expansion would not produce the desired CodeSystem IRIs, and the compact tokens would not resolve semantically.
CodeSystem namespaces (authoritative meaning)
The following CodeSystem namespaces are used to interpret each code token (expanded with
#<code>):http://smart.who.int/trust/CodeSystem/Domainshttp://smart.who.int/trust/CodeSystem/KeyUsagehttp://smart.who.int/trust/CodeSystem/ParticipantsExpected expansions:
domain.code = "PH4H"→http://smart.who.int/trust/CodeSystem/Domains#PH4Hkeyusage.code = "DSC"→http://smart.who.int/trust/CodeSystem/KeyUsage#DSCparticipant.code = "CHL"→http://smart.who.int/trust/CodeSystem/Participants#CHLProposed DID (
did.json) changes1) Change the context list to reference the new v2 context
Before:
After:
2) Update each
verificationMethodentry to use{ "code": ... }objectsBefore (excerpt from
verificationMethod[]):{ "id": "did:web:tng-cdn-dev.who.int:v2:trustlist:PH4H:CHL:DSC#+kGpHsnSCAg=", "type": "JsonWebKey2020", "controller": "did:web:tng-cdn-dev.who.int:v2:trustlist", "publicKeyJwk": { "kty": "EC", "kid": "+kGpHsnSCAg=" }, "domain": "PH4H", "participant": "CHL", "keyusage": "DSC" }After:
{ "id": "did:web:tng-cdn-dev.who.int:v2:trustlist:PH4H:CHL:DSC#+kGpHsnSCAg=", "type": "JsonWebKey2020", "controller": "did:web:tng-cdn-dev.who.int:v2:trustlist", "publicKeyJwk": { "kty": "EC", "kid": "+kGpHsnSCAg=" }, "domain": { "code": "PH4H" }, "participant": { "code": "CHL" }, "keyusage": { "code": "DSC" } }Proposed JSON‑LD context changes (
tng-additional-context/v2)The v2 context must ensure:
domain,participant,keyusageare treated as objects with scoped rulescodeis treated as an IRI (@type: "@id")@vocabv2 context (illustrative)
{ "@context": { "@version": 1.1, "@protected": true, "domain": { "@context": { "@protected": true, "@vocab": "http://smart.who.int/trust/CodeSystem/Domains#", "code": { "@type": "@id" } } }, "participant": { "@context": { "@protected": true, "@vocab": "http://smart.who.int/trust/CodeSystem/Participants#", "code": { "@type": "@id" } } }, "keyusage": { "@context": { "@protected": true, "@vocab": "http://smart.who.int/trust/CodeSystem/KeyUsage#", "code": { "@type": "@id" } } } } }Why scoped
@vocabis usedTo keep instances compact, we want
codevalues to be short tokens ("PH4H","CHL","DSC"). JSON‑LD needs a rule to expand those tokens into IRIs. The scoped@vocabprovides that rule per field, so each coded field expands into the correct CodeSystem namespace.Resulting behavior (sanity check)
With the new
did.json+tng-additional-context/v2:domain: { code: "PH4H" }expands tohttp://smart.who.int/trust/CodeSystem/Domains#PH4Hparticipant: { code: "CHL" }expands tohttp://smart.who.int/trust/CodeSystem/Participants#CHLkeyusage: { code: "DSC" }expands tohttp://smart.who.int/trust/CodeSystem/KeyUsage#DSCScope / impact
This change affects both:
domain,participant,keyusage)Backward compatibility is not a requirement.
Implementation checklist
https://worldhealthorganization.github.io/smart-trust/tng-additional-context/v2implementing the scoped-context pattern above.{ "code": "<token>" }for:domainparticipantkeyusage