├── .github └── workflows │ ├── auto-publish.yml │ └── codeql-analysis.yml ├── .gitignore ├── .pr-preview.json ├── CGFR └── 2023-04-05 │ ├── index.bs │ └── index.html ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CR └── 2023-11-21 │ └── Overview.html ├── EXPLAINER.md ├── FPWD └── 2023-05-23 │ └── index.html ├── LICENSE.md ├── README.md ├── common.js ├── example └── yaml-json-schema.yaml ├── index.html ├── schema └── json-schema-credential-schema.json ├── terms.html └── w3c.json /.github/workflows/auto-publish.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | pull_request: {} 4 | push: 5 | branches: [main] 6 | jobs: 7 | main: 8 | name: Build, Validate, and Deploy 9 | runs-on: ubuntu-20.04 10 | steps: 11 | - uses: actions/checkout@v3 12 | - uses: w3c/spec-prod@v2 13 | with: 14 | TOOLCHAIN: respec 15 | W3C_ECHIDNA_TOKEN: ${{ secrets.W3C_TR_TOKEN }} 16 | W3C_WG_DECISION_URL: https://www.w3.org/2017/vc/WG/Meetings/Minutes/2023-04-12-vcwg#resolution1 17 | W3C_BUILD_OVERRIDE: | 18 | shortName: vc-json-schema 19 | specStatus: CRD 20 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ "master" ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ "master" ] 20 | schedule: 21 | - cron: '26 8 * * 6' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'javascript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v3 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v2 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | 52 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 53 | # queries: security-extended,security-and-quality 54 | 55 | 56 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 57 | # If this step fails, then you should remove it and run the build manually (see below) 58 | - name: Autobuild 59 | uses: github/codeql-action/autobuild@v2 60 | 61 | # ℹ️ Command-line programs to run using the OS shell. 62 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 63 | 64 | # If the Autobuild fails above, remove it and uncomment the following three lines. 65 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. 66 | 67 | # - run: | 68 | # echo "Run, Build Application using script" 69 | # ./location_of_script_within_repo/buildscript.sh 70 | 71 | - name: Perform CodeQL Analysis 72 | uses: github/codeql-action/analyze@v2 73 | with: 74 | category: "/language:${{matrix.language}}" 75 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sw[nop] 2 | *~ 3 | .DS_Store 4 | .idea/modules.xml 5 | .idea/vc-data-model.iml 6 | .idea/vcs.xml 7 | .idea/workspace.xml 8 | .vscode 9 | .idea 10 | .gitignore 11 | 12 | **/node_modules 13 | **/.DS_Store 14 | **/.vscode 15 | **/package-lock.json 16 | 17 | out.html -------------------------------------------------------------------------------- /.pr-preview.json: -------------------------------------------------------------------------------- 1 | { 2 | "src_file": "index.html", 3 | "type": "respec" 4 | } -------------------------------------------------------------------------------- /CGFR/2023-04-05/index.bs: -------------------------------------------------------------------------------- 1 | 2 |
4 | Title: Verifiable Credentials JSON Schema Specification 5 | Status: w3c/CG-FINAL 6 | Prepare for TR: true 7 | TR: https://w3c-ccg.github.io/vc-json-schema/ 8 | ED: https://w3c-ccg.github.io/vc-json-schema/ 9 | !CG-FINAL: https://w3c-ccg.github.io/vc-json-schema/ 10 | 11 | Shortname: vcjsonschemaspec 12 | Level: 1 13 | 14 | Editor: [Gabe Cohen](https://linkedin.com/in/cohengabe), w3cid 116851, [Block](https://www.block.xyz) 15 | Editor: Orie Steele, w3cid 109171, [Transmute](https://www.transmute.industries/), orie@transmute.industries 16 | 17 | group: ccg 18 | Issue Tracking: GitHub https://github.com/w3c-ccg/vc-json-schema/issues 19 | !Tests: vc json schema spec tests (ongoing work) 20 | Text Macro: FALSE42 | 43 | 89 | 90 | # Introduction # {#intro} 91 | This specification provides a mechanism for the use of [=JSON Schemas=] with [=Verifiable Credentials=]. A significant part of the integrity of a [=Verifiable Credential=] comes from the ability to structure its contents so that all three parties — issuer, holder, verifier — may have a consistent mechanism of trust in interpreting the data that they are provided with. We introducing a new data model for an object to facilitate backing Credentials with [=JSON Schemas=] that we call a [=Credential Schema=]. 92 | 93 | This specification provides a standardized way of creating [=Credential Schemas=] to be used in credentialing platforms, how to version them, and how to read them. Credential Schemas may apply to any portion of a Verifiable Credential. Multiple JSON Schemas may back a single Verifiable Credential, e.g. a schema for the `credentialSubject` and another for other credential properties. 94 | 95 | ## Conformance ## {#conformance} 96 | 97 | As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative. 98 | 99 | The key words MAY, MUST, MUST NOT, RECOMMENDED, and SHOULD in this document are to be interpreted as described in BCP 14 [[RFC2119]] [[RFC8174]] when, and only when, they appear in all capitals, as shown here. 100 | 101 | # Terminology # {#terminology} 102 | 103 | : id 104 | :: A locally unique identifier to address the schema. 105 | 106 | : credential schema 107 | :: The data template for a credential. Refers to the entirety of a [=Credential Schema=], including both [=Metadata=] and [=JSON Schema=] properties. The term may refer to a document either with, or without a [=proof=]. 108 | 109 | : CredentialSchema2022 110 | :: The type of the `credentialSchema` property to be used when utilizing this specification. 111 | 112 |false
21 | Text Macro: PII personally identifying information 22 | Text Macro: RP Relying Party 23 | Text Macro: RPS Relying Parties 24 | Text Macro: INFORMATIVE This section is not normative. 25 | Text Macro: TRUEtrue
26 | Ignored Vars: op, alg, type, algorithm 27 | 28 | Abstract: Among other things, the [[VC-DATA-MODEL]] specifies the models used for Verifiable Credentials, 29 | Verifiable Presentations, and explains the relationships between three parties: 30 | issuers, holders, and verifiers. Critical pieces of functionality referenced 31 | throughout the [[VC-DATA-MODEL]] are the that of of verifiability, extensibility, and semantic 32 | interoperability. This specification provides a mechanism to make use of a Credential Schema in 33 | [=Verifiable Credential=], leveraging the existing 34 | Data Schemas concept. 35 | 36 | Status Text: This specification was published by the W3C Credentials Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Final Specification Agreement (FSA) other conditions apply. Learn more about W3C Community and Business Groups. If you wish to make comments regarding this document, please send them to public-credentials@w3.org (subscribe, archives). 37 | 38 | 39 | Boilerplate: omit conformance, omit feedback-header, omit abstract-header, omit logo 40 | Markup Shorthands: css off, markdown on 41 |
113 | { 114 | "type": "https://w3c-ccg.github.io/vc-json-schema/schema/2.0/schema.json", 115 | "version": "1.0", 116 | "id": "did:example:MDP8AsFhHzhwUvGNuYkX7T/06e126d1-fa44-4882-a243-1e326fbe21db?version=1.0", 117 | "name": "Email", 118 | "author": "did:example:MDP8AsFhHzhwUvGNuYkX7T", 119 | "authored": "2022-05-05T00:00:00+00:00", 120 | "schema": { 121 | "$id": "email-schema-1.0", 122 | "$schema": "https://json-schema.org/draft/2019-09/schema", 123 | "description": "Email", 124 | "type": "object", 125 | "properties": { 126 | "emailAddress": { 127 | "type": "string", 128 | "format": "email" 129 | } 130 | }, 131 | "required": ["emailAddress"], 132 | "additionalProperties": false 133 | } 134 | } 135 |136 | 137 | 138 | : metadata 139 | :: Top-level information on a [=Credential Schema=]. Pieces of data wrapping the [=JSON Schema=] to provide further context about the schema. 140 | 141 |
142 | { 143 | "type": "https://w3c-ccg.github.io/vc-json-schema/", 144 | "version": "1.0", 145 | "id": "did:example:MDP8AsFhHzhwUvGNuYkX7T/06e126d1-fa44-4882-a243-1e326fbe21db", 146 | "name": "Email", 147 | "author": "did:example:MDP8AsFhHzhwUvGNuYkX7T", 148 | "authored": "2021-01-01T00:00:00+00:00" 149 | } 150 |151 | 152 | : proof 153 | :: A digital signature over the [=Credential Schema=] for the sake of asserting authorship. A piece of [=Metadata=]. Accomplished using either [[DATA-INTEGRITY]] or [[JOSE]]. 154 | 155 | : type 156 | :: It is important in software systems for machines to understand the context of what a document is. In credential schemas this is declared in the type field. This field resolves to a JSON schema with details about the schema metadata that applies to the schema. A piece of [=Metadata=]. 157 | 158 | : version 159 | :: Denotes the revision of a given Credential Schema. 160 | 161 | : name 162 | :: A human-readable name for the schema. A piece of [=Metadata=]. 163 | 164 | : author 165 | :: [=DID=] of the identity which authored the credential schema. A piece of [=Metadata=]. 166 | 167 | : authored 168 | :: [[RFC3339]] date on which the schema was created. A piece of [=Metadata=]. 169 | 170 | : json schema 171 | :: [=schema=] 172 | 173 | : schema 174 | :: This is where the Credential Schema data fields are defined as a valid [[JSON-SCHEMA]]. A piece of [=Metadata=]. 175 | 176 |
177 | { 178 | "$id": "email-schema-1.0", 179 | "$schema": "https://json-schema.org/draft/2020-12/schema", 180 | "description": "Email", 181 | "type": "object", 182 | "properties": { 183 | "credentialSubject": { 184 | "type": "object", 185 | "properties": { 186 | "emailAddress": { 187 | "type": "string", 188 | "format": "email" 189 | }, 190 | "required": [ 191 | "emailAddress" 192 | ], 193 | "additionalProperties": false 194 | } 195 | } 196 | } 197 | } 198 |199 | 200 | : credential 201 | :: [=Verifiable Credential=] 202 | 203 | : verifiable credential 204 | :: See [[VC-DATA-MODEL]] 205 | 206 | : DID 207 | :: See [[DID-CORE]] 208 | 209 | : data integrity 210 | :: A methodology for ensuring the authenticity and integrity of digital documents which makes use of [[JSON-LD]]. See [[DATA-INTEGRITY]]. 211 | 212 | : presentation 213 | :: Presentation is a mechanism used to share one or more credentials with a given party. 214 | 215 | # Formatting # {#formatting} 216 | 217 | The [[VC-DATA-MODEL]] uses the JSON Linked Data interchange format. The specification allows for other formats, such as standard JSON with JSON Schema but provides limited examples. In the [Data Schemas section](https://www.w3.org/TR/vc-data-model/#data-schemas), JSON-SCHEMA-2018 validation is noted explicitly. This specification does not require the use of [[JSON-LD]], though some may prefer to utilize [=Data Integrity=] Proofs which this specification supports. If it becomes evident that it would be useful to include [[JSON-LD]] or another format that decision would be made in a revisal draft at a later date. 218 | 219 | The Verifiable Credentials data model relies heavily upon standard JSON with validation provided by [[JSON-SCHEMA]]. The data model embeds [[JSON-SCHEMA]] documents inside a larger document that contains useful metadata about a given credential schema. 220 | 221 | # Concepts # {#concepts} 222 | 223 | ## Verifiable Credentials Data Model ## {#verifiable_credentials_data_model} 224 | 225 | The Credential Schema is a document that is used to guarantee the structure, and by extension the semantics, of the set of claims comprising a Verifiable Credential. A shared Credential Schema allows all parties to reference data in a known way. 226 | 227 | A schema can be viewed from four perspectives: the author, issuer, verifier and holder. 228 | 229 | Author: An author creates a schema as to provide a blueprint for a [=Verifiable Credential=], specifying the shape and format of the data in such a credential. 230 | 231 | Issuer: Issuers utilize schemas to provide structure and meaning to the data they issue as [=Verifiable Credentials=]. By using schemas, issuers contribute to a credentialing ecosystem that promotes the usage and adoption of data standards. 232 | 233 | Verifier: Verifiers processes a [=Verifiable Credentials=] and need to do so with knowledge of the terms and data the compromise the credentials. [=Credential Schemas=] aid a verifier in both requesting and processing credentials that have been produced in a well-known format. 234 | 235 | Holder: Holders, or those who are the subject of credential issuance, can make sense of the data they control by evaluating it against a data schema. When data is requested from a holder which references a [=Credential Schema=] the holder has the capability to to present the data specifically requested by the verifier. 236 | 237 | ## Guarantees ## {#guarantees} 238 | 239 | With adherence to the specification, the following guarantees can be made about a schema: 240 | 241 | - A schema is versionable and it can evolve via new versions over time. 242 | - A schema is available for any issuer to use in a Credential and any holder or verifier of that Credential read. 243 | - A schema always guarantees the structure of a credential. A schema can apply to all or specific parts of a credential. 244 | 245 | ## Storage ## {#storage} 246 | 247 | [=Credential Schemas=] intended to be created and made available as immutable objects. They may be stored on any number of storage mediums such as a distributed ledger, traditional database, or decentralized file storage. The same schema may be replicated across multiple file stores with the same identifier. Immutability is key to enable consistent sources of truth for usage with Verifiable Credentials which are also immutable. Credential Schemas can evolve by creating new [versions](#versioning). 248 | 249 | ## Versioning ## {#versioning} 250 | 251 | Credentials Schemas are versioned via a [=version=] property. The [=version=] denotes the revision of a particular schema for a given storage medium. 252 | 253 | [=Authors=] and Issuers have an interest in versioning to track advancements and changes over time both for formatting changes (e.g. supporting [[JSON-SCHEMA]] [draft-bhutton-json-schema-00](https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00) as opposed to [Draft 7](https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-01)) as well as field-level changes (e.g. adding a new required field) as a schema evolves over time. Holders have an interest in versioning to gain an understanding in where their credentials can be used as they may receive requests for [=presentation=] filtering by schema ID. Similarly, Verifiers have an interest in versioning to know which data, or schema versions they should accept and known how to process in their systems. 254 | 255 | Guidelines for versioning can be found in the [Versioning Guidelines section of this document](#versioning_guidelines). 256 | 257 | # Data Model # {#data_model} 258 | 259 | ## Credential Schema ## {#credential_schema} 260 | 261 | This section provides the [[JSON-SCHEMA]] definition for [=Credential Schema=] along with an example of a [=Credential Schema=] for an Email [=Verifiable Credential=]. 262 | 263 | The JSON Schema definition for a Credential Schema below makes use of [JSON Schema Draft 2020-12](https://json-schema.org/draft/2020-12/json-schema-core.html). 264 | 265 | JSON Schema 266 |
267 | { 268 | "$id": "credential-schema-2.0", 269 | "$schema": "https://json-schema.org/draft/2020-12/schema", 270 | "description": "JSON Schema for W3C Verifiable Credential JSON Schema", 271 | "type": "object", 272 | "properties": { 273 | "type": { 274 | "type": "string" 275 | }, 276 | "version": { 277 | "type": "string", 278 | "pattern": "^\\d+\\.\\d+$" 279 | }, 280 | "id": { 281 | "type": "string" 282 | }, 283 | "name": { 284 | "type": "string" 285 | }, 286 | "author": { 287 | "type": "string" 288 | }, 289 | "authored": { 290 | "type": "string" 291 | }, 292 | "schema": { 293 | "$ref": "https://json-schema.org/draft/2020-12/schema" 294 | }, 295 | "proof": { 296 | "type": "object" 297 | } 298 | }, 299 | "required": [ 300 | "type", 301 | "version", 302 | "id", 303 | "name", 304 | "author", 305 | "authored", 306 | "schema" 307 | ] 308 | } 309 |310 | 311 | ## Metadata ## {#credential_schema_metadata} 312 | 313 | The properties, in order, before the JSON Schema document, embedded into the [=JSON Schema=] are as follows: 314 | 315 | 1. [=type=] 316 | 317 | Credential Schema Metadata MUST provide a `type` property. 318 | 319 | The value of the `type` property MUST point to a URI specifying the draft of this specification to use. The current draft URI is https://w3c-ccg.github.io/vc-json-schema/. 320 | 321 | 2. [=version=] 322 | 323 | Credential Schema Metadata MUST provide a `version` property. 324 | 325 | The value of the `version` property MUST point to a semantic version of a given credential schema; follows the [versioning guidelines](#versioning_guidelines). 326 | 327 | 3. [=id=] 328 | 329 | Credential Schema Metadata MUST provide an `id` property. 330 | 331 | The value of the `id` property MUST point to a locally unique identifier to address the schema on a given data storage medium (e.g. a database, ledger, distributed file store). Each credential schema has its own unique identifier and each version of a schema is required to have its own unique identifier. 332 | 333 | It is RECOMMENDED that this identifier is [Uniform Resource Identifier](https://www.rfc-editor.org/rfc/rfc3986) which SHOULD contain information pertaining to the author and version of the schema. For example, if the author controls a DID
did:example:abcdefghi334 | 335 | a possible schema ID the author created would have an identifier such as:
did:example:abcdefghi/17de181feb67447da4e78259d92d0240?version=1336 | 337 | which makes use of DID Path syntax as defined by [[DID-CORE]]. 338 | 339 | 4. [=name=] 340 | 341 | Credential Schema Metadata MUST provide a `name` property. 342 | 343 | The value of the `name` property is RECOMMENDED to be a human-readable name which describes the [=Credential Schema=]. 344 | 345 | 5. [=author=] 346 | 347 | Credential Schema Metadata MUST provide an `author` property. 348 | 349 | The value of the `author` property is RECOMMENDED to be a [=DID=] of the author of the [=Credential Schema=]. 350 | 351 | 6. [=authored=] 352 | 353 | Credential Schema Metadata MUST provide an `authored` property. 354 | 355 | The value of the `authored` property MUST be a valid [[RFC3339]] timestamp whose value reflects the date-time value for when the [=Credential Schema=] was created. 356 | 357 | 358 |
359 | { 360 | "type": "https://w3c-ccg.github.io/vc-json-schema/", 361 | "version": "1.0", 362 | "id": "06e126d1-fa44-4882-a243-1e326fbe21db", 363 | "name": "Email", 364 | "author": "did:example:MDP8AsFhHzhwUvGNuYkX7T", 365 | "authored": "2021-01-01T00:00:00+00:00" 366 | } 367 |368 | 369 | ## Schema ## {#credential_schema_schema} 370 | 371 | A [=Credential Schema=] MUST have a `schema` property. The `schema` property MUST be a valid [=JSON Schema=] document. 372 | 373 |
374 | { 375 | "$schema": "https://json-schema.org/draft/2020-12/schema", 376 | "description": "Email", 377 | "type": "object", 378 | "properties": { 379 | "credentialSubject": { 380 | "type": "object", 381 | "properties": { 382 | "emailAddress": { 383 | "type": "string", 384 | "format": "email" 385 | } 386 | }, 387 | "required": [ 388 | "emailAddress" 389 | ] 390 | } 391 | } 392 | } 393 |394 | 395 | Note: It is recommended that Credential Schemas avoid setting the `additionalProperties` value to `false`. Doing so could invalidate credentials that utilize the `id` property in `credentialSubject`. As an alternative, implementers could add an `id` property to each Credential Schema. 396 | 397 | Issue: ISSUE #105. Add language on using different versions of JSON Schema specifications. 398 | 399 | ### Multiple Schemas ### {#credential_schema_schema_multiple} 400 | 401 | A common use case is to include multiple schemas to validate against which a single [=Verifiable Credential=]. One such use case is to utilize the JSON Schema defined by the VC Data Model in addition to a schema to validate a specific property in the credential, such as the `credentialSubject`. Multiple schemas MAY be combined together using native constructs from the [[JSON-SCHEMA]] specification, through utilizing properties such as `oneOf`, `anyOf`, or `allOf`. 402 | 403 | We provide an example of how to construct such a schema using the [[JSON-SCHEMA]] property `allOf` below, combining schemas for a Verifiable Credential, name, and email address: 404 | 405 |
406 | { 407 | "allOf": [ 408 | { 409 | "$ref": "https://raw.githubusercontent.com/w3c/vc-data-model/main/schema/verifiable-credential/verifiable-credential-schema.json" 410 | }, 411 | { 412 | "$id": "name-schema", 413 | "$schema": "https://json-schema.org/draft/2020-12/schema", 414 | "description": "Name", 415 | "type": "object", 416 | "properties": { 417 | "credentialSubject": { 418 | "type": "object", 419 | "properties": { 420 | "name": { 421 | "type": "object", 422 | "properties": { 423 | "firstName": { 424 | "type": "string" 425 | }, 426 | "lastName": { 427 | "type": "string" 428 | }, 429 | "additionalProperties": false 430 | }, 431 | "required": [ 432 | "firstName", 433 | "lastName" 434 | ] 435 | } 436 | } 437 | } 438 | } 439 | }, 440 | { 441 | "$id": "email-schema-1.0", 442 | "$schema": "https://json-schema.org/draft/2020-12/schema", 443 | "description": "Email", 444 | "type": "object", 445 | "properties": { 446 | "credentialSubject": { 447 | "type": "object", 448 | "properties": { 449 | "email": { 450 | "type": "object", 451 | "properties": { 452 | "emailAddress": { 453 | "type": "string", 454 | "format": "email" 455 | } 456 | }, 457 | "required": ["emailAddress"] 458 | } 459 | } 460 | } 461 | } 462 | } 463 | ] 464 | } 465 |466 | 467 | The example above is used to validate every property in the following example [=Verifiable Credential=]: 468 | 469 |
470 | { 471 | "@context": ["https://www.w3.org/ns/credentials/v2"], 472 | "id": "4995c86c-851f-43a6-9dd2-03dc891091fd", 473 | "type": ["VerifiableCredential"], 474 | "issuer": "did:example:1234", 475 | "validFrom": "2023-01-01T05:05:05Z", 476 | "credentialSubject": { 477 | "firstName": "Alice", 478 | "lastName": "Bobertson", 479 | "emailAddress": "alice@bobertson.com" 480 | }, 481 | "credentialSchema": { 482 | "id": "multiple-credential-schema-test", 483 | "type": "CredentialSchema2022" 484 | }, 485 | "proof": { ... } 486 | } 487 |488 | 489 | Notably, this specification defines no special processing rules beyond those already defined by [[JSON-SCHEMA]] itself. 490 | 491 | ## Proof ## {#credential_schema_proof} 492 | 493 | Any [=Credential Schema=] may be authenticated using [[DATA-INTEGRITY]] or [[JOSE]]. 494 | 495 | Issue: ISSUE #103. Discussion needed on whether it is necessary to add language on authentication, or whether a Credential Schema should itself be packaged as a VC itself. 496 | 497 | # Processing # {#processing} 498 | 499 | There is wide support for JSON Schema processing and support for [[JSON-SCHEMA-IMPLMENTATIONS]] can be found in most programming languages. 500 | 501 | To process a [=Verifiable Credential=] against a [=Credential Schema=], one must first extract the schema from the `schema` property of a [=Credential Schema=], and next apply [validation](#processing_validation). 502 | 503 | ## Validation ## {#processing_validation} 504 | 505 | Determining the validity of a [=Verifiable Credential=] is at the discretion of the verifier of a given credential. Validity could mean any of: a valid [=proof=]; a valid [=proof=] and validation against a given [=schema=]; a valid [=proof=], valid credentialStatus, and trusted issuer; or any other set of conditions. The [[VC-DATA-MODEL]]'s section on Validity Checks offers guidance on determining whether a [=Verifiable Credential=] should be considered valid. 506 | 507 | Validation of a given Credential against its schema is to be performed according to the [[JSON-SCHEMA-VALIDATION]] specification. 508 | 509 | An example of the `credentialSchema` property which specifies two properties is shown below: 510 | 511 | - id: a resolvable identifier for a specific [=Credential Schema=] document 512 | 513 | - type: [=CredentialSchema2022=] 514 | 515 |
516 | { 517 | "@context": [ 518 | "https://www.w3.org/2018/credentials/v1", 519 | "https://www.w3.org/2018/credentials/examples/v1" 520 | ], 521 | "id": "http://example.edu/credentials/3732", 522 | "type": ["VerifiableCredential", "UniversityDegreeCredential"], 523 | "issuer": "https://example.edu/issuers/14", 524 | "issuanceDate": "2010-01-01T19:23:24Z", 525 | "credentialSubject": { 526 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 527 | "degree": { 528 | "type": "BachelorDegree", 529 | "name": "Bachelor of Science and Arts" 530 | } 531 | }, 532 | "credentialSchema": { 533 | "id": "https://example.org/examples/degree.json", 534 | "type": "CredentialSchema2022" 535 | } 536 | } 537 |538 | 539 | It RECOMMENDED that implementers use at most one [=Credential Schema=] for each [=Verifiable Credential=]. This data model defines a mechanism to combine multiple [=JSON Schemas=] into a single [=Credential Schema=] in the [schema section](#credential_schema_schema). 540 | 541 | ## Acceptance ## {#processing_acceptance} 542 | 543 | A party may choose to accept [=Credential Schemas=] based on multiple different criteria: storage location, authorship, identifier, version, etc. 544 | 545 | The process by which a schema or set of schemas is accepted by a party is out of scope of this document. It is advisable that such a process be flexible to accommodate important criteria of a schema, such as supporting version ranges with a common property, or enforcing authorship from a known author with a valid authentication mechanism (often referred to as a [=proof=]). 546 | 547 | # Versioning Guidelines # {#versioning_guidelines} 548 | 549 | Issue: ISSUE #120. Feature at risk of removal. 550 | 551 | This section applies to [=version=] property of the [=metadata=]. 552 | 553 | In versioning [=Credential Schemas=] we are primarily concerned with maintaining backwards compatibility and enabling a tracked evolution of schemas. Versioning is defined as MODEL.REVISION where MODEL refers to a breaking change and REVISION refers to a non-breaking change. 554 | 555 | MODEL Updating this number indicates that this version breaks the schema for ANY interaction with an older [=schema=]. For processing, if a holder presents a [=credential=] referencing from a [=schema=] with version 1.0 and a verifier is requesting a credential against version 2.0 of that schema, the verifier is not able to process the credential. 556 | 557 | REVISION Updating this number indicates that this version may prevent interactions with parts of the [=schema=]. For processing, if a holder presents a credential referencing a schema with version 1.0 and a verifier is requesting a credential against version 1.5 of that schema, there are likely to be SOME fields incompatible with the expected [=credential=]. 558 | 559 | ## Model ## {#model} 560 | 561 | When a schema breaks backwards compatibility it is considered a model change. The most common case of a MODEL change is the addition or subtraction of a required field. It is important to note that for the change of a key name on a required field constitutes a MODEL change as this introduces a breaking change, adding a required field. 562 | 563 | An example of this rule is when the additionalProperties field's value changes. Changing additionalProperties from false to true OR from true to false constitutes a breaking change, necessitating a MODEL increment. 564 | 565 |
566 | { 567 | "type": "https://w3c-ccg.github.io/vc-json-schema/", 568 | "version": "1.1", 569 | "id": "did:example:MDP8AsFhHzhwUvGNuYkX7T/06e126d1-fa44-4882-a243-1e326fbe21db;version=1.1", 570 | "name": "Email", 571 | "author": "did:example:MDP8AsFhHzhwUvGNuYkX7T", 572 | "authored": "2018-01-01T00:00:00+00:00", 573 | "schema": { 574 | "$id": "email-schema-1.1", 575 | "$schema": "https://json-schema.org/draft/2020-12/schema", 576 | "description": "Email", 577 | "type": "object", 578 | "properties": { 579 | "credentialSubject": { 580 | "type": "object", 581 | "properties": { 582 | "emailAddress": { 583 | "type": "string", 584 | "format": "email" 585 | }, 586 | "backupEmailAddress": { 587 | "type": "string", 588 | "format": "email" 589 | } 590 | }, 591 | "required": [ 592 | "emailAddress" 593 | ], 594 | "additionalProperties": false 595 | } 596 | } 597 | } 598 | } 599 |600 | 601 | This time our credentialing requirements for our email schema have changed and we need to attach a `firstName` for verification. This is a required field, so we know it is a MODEL change. 602 | 603 |
604 | { 605 | "type": "https://w3c-ccg.github.io/vc-json-schema/", 606 | "version": "2.0", 607 | "id": "did:example:MDP8AsFhHzhwUvGNuYkX7T/06e126d1-fa44-4882-a243-1e326fbe21db;version=2.0", 608 | "name": "Email", 609 | "author": "did:example:MDP8AsFhHzhwUvGNuYkX7T", 610 | "authored": "2018-01-01T00:00:00+00:00", 611 | "schema": { 612 | "$id": "email-schema-2.0", 613 | "$schema": "https://json-schema.org/draft/2020-12/schema", 614 | "description": "Email", 615 | "type": "object", 616 | "properties": { 617 | "credentialSubject": { 618 | "type": "object", 619 | "properties": { 620 | "emailAddress": { 621 | "type": "string", 622 | "format": "email" 623 | }, 624 | "firstName": { 625 | "type": "string" 626 | }, 627 | "backupEmailAddress": { 628 | "type": "string", 629 | "format": "email" 630 | } 631 | }, 632 | "required": [ 633 | "emailAddress", 634 | "firstName" 635 | ], 636 | "additionalProperties": false 637 | } 638 | } 639 | } 640 | } 641 |642 | 643 | ## Revision ## {#revision} 644 | 645 | The addition or removal of an optional field is what constitutes a REVISION. Adding or removing an optional field does not break historical data in a [=schema=], and in a claims exchange protocol, missing optional fields can be ignored. 646 | 647 |
648 | { 649 | "type": "https://w3c-ccg.github.io/vc-json-schema/", 650 | "version": "1.0", 651 | "id": "did:example:MDP8AsFhHzhwUvGNuYkX7T/06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", 652 | "name": "Email", 653 | "author": "did:example:MDP8AsFhHzhwUvGNuYkX7T", 654 | "authored": "2018-01-01T00:00:00+00:00", 655 | "schema": { 656 | "$id": "email-schema-1.0", 657 | "$schema": "https://json-schema.org/draft/2020-12/schema", 658 | "description": "Email", 659 | "type": "object", 660 | "properties": { 661 | "credentialSubject": { 662 | "type": "object", 663 | "properties": { 664 | "emailAddress": { 665 | "type": "string", 666 | "format": "email" 667 | } 668 | }, 669 | "required": [ 670 | "emailAddress" 671 | ], 672 | "additionalProperties": false 673 | } 674 | } 675 | } 676 | } 677 |678 | 679 | In this example we once again reference the email schema, but this time we add an optional field backupEmailAddress. Note that this would not break the claims exchange because the field is optional. 680 | 681 |
682 | { 683 | "type": "https://w3c-ccg.github.io/vc-json-schema/", 684 | "version": "1.1", 685 | "id": "did:example:MDP8AsFhHzhwUvGNuYkX7T/06e126d1-fa44-4882-a243-1e326fbe21db;version=1.1", 686 | "name": "Email", 687 | "author": "did:example:MDP8AsFhHzhwUvGNuYkX7T", 688 | "authored": "2018-01-01T00:00:00+00:00", 689 | "schema": { 690 | "$id": "email-schema-1.1", 691 | "$schema": "https://json-schema.org/draft/2020-12/schema", 692 | "description": "Email", 693 | "type": "object", 694 | "properties": { 695 | "credentialSubject": { 696 | "type": "object", 697 | "properties": { 698 | "emailAddress": { 699 | "type": "string", 700 | "format": "email" 701 | }, 702 | "backupEmailAddress": { 703 | "type": "string", 704 | "format": "email" 705 | } 706 | }, 707 | "required": [ 708 | "emailAddress" 709 | ], 710 | "additionalProperties": false 711 | } 712 | } 713 | } 714 | } 715 |716 | 717 | # Extensibility # {#extensibility} 718 | 719 | By introducing a [=version=] field we allow the [=credential schema=] to become extensible. Properties such as derivedFrom could reference a schema that a new schema is built on top of. Similarly, platform-utility features such as searchability could be provided by adding a tags array that contains categorization and classification information for a [=schema=]. 720 | 721 | These are just a few examples that illustrate the flexibility of the proposed model. It can be extended to support a wide variety of use-cases and make the burden on issuance and verification simpler by facilitating the development of higher-level tooling. 722 | 723 | Issue: ISSUE #107. Expand on this section or remove. 724 | 725 | # Examples # {#examples} 726 | 727 | ## Verifiable Credentials ## {#vc_example} 728 | 729 | We define an Email schema as the basis for a credential. 730 | 731 |
732 | { 733 | "type": "https://w3c-ccg.github.io/vc-json-schema/", 734 | "version": "1.0", 735 | "id": "did:example:MDP8AsFhHzhwUvGNuYkX7T/06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", 736 | "name": "Email", 737 | "author": "did:example:MDP8AsFhHzhwUvGNuYkX7T", 738 | "authored": "2021-01-01T00:00:00+00:00", 739 | "schema": { 740 | "$id": "email-schema-1.0", 741 | "$schema": "https://json-schema.org/draft/2020-12/schema", 742 | "description": "Email", 743 | "type": "object", 744 | "properties": { 745 | "credentialSubject": { 746 | "type": "object", 747 | "properties": { 748 | "emailAddress": { 749 | "type": "string", 750 | "format": "email" 751 | }, 752 | "required": [ 753 | "emailAddress" 754 | ], 755 | "additionalProperties": false 756 | } 757 | } 758 | } 759 | } 760 | } 761 |762 | 763 | The example references a [=Credential Schema=] with an identifier did:example:MDP8AsFhHzhwUvGNuYkX7T/06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0 inside of a Verifiable Credential following the [[VC-DATA-MODEL]]. The example is adapted from Example 18 in the specification. 764 | 765 |
766 | { 767 | "@context": [ 768 | "https://www.w3.org/2018/credentials/v1", 769 | "https://www.w3.org/2018/credentials/examples/v1" 770 | ], 771 | "id": "http://example.edu/credentials/1872", 772 | "type": ["VerifiableCredential", "EmailCredential"], 773 | "issuer": "https://example.com/issuers/565049", 774 | "issuanceDate": "2021-01-01T00:00:00Z", 775 | "credentialSchema": { 776 | "id": "did:example:MDP8AsFhHzhwUvGNuYkX7T/06e126d1-fa44-4882-a243-1e326fbe21db;version=1.0", 777 | "type": "CredentialSchema2022" 778 | }, 779 | "credentialSubject": { 780 | "id": "did:example:MDP8AsFhHzhwUvGNuYkX7T", 781 | "emailAddress": "first.last@example.com" 782 | } 783 | }, 784 | "proof": { ... } 785 | } 786 |787 | 788 | The ID of the [=Credential Schema=] is visible in the credentialSchema section of the credential, and provides information about the schema's author and version. The type of CredentialSchema2022 refers to the type value defined by this specification providing information on how the data in the credentialSubject should be validated against the provided schema. 789 | 790 | # Drawbacks # {#drawbacks} 791 | 792 | Within a credentialing ecosystem, relying heavily upon [[JSON-SCHEMA]] makes data shapes for credentials consistent, and could enable an ecosystem with many similar schemas with slight changes (naming, capitalization). Without proper oversight or authoritative schemas to limit duplication or misuse, utilization of [[JSON-SCHEMA]] could lead to a poor user experience. At a higher level, platform level tooling can be provided to minimize confusion and promote reuse. 793 | 794 | Validation against a [[JSON-SCHEMA]] may be confused with validation or verification of a Verifiable Credential. A valid credential according to a [[JSON-SCHEMA]] refers only to the structure of the claims comprising a Verifiable Credential. This doesn't imply anything about the validity of the Verifiable Credential itself. It's possible for a Verifiable Credential to be considered valid by one verifier, while another verifier would not consider it valid. 795 | 796 | Within the broader Credentialing Ecosystem, interoperability could be more difficult if the wider community adopts [[JSON-LD]] without advocating for pairing with [[JSON-SCHEMA]] based schemas or credentials. This issue can mainly be side-stepped with the metadata we include –– the Credential Schema –– since this model is flexible to change. A new [=version=] could be introduced that supports [[JSON-LD]] and removes support for [[JSON-SCHEMA]]. A drawback here is the requirement that all schemas have this piece of metadata, which itself is versioned and evolvable. 797 | 798 | A flip side to drawbacks of the usage of [[JSON-SCHEMA]] is that there is a plethora of documentation, libraries, and usage of [[JSON-SCHEMA]] across programming languages and the web. 799 | 800 | # Usage with JSON-LD # {#alternatives} 801 | 802 | [[JSON-LD]] is widely used in the Verifiable Credentials Data Model ecosystem. Both [[JSON-LD]] and [[JSON-SCHEMA]] serve distinct use cases. [[JSON-LD]] is primarily useful for facilitating global semantic interoperability for terms in a credential and tie-in to an "open world data model."" [[JSON-SCHEMA]] on the other hand is most often useful for strict data validation, though it does not provide the same functionality in regards to strict data validation. 803 | 804 | It has been suggested that both [[JSON-SCHEMA]] and [[JSON-LD]] can work symbiotically in the credentialing ecosystem: [[JSON-LD]] providing semantic interoperability, and [[JSON-SCHEMA]] providing static validation. 805 | 806 | Issue: ISSUE #122. Need to add an example of a credential using both JSON-LD and JSON Schema along with language as to why one would choose to do this. 807 | 808 | # Interoperability # {#interoperability} 809 | 810 | The primary concern of this specification is to facilitate an ecosystem in which [=Verifiable Credentials=] can be issued and used. To be interoperable, additional schema types may need to be supported. Given the capability of versioning for [Credential Schema Metadata](#metadata) interoperability between Credential Schemas is mostly solved. 811 | 812 | A goal of publishing this document is to promote others to adopt this schema philosophy. It also opens the door for providing feedback and collaborative contribution to developing primitives that would lead to a successful verifiable ecosystem. 813 | 814 | Issue: ISSUE #106. Discussion on other types of interoperability and how this schema does or does not help. 815 | 816 |
817 | { 818 | "VC-DATA-MODEL": { 819 | "href": "https://www.w3.org/TR/vc-data-model/", 820 | "title": "Verifiable Credentials Data Model 1.0", 821 | "publisher": "W3C" 822 | }, 823 | "RFC3339": { 824 | "href": "https://tools.ietf.org/html/rfc3339", 825 | "title": "Date and Time on the Internet: Timestamps", 826 | "publisher": "IETF" 827 | }, 828 | "JSON-SCHEMA": { 829 | "href": "https://json-schema.org/draft/2020-12/json-schema-core.html", 830 | "title": "JSON Schema: A Media Type for Describing JSON Documents", 831 | "publisher": "IETF" 832 | }, 833 | "JSON-SCHEMA-VALIDATION": { 834 | "href": "https://json-schema.org/draft/2020-12/json-schema-validation.html", 835 | "title": "JSON Schema Validation: A Vocabulary for Structural Validation of JSON", 836 | "publisher": "IETF" 837 | }, 838 | "DID-CORE": { 839 | "href": "https://w3c.github.io/did-core/", 840 | "title": "Decentralized Identifiers (DIDs) v1.0", 841 | "publisher": "W3C" 842 | }, 843 | "JSON-LD": { 844 | "href": "https://w3c.github.io/json-ld-syntax/", 845 | "title": "JSON-LD 1.1: A JSON-based Serialization for Linked Data", 846 | "publisher": "W3C" 847 | }, 848 | "DATA-INTEGRITY": { 849 | "href": "https://w3c-ccg.github.io/data-integrity-spec/", 850 | "title": "Data Integrity. Manu Sporny; Dave Longley. Credentials Community Group. CG-DRAFT", 851 | "publisher": "W3C" 852 | }, 853 | "JOSE": { 854 | "href": "https://jose.readthedocs.io/en/latest/", 855 | "title": "Javascript Object Signing and Encryption (JOSE)", 856 | "publisher": "IETF" 857 | }, 858 | "JSON-SCHEMA-IMPLMENTATIONS": { 859 | "href": "https://json-schema.org/implementations.html", 860 | "title": "JSON Schema Implementations", 861 | "publisher": "json-schema-org" 862 | }, 863 | "RFC2119": { 864 | "href": "https://www.rfc-editor.org/rfc/rfc2119", 865 | "title": "Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice", 866 | "publisher": "IETF" 867 | }, 868 | "RFC8174": { 869 | "href": "https://www.rfc-editor.org/rfc/rfc8174", 870 | "title": "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice", 871 | "publisher": "IETF" 872 | } 873 | } 874 |-------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # These owners will be the default owners for everything in 2 | # the repo. Unless a later match takes precedence, 3 | # they will be requested for review when someone opens a 4 | # pull request. 5 | * @mkhraisha 6 | 7 | # See CODEOWNERS syntax here: https://help.github.com/articles/about-codeowners/#codeowners-syntax 8 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | All documentation, code and communication under this repository are covered 4 | by the [W3C Code of Ethics and Professional Conduct](https://www.w3.org/Consortium/cepc/). 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # W3C Verifiable Credentials Working Group 2 | 3 | Contributions to this repository are intended to become part of 4 | Recommendation-track documents governed by the 5 | [W3C Patent Policy](https://www.w3.org/Consortium/Patent-Policy-20040205/) and 6 | [Software and Document License](https://www.w3.org/Consortium/Legal/copyright-software). 7 | To make substantive contributions to specifications, you must either participate 8 | in the relevant W3C Working Group or make a non-member patent licensing commitment. 9 | 10 | If you are not the sole contributor to a contribution (pull request), please 11 | identify all contributors in the pull request comment. 12 | 13 | To add a contributor (other than yourself, that's automatic), mark them one 14 | per line as follows: 15 | 16 | ``` 17 | +@github_username 18 | ``` 19 | 20 | If you added a contributor by mistake, you can remove them in a comment with: 21 | 22 | ``` 23 | -@github_username 24 | ``` 25 | 26 | If you are making a pull request on behalf of someone else but you had no 27 | part in designing the feature, you can remove yourself with the above syntax. -------------------------------------------------------------------------------- /EXPLAINER.md: -------------------------------------------------------------------------------- 1 | # VC JSON Schema Explained 2 | 3 | [Verifiable Credentials](https://w3c.github.io/vc-data-model/) provide a JSON-LD data model that enables the issuance, sharing, and verification of digital credentials in a secure and interoperable manner. These credentials provide a way for individuals, organizations, and other entities to digitally represent and share their qualifications, attributes, and/or other relevant information. Verifiable Credentials are designed to enhance trust, privacy, and control in digital interactions by allowing the owner of the credentials to control how their information is shared and verified. 4 | 5 | ## Authors 6 | 7 | - Gabe Cohen 8 | - Orie Steele 9 | - Andres Uribe 10 | 11 | ## Participate 12 | 13 | - [Issue tracker](https://github.com/w3c/vc-json-schema/issues) 14 | - [Discussion forum](https://lists.w3.org/Archives/Public/public-vc-wg/) 15 | 16 | ## Goals 17 | 18 | Leveraging the section on [Data Schemas](https://w3c.github.io/vc-data-model/#data-schemas) in the VC Data Model, we aim to provide a stable and usable implementation for the `credentialSchema` property using the widely-adopted [JSON Schema](https://json-schema.org/) technology for _data verification schemas_. This allows any verifiable credential to have its data shape defined by a JSON Schema. We allow the JSON Schema to be represented as plain JSON or as a verifiable credential. 19 | 20 | As stated in the data model: 21 | 22 | > Data schemas are useful when enforcing a specific structure on a given collection of data. 23 | > 24 | > Data verification schemas, which are used to verify that the structure and contents of a credential or verifiable credential conform to a published schema. 25 | 26 | 27 | ## How It Works 28 | 29 | Before constructing or issuing a verifiable credential, there must first be a JSON Schema. The JSON Schema can exist anywhere as long as it is URI-addressable. The JSON Schema can be conformant to any specification version listed in the latest draft of this specification. We provide two `type` values for using JSON Schema within the `credentialSchema` property of a verifiable credential: 30 | 31 | 1. `JsonSchema2023` 32 | 33 | For plain use of a JSON Schema, we make available the type `JsonSchema2023`. 34 | 35 | 2. `CredentialSchema2023` 36 | 37 | Should the author of a JSON schema want to add additional features such as status, integrity protection, or retaining authorship information, there is an option to wrap the schema in a verifiable credential. For use of a JSON Schema packaged as a verifiable credential, we make available the type `CredentialSchema2023`. 38 | 39 | ### Example using JsonSchema2023 40 | 41 | **JSON Schema** 42 | 43 | ```json 44 | { 45 | "$id": "https://example.com/schemas/email.json", 46 | "$schema": "https://json-schema.org/draft/2020-12/schema", 47 | "title": "EmailCredential", 48 | "description": "EmailCredential using JsonSchema2023", 49 | "type": "object", 50 | "properties": { 51 | "credentialSubject": { 52 | "type": "object", 53 | "properties": { 54 | "emailAddress": { 55 | "type": "string", 56 | "format": "email" 57 | } 58 | }, 59 | "required": [ 60 | "emailAddress" 61 | ] 62 | } 63 | } 64 | } 65 | ``` 66 | 67 | **Verifiable Credential** 68 | 69 | ```json 70 | { 71 | "@context": [ 72 | "https://www.w3.org/ns/credentials/v2", 73 | "https://www.w3.org/ns/credentials/examples/v2" 74 | ], 75 | "id": "https://example.com/credentials/3732", 76 | "type": ["VerifiableCredential", "EmailCredential"], 77 | "issuer": "https://example.com/issuers/14", 78 | "issuanceDate": "2010-01-01T19:23:24Z", 79 | "credentialSubject": { 80 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 81 | "emailAddress": "subject@example.com" 82 | }, 83 | "credentialSchema": { 84 | "id": "https://example.com/schemas/email.json", 85 | "type": "JsonSchema2023" 86 | } 87 | } 88 | ``` 89 | 90 | ### Example using CredentialSchema2023 91 | 92 | **JSON Schema as a Credential** 93 | 94 | ```json 95 | { 96 | "@context": [ 97 | "https://www.w3.org/ns/credentials/v2", 98 | "https://www.w3.org/ns/credentials/examples/v2" 99 | ], 100 | "id": "https://example.com/credentials/3734", 101 | "type": ["VerifiableCredential", "CredentialSchema2023"], 102 | "issuer": "https://example.com/issuers/14", 103 | "issuanceDate": "2010-01-01T19:23:24Z", 104 | "credentialSubject": { 105 | "$id": "https://example.com/schemas/email-credential-schema.json", 106 | "$schema": "https://json-schema.org/draft/2020-12/schema", 107 | "title": "EmailCredential", 108 | "description": "EmailCredential using CredentialSchema2023", 109 | "type": "object", 110 | "properties": { 111 | "credentialSubject": { 112 | "type": "object", 113 | "properties": { 114 | "emailAddress": { 115 | "type": "string", 116 | "format": "email" 117 | } 118 | }, 119 | "required": ["emailAddress"] 120 | } 121 | } 122 | } 123 | } 124 | ``` 125 | 126 | **Verifiable Credential** 127 | 128 | ```json 129 | { 130 | "@context": [ 131 | "https://www.w3.org/ns/credentials/v2", 132 | "https://www.w3.org/ns/credentials/examples/v2" 133 | ], 134 | "id": "https://example.com/credentials/3733", 135 | "type": ["VerifiableCredential", "EmailCredential"], 136 | "issuer": "https://example.com/issuers/14", 137 | "issuanceDate": "2010-01-01T19:23:24Z", 138 | "credentialSubject": { 139 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 140 | "emailAddress": "subject@example.com" 141 | }, 142 | "credentialSchema": { 143 | "id": "https://example.com/credentials/3734", 144 | "type": "CredentialSchema2023" 145 | } 146 | } 147 | ``` 148 | 149 | ## Conclusions 150 | 151 | This document is a high-level summary of VC JSON Schemas as one option for use of the `credentialSchema` property in the VC Data Model. There may be other `type` definitions that make use of schema mechanisms other than JSON Schema, as the VC Data Model is by design open and extensible. 152 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | All documents in this Repository are licensed by contributors under the [W3C Software and Document License](https://www.w3.org/Consortium/Legal/copyright-software). 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Verifiable Credential JSON Schema 2023 2 | 3 | This specification provides a mechanism for the use of [JSON Schemas](https://json-schema.org/) with [Verifiable Credentials](https://w3c.github.io/vc-data-model/). A significant part of the integrity of a Verifiable Credential comes from the ability to structure its contents so that all three parties — issuer, holder, verifier — may have a consistent mechanism of trust in interpreting the data that they are provided with. We introducing a new data model for an object to facilitate backing Credentials with JSON Schemas that we call a Credential Schema. 4 | 5 | https://w3c.github.io/vc-json-schema/ 6 | 7 | We encourage contributions meeting the [Contribution Guidelines](CONTRIBUTING.md). While we prefer the creation of issues 8 | and Pull Requests in the GitHub repository, discussions may also occur on the [public-credentials](http://lists.w3.org/Archives/Public/public-credentials/) mailing list. 9 | 10 | ### Test Suite 11 | 12 | A [docker](https://www.docker.com/)-based test suite for the specification can [be found here](https://github.com/w3c/vc-json-schema-test-suite). All implementers are encouraged to add to the test suite. 13 | 14 | ### Building 15 | 16 | To build, we use [`respec`](https://respec.org/). 17 | 18 | After installing `respec`, you can build the spec locally using the following command: 19 | 20 | ```sh 21 | respec --localhost index.html out.html --verbose -e 22 | ``` 23 | 24 | Next open up `out.html` in a web browser and review the document. 25 | 26 | ### Other useful links 27 | * [Public group email archive](https://lists.w3.org/Archives/Public/public-credentials/) 28 | * [VC Data Model](https://www.w3.org/TR/vc-data-model/) 29 | * [JSON Schema](https://json-schema.org/) 30 | * [Test Suite](https://github.com/w3c/vc-json-schema-test-suite) 31 | -------------------------------------------------------------------------------- /common.js: -------------------------------------------------------------------------------- 1 | /* globals omitTerms, respecConfig, $, require */ 2 | /* exported linkCrossReferences, restrictReferences, fixIncludes */ 3 | 4 | var vcwg = { 5 | // Add as the respecConfig localBiblio variable 6 | // Extend or override global respec references 7 | localBiblio: { 8 | "JSON-SCHEMA": { 9 | href: "https://json-schema.org/specification.html", 10 | title: "JSON Schema: A Media Type for Describing JSON Documents", 11 | publisher: "OpenJS Foundation" 12 | }, 13 | "JSON-SCHEMA-2020-12": { 14 | href: "https://json-schema.org/draft/2020-12/release-notes.html", 15 | title: "JSON Schema 2020-12 Release Notes", 16 | publisher: "OpenJS Foundation" 17 | }, 18 | "JSON-SCHEMA-2019-09": { 19 | href: "https://json-schema.org/draft/2019-09/release-notes.html", 20 | title: "JSON Schema 2019-09 Release Notes", 21 | publisher: "OpenJS Foundation" 22 | }, 23 | "JSON-SCHEMA-DRAFT-7": { 24 | href: "https://json-schema.org/draft-07/json-schema-release-notes.html", 25 | title: "JSON Schema Draft-07 Release Notes", 26 | publisher: "OpenJS Foundation" 27 | }, 28 | "VC-JOSE-COSE": { 29 | href: "https://www.w3.org/TR/vc-jose-cose/", 30 | title: "Securing Verifiable Credentials using JOSE and COSE", 31 | authors: ["Orie Steele", "Michael Jones", "Michael Prorock"], 32 | publisher: "W3C" 33 | }, 34 | "SD-JWT": { 35 | title: "Selective Disclosure for JWTs (SD-JWT)", 36 | href: "https://datatracker.ietf.org/doc/html/draft-ietf-oauth-selective-disclosure-jwt-05", 37 | authors: ["Daniel Fett", "Kristina Yasuda", "Brian Campbell"], 38 | status: "Internet-Draft", 39 | publisher: "IETF" 40 | } 41 | } 42 | }; 43 | require(["core/pubsubhub"], (respecEvents) => { 44 | "use strict"; 45 | 46 | respecEvents.sub('end-all', (message) => { 47 | console.log("END EVENT", message); 48 | // remove data-cite on where the citation is to ourselves. 49 | const selfDfns = document.querySelectorAll("dfn[data-cite^='" + respecConfig.shortName.toUpperCase() + "#']"); 50 | for (const dfn of selfDfns) { 51 | delete dfn.dataset.cite; 52 | } 53 | 54 | // Update data-cite references to ourselves. 55 | const selfRefs = document.querySelectorAll("a[data-cite^='" + respecConfig.shortName.toUpperCase() + "#']"); 56 | for (const anchor of selfRefs) { 57 | anchor.href= anchor.dataset.cite.replace(/^.*#/,"#"); 58 | delete anchor.dataset.cite; 59 | } 60 | 61 | }); 62 | 63 | }); 64 | 65 | // Removes dfns that aren't referenced anywhere in the spec. 66 | // To ensure a definition appears in the Terminology section, use 67 | // and link to it! 68 | // This is triggered by postProcess in the respec config. 69 | function restrictRefs(config, document) { 70 | 71 | // Get set of ids internal dfns referenced in the spec body 72 | const internalDfnLinks = document.querySelectorAll("a.internalDFN"); 73 | let internalDfnIds = new Set(); 74 | for (const dfnLink of internalDfnLinks) { 75 | const dfnHref = dfnLink.href.split("#")[1]; 76 | internalDfnIds.add(dfnHref); 77 | } 78 | 79 | // Remove unused dfns from the termlist 80 | const termlist = document.querySelector(".termlist"); 81 | const linkIdsInDfns = []; 82 | for (const child of termlist.querySelectorAll("dfn")){ 83 | if (!internalDfnIds.has(child.id)){ 84 | let dt = child.closest("dt"); 85 | let dd = dt.nextElementSibling; 86 | 87 | // Get internal links from dfns we're going to remove 88 | // because these show up in the dfn-panels later and then 89 | // trigger the local-refs-exist linter (see below) 90 | const linksInDfn = dd.querySelectorAll("a.internalDFN"); 91 | for (link of linksInDfn) { 92 | linkIdsInDfns.push(link.id); 93 | } 94 | 95 | termlist.removeChild(dt); 96 | termlist.removeChild(dd); 97 | } 98 | } 99 | 100 | // Remove unused dfns from the dfn-panels 101 | // (these are hidden, but still trigger the local-refs-exist linter) 102 | // (this seems like a hack, there's probably a better way to hook into respec 103 | // before it gets to this point) 104 | const dfnPanels = document.querySelectorAll(".dfn-panel"); 105 | for (const panel of dfnPanels) { 106 | if (!internalDfnIds.has(panel.querySelector(".self-link").href.split("#")[1])) { 107 | panel.parentNode.removeChild(panel); 108 | } 109 | 110 | // Remove references to dfns we removed which link to other dfns 111 | const panelLinks = panel.querySelectorAll("li a"); 112 | for (const link of panelLinks) { 113 | if (linkIdsInDfns.includes(link.href.split("#")[1])) { 114 | link.parentNode.removeChild(link); 115 | } 116 | } 117 | } 118 | } 119 | 120 | function _esc(s) { 121 | return s.replace(/&/g,'&') 122 | .replace(/>/g,'>') 123 | .replace(/"/g,'"') 124 | .replace(/ s.trim()).map(s => s.search(/[^\s]/)); 134 | const leastIndent = Math.min(...indents); 135 | return lines.map(s => s.slice(leastIndent)).join("\n"); 136 | } 137 | 138 | function updateExample(doc, content) { 139 | // perform transformations to make it render and prettier 140 | return _esc(reindent(unComment(doc, content))); 141 | } 142 | 143 | function unComment(doc, content) { 144 | // perform transformations to make it render and prettier 145 | return content 146 | .replace(//, '') 148 | .replace(/< !\s*-\s*-/g, '') 150 | .replace(/-\s*-\s*>/g, '-->'); 151 | } -------------------------------------------------------------------------------- /example/yaml-json-schema.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | "$id": https://example.com/schemas/email.json 3 | "$schema": https://json-schema.org/draft/2020-12/schema 4 | title: Email Credential Schema 5 | description: Email Credential JSON Schema using YAML 6 | type: object 7 | properties: 8 | credentialSubject: 9 | type: object 10 | properties: 11 | emailAddress: 12 | type: string 13 | format: email 14 | required: 15 | - emailAddress 16 | example: |- 17 | { 18 | "$id": "https://example.com/schemas/email.json", 19 | "$schema": "https://json-schema.org/draft/2020-12/schema", 20 | "title": "EmailCredential", 21 | "description": "Email Credential JSON Schema", 22 | "type": "object", 23 | "properties": { 24 | "credentialSubject": { 25 | "type": "object", 26 | "properties": { 27 | "emailAddress": { 28 | "type": "string", 29 | "format": "email" 30 | } 31 | }, 32 | "required": ["emailAddress"] 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
117 | Among other things, the [[VC-DATA-MODEL-2.0]] specifies the models used for Verifiable Credentials, 118 | Verifiable Presentations, and explains the relationships between three parties: 119 | issuers, holders, and verifiers. Verifiability, extensibility, and semantic 120 | interoperability are critical pieces of functionality referenced throughout 121 | the [[VC-DATA-MODEL-2.0]]. This specification provides a mechanism to make use of a Credential Schema in 122 | Verifiable Credential, leveraging the existing 123 | Data Schemas concept. 124 |
125 |129 | The Working Group is actively seeking implementation feedback for this 130 | specification. In order to exit the Candidate Recommendation phase, the 131 | Working Group has set the requirement of at least two independent 132 | implementations for each mandatory feature in the specification. For details 133 | on the conformance testing process, see the test suites listed in the 134 | 135 | implementation report. 136 |
137 |141 | This specification provides a mechanism for the use of JSON Schemas with 142 | Verifiable Credentials. A significant part of the integrity of a Verifiable Credential 143 | comes from the ability to structure its contents so that all three parties — 144 | issuer, holder, verifier — may have a consistent mechanism of trust in 145 | interpreting the data that they are provided with. We introducing a new data 146 | model for an object to facilitate backing Credentials with JSON Schemas 147 | that we call a Credential Schema. 148 |
149 |150 | This specification provides a standardized way of creating Credential Schemas 151 | to be used in credentialing systems. Credential Schemas may apply to any portion 152 | of a Verifiable Credential. Multiple JSON Schemas may back a single Verifiable Credential, 153 | e.g. a schema for the `credentialSubject` and another for other credential properties. 154 |
155 |
165 | The following sections outline the data models for this document, of which there are two:
166 | JsonSchema
for usage of a [[JSON-SCHEMA]] directly in a credentialSchema
167 | property, and JsonSchemaCredential
for usage of a [[JSON-SCHEMA]] represented as a
168 | verifiable credential.
169 |
171 | Implementers MAY package a [[JSON-SCHEMA]] as a verifiable credential when they wish to 172 | leverage features of the [[VC-DATA-MODEL-2.0]], answering questions such as: 173 |
174 |issuer
property)validFrom
, validUntil
, and credentialStatus
properties)183 | This term is part of the 184 | Verifiable Credentials Vocabulary v2.0. 185 |
186 |
187 | JsonSchema is used for the validation of W3C Verifiable Credentials using
188 | JSON Schema. When dereferencing the id
property associated with the
189 | JsonSchema
type
value the result is a valid JSON
190 | Schema document according to its specification version.
191 |
192 | The specification version of [[JSON-SCHEMA]] can be any version noted in the section 193 | on JSON Schema Specifications. 194 |
195 |Property | 199 |Description | 200 |
---|---|
id | 205 |The constraints on the id property are listed in the Verifiable Credentials
206 | Data Model specification [[VC-DATA-MODEL-2.0]]. The value MUST be a URL that identifies
207 | the schema associated with the verifiable credential. |
208 |
type | 211 |The type property MUST be JsonSchema . |
212 |
216 | The jsonSchema
property is only to be used
217 | when the JsonSchema
class instance is the object of the credentialSubject
218 | property within a JsonSchemaCredential
instance.
219 |
221 | An example of utilizing the VC Data Model's credentialSchema
222 | is provided below:
223 |
225 | { 226 | "@context": [ 227 | "https://www.w3.org/ns/credentials/v2", 228 | "https://www.w3.org/ns/credentials/examples/v2" 229 | ], 230 | "id": "https://example.com/credentials/3732", 231 | "type": ["VerifiableCredential", "EmailCredential"], 232 | "issuer": "https://example.com/issuers/14", 233 | "issuanceDate": "2010-01-01T19:23:24Z", 234 | "credentialSubject": { 235 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 236 | "emailAddress": "subject@example.com" 237 | }, 238 | "credentialSchema": { 239 | "id": "https://example.com/schemas/email.json", 240 | "type": "JsonSchema" 241 | } 242 | } 243 |244 |
245 | Upon dereferencing the value of the id
https://example.com/schemas/email.json
,
246 | a process also be referred to as schema resolution, the following JSON Schema
247 | document is returned:
248 |
250 | { 251 | "$id": "https://example.com/schemas/email.json", 252 | "$schema": "https://json-schema.org/draft/2020-12/schema", 253 | "title": "EmailCredential", 254 | "description": "EmailCredential using JsonSchema", 255 | "type": "object", 256 | "properties": { 257 | "credentialSubject": { 258 | "type": "object", 259 | "properties": { 260 | "emailAddress": { 261 | "type": "string", 262 | "format": "email" 263 | } 264 | }, 265 | "required": [ 266 | "emailAddress" 267 | ] 268 | } 269 | } 270 | } 271 |272 |
276 | This term is part of the 277 | Verifiable Credentials Vocabulary v2.0. 278 |
279 |
280 | JsonSchemaCredential is used for the validation of W3C Verifiable Credentials using
281 | JSON Schema, where the JSON Schema is contained with a verifiable credential.
282 | When dereferencing the id
property associated with the
283 | credentialSchema
type
value, the result is a valid
284 | verifiable credential. For the resulting verifiable credential:
285 |
286 |
credentialSubject
property MUST contain two properties:
289 | type
– the value of which MUST be JsonSchema
jsonSchema
– an object which contains a valid JSON SchemacredentialSchema
property MUST always be set to:
296 | 297 | { 298 | "id": "https://www.w3.org/ns/credentials/json-schema/v2.json", 299 | "type": "JsonSchema", 300 | "digestSRI": "sha384-S57yQDg1MTzF56Oi9DbSQ14u7jBy0RDdx0YbeV7shwhCS88G8SCXeFq82PafhCrW" 301 | } 302 |303 |
304 | The hash value of the digestSRI
property might change during the Candidate Recommendation
305 | phase based on implementer feedback that requires the referenced files to be modified.
306 |
310 | Any version of [[JSON-SCHEMA]] in the section on 311 | JSON Schema Specifications 312 | can be used. 313 |
314 |Property | 318 |Description | 319 |
---|---|
id | 324 |The constraints on the id property are listed in the Verifiable Credentials
325 | Data Model specification [[VC-DATA-MODEL-2.0]]. The value MUST be a URL that identifies
326 | the verifiable credential which contains a credential schema. |
327 |
type | 330 |The type property MUST be JsonSchemaCredential . |
331 |
credentialSubject.id | 334 |The credentialSubject 's id property MUST follow the guidance
335 | provided for identifiers in the [[VC-DATA-MODEL-2.0]]
336 | specification. |
337 |
credentialSubject.type | 340 |The credentialSubject 's type property MUST be
341 | JsonSchema. |
342 |
credentialSubject.jsonSchema | 345 |The credentialSubject MUST use the jsonSchema property to
346 | represent a valid [[JSON-SCHEMA]]. |
347 |
351 | An example of utilizing the VC Data Model's credentialSchema
352 | is provided below:
353 |
355 | { 356 | "@context": [ 357 | "https://www.w3.org/ns/credentials/v2", 358 | "https://www.w3.org/ns/credentials/examples/v2" 359 | ], 360 | "id": "https://example.com/credentials/3733", 361 | "type": ["VerifiableCredential", "ExampleEmailCredential"], 362 | "issuer": "https://example.com/issuers/14", 363 | "issuanceDate": "2010-01-01T19:23:24Z", 364 | "credentialSubject": { 365 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 366 | "emailAddress": "subject@example.com" 367 | }, 368 | "credentialSchema": { 369 | "id": "https://example.com/credentials/3734", 370 | "type": "JsonSchemaCredential" 371 | } 372 | } 373 |374 |
375 | Upon dereferencing the value of the id
https://example.com/credentials/3734
,
376 | a process also be referred to as schema resolution, the following verifiable credential,
377 | representing a JSON Schema, is returned:
378 |
380 | { 381 | "@context": [ 382 | "https://www.w3.org/ns/credentials/v2", 383 | "https://www.w3.org/ns/credentials/examples/v2" 384 | ], 385 | "id": "https://example.com/credentials/3734", 386 | "type": ["VerifiableCredential", "JsonSchemaCredential"], 387 | "issuer": "https://example.com/issuers/14", 388 | "issuanceDate": "2010-01-01T19:23:24Z", 389 | "credentialSchema": { 390 | "id": "https://www.w3.org/ns/credentials/json-schema/v2.json", 391 | "type": "JsonSchema", 392 | "digestSRI": "sha384-S57yQDg1MTzF56Oi9DbSQ14u7jBy0RDdx0YbeV7shwhCS88G8SCXeFq82PafhCrW" 393 | }, 394 | "credentialSubject": { 395 | "id": "https://example.com/schemas/email-credential-schema.json", 396 | "type": "JsonSchema", 397 | "jsonSchema": { 398 | "$id": "https://example.com/schemas/email-credential-schema.json", 399 | "$schema": "https://json-schema.org/draft/2020-12/schema", 400 | "title": "EmailCredential", 401 | "description": "EmailCredential using JsonSchemaCredential", 402 | "type": "object", 403 | "properties": { 404 | "credentialSubject": { 405 | "type": "object", 406 | "properties": { 407 | "emailAddress": { 408 | "type": "string", 409 | "format": "email" 410 | } 411 | }, 412 | "required": ["emailAddress"] 413 | } 414 | } 415 | } 416 | } 417 | } 418 |419 |
422 | This term is part of the 423 | Verifiable Credentials Vocabulary v2.0. 424 |
425 |jsonSchema enables the use of the jsonSchema
property
426 | within the credentialSubject
of a verifiable credential. The term is
427 | intended to be used with the type only. The value of
428 | the jsonSchema
property MUST be a valid [[JSON-SCHEMA]].
429 |
431 | {
432 | "@context": [
433 | "https://www.w3.org/ns/credentials/v2",
434 | "https://www.w3.org/ns/credentials/examples/v2"
435 | ],
436 | "id": "https://example.com/credentials/3734",
437 | "type": ["VerifiableCredential", "JsonSchemaCredential"],
438 | "issuer": "https://example.com/issuers/14",
439 | "issuanceDate": "2010-01-01T19:23:24Z",
440 | "credentialSchema": {
441 | "id": "https://www.w3.org/ns/credentials/json-schema/v2.json",
442 | "type": "JsonSchema",
443 | },
444 | "credentialSubject": {
445 | "id": "https://example.com/schemas/favorite-color-schema.json",
446 | "type": "JsonSchema",
447 | "jsonSchema": {
448 | "$id": "https://example.com/schemas/favorite-color-schema.json",
449 | "$schema": "https://json-schema.org/draft/2020-12/schema",
450 | "title": "Favorite Color Schema",
451 | "description": "Favorite Color using JsonSchemaCredential",
452 | "type": "object",
453 | "properties": {
454 | "credentialSubject": {
455 | "type": "object",
456 | "properties": {
457 | "favoriteColor": {
458 | "type": "string"
459 | "enum": ["red", "orange", "green", "blue", "yellow", "purple"]
460 | }
461 | },
462 | "required": ["favoriteColor"]
463 | }
464 | }
465 | }
466 |
467 | }
468 | }
469 |
470 |
471 | The $ref
property can be used to reference another jsonSchema without redefining the JSON structure.
472 |
474 | {
475 | "@context": [
476 | "https://www.w3.org/ns/credentials/v2",
477 | "https://www.w3.org/ns/credentials/examples/v2"
478 | ],
479 | "id": "https://example.com/credentials/3734",
480 | "type": ["VerifiableCredential", "JsonSchemaCredential"],
481 | "issuer": "https://example.com/issuers/14",
482 | "issuanceDate": "2010-01-01T19:23:24Z",
483 | "credentialSchema": {
484 | "id": "https://www.w3.org/ns/credentials/json-schema/v2.json",
485 | "type": "JsonSchema",
486 | },
487 | "credentialSubject": {
488 | "id": "https://example.com/schemas/favorite-color-schema.json",
489 | "type": "JsonSchema",
490 | "jsonSchema": {
491 | "$ref": "https://example.com/schemas/favorite-color-schema.json"
492 | }
493 |
494 | }
495 | }
496 |
497 | 503 | The following section describes the allowed specifications for 504 | using a [[JSON-SCHEMA]] with a credential schema. 505 |
506 |507 | To promote conformance and enable interoperability, implementers MUST 508 | provide support for JSON Schema specifications where, in the following table, 509 | the required column's value is yes. 510 |
511 |JSON Schema Specification | 515 |Date of Publication | 516 |$schema URI | 517 |Required | 518 |
---|---|---|---|
[[JSON-SCHEMA-2020-12]] | 523 |10 June 2022 | 524 |https://json-schema.org/draft/2020-12/schema | 525 |Yes | 526 |
531 | A stable JSON Schema specification 532 | is in the works. When it's released, we intend to update this table to require the stable version. 533 |
534 | 535 |538 | JSON Schema specifications reserve certain keywords that hold specific meanings and 539 | functions during the processing of JSON Schemas. It is crucial to avoid using conflicting 540 | keys when creating JSON Schemas. The specification document for each version of JSON Schema 541 | lists these reserved keywords, which can be found in the table provided above. 542 |
543 |544 | In the upcoming sections we list some keywords that possess unique significance in 545 | [[JSON-SCHEMA]] documents and SHOULD NOT be used in conflicting ways, such as redefining 546 | these keywords, or using them in a manner other than as noted by [[JSON-SCHEMA]] specifications. 547 |
548 |549 | Furthermore, we identify specific keywords, that are not explicitly defined by JSON Schema, 550 | but are emphasized in this specification to support widespread usage. 551 |
552 |
555 | Across JSON Schema specifications, the $id
keyword identifies a schema resource
556 | with its canonical URI. The $id
MUST be present, and its value MUST represent
557 | a valid URI-reference as specified by the associated [[JSON-SCHEMA]] version.
558 |
560 | It is RECOMMENDED that the value of the $id
property match the id
561 | value in the credentialSchema
object of a verifiable credential, and
562 | that the value of the $id
is a dereferenceable URL.
563 |
568 | Across JSON Schema specifications, the $schema
keyword identifies a JSON Schema
569 | providing the feature set for a given JSON Schema specification. This property MUST be present
570 | in each schema. For example, when constructing a schema for Draft 2020-12 the value of
571 | the $schema
identifier MUST be https://json-schema.org/draft/2020-12/schema
.
572 |
577 | It is RECOMMENDED that all JSON Schemas include the optional title
property as defined in
578 | [[JSON-SCHEMA]].
579 |
584 | It is RECOMMENDED that all JSON Schemas include the optional description
property as
585 | defined in [[JSON-SCHEMA]].
586 |
591 | JSON Schemas SHOULD choose to include an optional lang
property that indicates the
592 | language tag for the values of the [=title=] and
593 | [=description=] properties defined in the JSON Schema. The value of this field MUST be a
594 | canonical unicode locale identifier.
595 | When absent, implementers MUST assume that the value of this property is `und`.
596 |
601 | JSON Schemas SHOULD choose to include an optional dir
property that indicates the
602 | base direction for the values of the [=title=] and [=description=] properties defined in
603 | the JSON Schema. The value of this property MUST be a text-direction. When absent, implementers
604 | MUST assume that the value of this property is "[=text-direction/auto=]".
605 |
607 | The text-directions are the following: 608 |
609 |
634 | The standard representation of [[JSON-SCHEMA]] uses the [[RFC8259]] JSON data interchange
635 | syntax with .json
as the file extension.
636 |
638 | Implementers MAY use OpenAPI Specification's [[[OPENAPIS-3.1.0]]] [[YAML]] representation
639 | of a [[JSON-SCHEMA]] with .yaml
as the file extension.
640 |
642 | YAML representations of JSON Schemas can only be used with credential schemas whose type is JsonSchema. 643 |
644 | 645 | An example [[JSON-SCHEMA]] using [[YAML]] is provided below. 646 | 647 |652 | This section details how to process Credential Schemas, which is commonly referred to 653 | as JSON schema validation. 654 |
655 |
656 | There are many open source implementations of [[JSON-SCHEMA]] validators across many common programming 657 | languages. The OpenJS Foundation maintains a list of implementations 658 | as a part of the JSON Schema official documentation. 659 |
660 |
661 | A common feature of a JSON Schema validator is the ability to detect the version of a JSON Schema document
662 | and select the validator for that specific version of [[JSON-SCHEMA]]. This is done by switching on the
663 | schema's $schema
property and picking the corresponding validator. Schemas without a
664 | $schema
property are not considered valid and MUST NOT be processed. Implementers
665 | SHOULD choose validators which possess this capability and are able to limit validation to the
666 | JSON Schema specifications supported by this document.
667 |
669 | Conformant implementers MUST support JSON Schema specification versions marked as required 670 | in the table defined in the JSON Schema specifications section 671 | of this document. Implementers MAY support JSON Schema specification versions not marked as 672 | required. 673 |
674 |677 | Credential Schemas MAY be packaged as verifiable credentials as defined 678 | by usage of the JsonSchemaCredential type. 679 | The credential containing a credential schema MAY be secured by using either an 680 | embedded or external proof as defined in 681 | Securing Verifiable Credentials. 682 |
683 |684 | Secured credentials representing credential schemas SHOULD first be validated 685 | according to the rules set out in the aforementioned securing specifications 686 | before proceeding with additional processing. 687 |
688 |689 | Provide examples for secured credential schemas. 690 |
691 |692 | Credential Schemas of type JsonSchema MAY 693 | be annotated with integrity information by adding the `digestSRI` property to the `credentialSchema` value 694 | in the Verifiable Credential which contains the schema, using the method specified in 695 | Integrity of Related Resources. 696 | It is RECOMMENDED that validation of the integrity of the schema be done before evaluation. 697 |
698 |699 | An example of such usage is provided below: 700 |
701 |
702 | {
703 | "@context": [
704 | "https://www.w3.org/ns/credentials/v2",
705 | "https://www.w3.org/ns/credentials/examples/v2"
706 | ],
707 | "id": "https://example.com/credentials/3733",
708 | "type": ["VerifiableCredential", "EmailCredential"],
709 | "issuer": "https://example.com/issuers/14",
710 | "issuanceDate": "2010-01-01T19:23:24Z",
711 | "credentialSubject": {
712 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
713 | "emailAddress": "subject@example.com"
714 | },
715 | "credentialSchema": {
716 | "id": "https://example.com/schemas/email.json",
717 | "type": "JsonSchema",
718 | "digestSRI": "sha384-dNwyy/Zs/YjPor8aoOgnaCqb+PH24QcNFxbxM1XoBOxdbgnpQcVaGYH8QunXww2U"
719 | }
720 | }
721 |
722 | 726 | Validation of a given credential against a schema is to be performed according 727 | to its associated [[JSON-SCHEMA]] specification. Validation MUST result in one of the following three possible 728 | outcomes: 729 |
730 |736 | Examples for the Success and Failure possible outcomes are provided below. 737 |
738 |741 | { 742 | "$id": "https://example.com/schemas/email.json", 743 | "$schema": "https://json-schema.org/draft/2020-12/schema", 744 | "title": "EmailCredential", 745 | "description": "EmailCredential using JsonSchema", 746 | "type": "object", 747 | "properties": { 748 | "credentialSubject": { 749 | "type": "object", 750 | "properties": { 751 | "emailAddress": { 752 | "type": "string", 753 | "format": "email" 754 | } 755 | }, 756 | "required": ["emailAddress"] 757 | } 758 | } 759 | } 760 |761 |
762 | Validation according to the spec [[JSON-SCHEMA-2020-12]] yields a Success result 763 | when applying it to the VC below. 764 |
765 |766 | { 767 | "@context": [ 768 | "https://www.w3.org/ns/credentials/v2", 769 | "https://www.w3.org/ns/credentials/examples/v2" 770 | ], 771 | "id": "https://example.com/credentials/3732", 772 | "type": ["VerifiableCredential", "EmailCredential"], 773 | "issuer": "https://example.com/issuers/14", 774 | "issuanceDate": "2010-01-01T19:23:24Z", 775 | "credentialSubject": { 776 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 777 | "emailAddress": "subject@example.com" 778 | }, 779 | "credentialSchema": { 780 | "id": "https://example.com/schemas/email.json", 781 | "type": "JsonSchema" 782 | } 783 | } 784 |785 |
789 | Validation according to the spec [[JSON-SCHEMA-2020-12]] yields a Failure result when 790 | applying it to the VC below. 791 |
792 |793 | { 794 | "@context": [ 795 | "https://www.w3.org/ns/credentials/v2", 796 | "https://www.w3.org/ns/credentials/examples/v2" 797 | ], 798 | "id": "https://example.com/credentials/3732", 799 | "type": ["VerifiableCredential", "EmailCredential"], 800 | "issuer": "https://example.com/issuers/14", 801 | "issuanceDate": "2010-01-01T19:23:24Z", 802 | "credentialSubject": { 803 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 804 | "emailAddress": "not an email" 805 | }, 806 | "credentialSchema": { 807 | "id": "https://example.com/schemas/email.json", 808 | "type": "JsonSchema" 809 | } 810 | } 811 |812 |
816 | Assuming that the implementer does not support [[?JSON-SCHEMA-2019-09]], an example of an Indeterminate 817 | evaluation is provided below. 818 |
819 |820 | { 821 | "$id": "https://example.com/schemas/email.json", 822 | "$schema": "https://json-schema.org/draft/2019-09/schema", 823 | "title": "EmailCredential", 824 | "description": "EmailCredential using JsonSchema", 825 | "type": "object", 826 | "properties": { 827 | "credentialSubject": { 828 | "type": "object", 829 | "properties": { 830 | "emailAddress": { 831 | "type": "string", 832 | "format": "email" 833 | } 834 | }, 835 | "required": [ 836 | "emailAddress" 837 | ] 838 | } 839 | } 840 | } 841 |842 |
843 | { 844 | "@context": [ 845 | "https://www.w3.org/ns/credentials/v2", 846 | "https://www.w3.org/ns/credentials/examples/v2" 847 | ], 848 | "id": "https://example.com/credentials/3732", 849 | "type": ["VerifiableCredential", "EmailCredential"], 850 | "issuer": "https://example.com/issuers/14", 851 | "issuanceDate": "2010-01-01T19:23:24Z", 852 | "credentialSubject": { 853 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 854 | "emailAddress": "not an email" 855 | }, 856 | "credentialSchema": { 857 | "id": "https://example.com/schemas/email.json", 858 | "type": "JsonSchema" 859 | } 860 | } 861 |862 |
868 | This section details some issues implementers of the specification 869 | may consider. 870 |
871 |874 | Implementers may wish to validate certain properties in a 875 | verifiable credential. To do this, credential schemas can be 876 | constructed to validate subsets of a credential's data. 877 |
878 |
879 | One example of such a construction would be to validate the presence of certain
880 | top-level properties in a verifiable credential. The following example
881 | demonstrates a schema which enforces that a credential issued against it
882 | has an validUntil
property and includes evidence
.
883 |
885 | { 886 | "$id": "validuntil-and-evidence-schema", 887 | "$schema": "https://json-schema.org/draft/2020-12/schema", 888 | "title": "Example validUntil and evidence schema", 889 | "description": "Schema requiring validUntil and evidence properties", 890 | "type": "object", 891 | "properties": { 892 | "validUntil": { 893 | "type": "object" 894 | }, 895 | "evidence": { 896 | "type": "object" 897 | } 898 | }, 899 | "required": ["validUntil", "evidence"] 900 | } 901 |902 |
906 | When using [[JSON-SCHEMA]], it is advised that implementers avoid
907 | setting the additionalProperties
to false. Doing
908 | so could inadvertently exclude properties in a credential from passing
909 | validation.
910 |
912 | As an example, consider a credential schema that is intended to validate
913 | the credentialSubject
property of a credential. It is common
914 | for the credentialSubject
property to include an id
,
915 | denoting the identifier the subject. Not including this id
property
916 | in a given schema would result in validation failure. The simple alternative
917 | is to avoid setting additionalProperties
to false.
918 |
920 | { 921 | "$id": "name-schema", 922 | "$schema": "https://json-schema.org/draft/2020-12/schema", 923 | "title": "Name schema", 924 | "description": "A schema capturing a human name", 925 | "type": "object", 926 | "properties": { 927 | "credentialSubject": { 928 | "type": "object", 929 | "properties": { 930 | "name": { 931 | "type": "object", 932 | "properties": { 933 | "firstName": { 934 | "type": "string" 935 | }, 936 | "lastName": { 937 | "type": "string" 938 | }, 939 | "additionalProperties": false 940 | }, 941 | "required": [ 942 | "firstName", 943 | "lastName" 944 | ] 945 | } 946 | } 947 | } 948 | } 949 | } 950 |951 |
955 | Versioning is not provided as an explicit feature of this specification. 956 | Implementers are advised to make backwards compatabile changes to schemas, should 957 | they be adjusted. Otherwise, it is advised that new credential schemas 958 | be created with unique identifiers to avoid processing conflicts. 959 |
960 |
964 | It is important to make sure that credential schemas have not been tampered with
965 | before processing. When making use of the JsonSchemaCredential2023
representation
966 | of a schema, the credential's associated integrity protection mechanism can be used to detect mutations
967 | of a credential schema via its digital signature.
968 |
970 | As an alternative, the aforementioned 971 | Integrity of Related Resources scheme may be used to provide content integrity 972 | protection, ensuring that the underlying credential schema resource has not been tampered with. 973 |
974 |978 | Credential schemas can be stored on any number of storage media such as a distributed 979 | ledger, traditional database, or decentralized file storage. For more robust availability 980 | guarantees, the same schema could be replicated across multiple file stores. 981 |
982 |
986 | A common use case is to include multiple schemas to validate against a single
987 | verifiable Credential. One such use case is to use the JSON Schema defined by the [[VC-DATA-MODEL-2.0]] in addition to a schema to validate a specific property in the credential, such as the credentialSubject
. Multiple schemas MAY be combined using native constructs from the [[JSON-SCHEMA]] specification, through use of properties such as oneOf
, anyOf
, or allOf
.
988 |
990 | An example of how to construct such a schema using the [[JSON-SCHEMA]] property
991 | allOf
is provided below, combining schemas for a verifiable credential,
992 | name, and email address:
993 |
995 | { 996 | "allOf": [ 997 | { 998 | "$ref": "https://raw.githubusercontent.com/w3c/vc-data-model/main/schema/verifiable-credential/verifiable-credential-schema.json" 999 | }, 1000 | { 1001 | "$id": "name-schema", 1002 | "$schema": "https://json-schema.org/draft/2020-12/schema", 1003 | "title": "Name schema", 1004 | "description": "A schema capturing a human name", 1005 | "type": "object", 1006 | "properties": { 1007 | "credentialSubject": { 1008 | "type": "object", 1009 | "properties": { 1010 | "name": { 1011 | "type": "object", 1012 | "properties": { 1013 | "firstName": { 1014 | "type": "string" 1015 | }, 1016 | "lastName": { 1017 | "type": "string" 1018 | }, 1019 | "additionalProperties": false 1020 | }, 1021 | "required": [ 1022 | "firstName", 1023 | "lastName" 1024 | ] 1025 | } 1026 | } 1027 | } 1028 | } 1029 | }, 1030 | { 1031 | "$id": "email-schema-1.0", 1032 | "$schema": "https://json-schema.org/draft/2020-12/schema", 1033 | "title": "Email schema", 1034 | "description": "A schema requiring an email address.", 1035 | "type": "object", 1036 | "properties": { 1037 | "credentialSubject": { 1038 | "type": "object", 1039 | "properties": { 1040 | "email": { 1041 | "type": "object", 1042 | "properties": { 1043 | "emailAddress": { 1044 | "type": "string", 1045 | "format": "email" 1046 | } 1047 | }, 1048 | "required": ["emailAddress"] 1049 | } 1050 | } 1051 | } 1052 | } 1053 | } 1054 | ] 1055 | } 1056 |1057 |
1058 | The example above is used to validate every property in the following 1059 | verifiable credential: 1060 |
1061 |1062 | { 1063 | "@context": ["https://www.w3.org/ns/credentials/v2"], 1064 | "id": "4995c86c-851f-43a6-9dd2-03dc891091fd", 1065 | "type": ["VerifiableCredential"], 1066 | "issuer": "did:example:1234", 1067 | "validFrom": "2023-01-01T05:05:05Z", 1068 | "credentialSubject": { 1069 | "firstName": "Alice", 1070 | "lastName": "Bobertson", 1071 | "emailAddress": "alice@bobertson.com" 1072 | }, 1073 | "credentialSchema": { 1074 | "id": "multiple-credential-schema-test", 1075 | "type": "JsonSchemaCredential" 1076 | } 1077 | } 1078 |1079 |
1080 | Using `allOf` when composing a JSON Schema can easily result in a schema for which all JSON documents will fail to validate. Such a situation may happen when multiple schemas reference the same property. Implementers are advised to test their schemas against a set of sample input documents before introducing any real world usage. Including sample input that suceeds and fails is considered a good practice. 1081 |
1082 |1086 | Validation against a [[JSON-SCHEMA]] may be confused with 1087 | validation 1088 | or verification 1089 | of a Verifiable Credential. A valid credential according to a [[JSON-SCHEMA]] refers 1090 | only to the structure of the claims comprising a Verifiable Credential. This idea of 1091 | validity does not imply anything about the validity of the Verifiable Credential itself. 1092 | It's possible for a Verifiable Credential to be considered valid by one verifier, 1093 | while another verifier would not consider it valid. 1094 |
1095 |
1099 | It is common to define a credential schema
that will be set for
1100 | Verifiable Credentials whose type
1101 | property contains a specific type
. In this scenario, it is advised to use the value
1102 | of the specific type
in the id
or in a name
or
1103 | description
property.
1104 | of a [[JSON-SCHEMA]].
1105 |
1107 | The example below illustrates this for EmailCredential
:
1108 |
1110 | { 1111 | "@context": [ 1112 | "https://www.w3.org/ns/credentials/v2", 1113 | "https://www.w3.org/ns/credentials/examples/v2" 1114 | ], 1115 | "id": "https://example.com/credentials/email-credential", 1116 | "type": ["VerifiableCredential", "EmailCredential"], 1117 | "issuer": "https://example.com/issuers/14", 1118 | "issuanceDate": "2010-01-01T19:23:24Z", 1119 | "credentialSubject": { 1120 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 1121 | "emailAddress": "tester@example.com" 1122 | }, 1123 | "credentialSchema": { 1124 | "id": "https://example.org/examples/email.json", 1125 | "type": "JsonSchema" 1126 | } 1127 | } 1128 |1129 |
1130 | { 1131 | "$id": "https://example.com/schemas/email.json", 1132 | "$schema": "https://json-schema.org/draft/2020-12/schema", 1133 | "title": "Email Credential", 1134 | "description": "Email Credential Schema for usage in JsonSchema", 1135 | "type": "object", 1136 | "properties": { 1137 | "credentialSubject": { 1138 | "type": "object", 1139 | "properties": { 1140 | "emailAddress": { 1141 | "type": "string", 1142 | "format": "email" 1143 | } 1144 | }, 1145 | "required": [ 1146 | "emailAddress" 1147 | ] 1148 | } 1149 | } 1150 | } 1151 |1152 |
1153 | It is important to note that a credential schema enables issuers to communicate how to process
1154 | the structure of data inside a verifiable credential, whereas the type
property of a verifiable credential
1155 | lets issuers communicate the semantics of the data. It is advised to associate all properties
1156 | that have a semantic mapping with a property in a credential schema.
1157 |
1163 | This section details the general privacy considerations and specific privacy 1164 | implications of deploying this specification into production environments. 1165 |
1166 |
1167 | When using the JsonSchemaCredential
1168 | type
, implementers are advised to review the
1169 | Privacy Considerations outlined in the [[VC-DATA-MODEL-2.0]].
1170 |
1174 | Data associated with schemas and verifiable credentials are susceptible 1175 | to privacy violations when shared. Personally identifying data, such as a 1176 | government-issued identifier, address, or name, can be used to track and correlate 1177 | entities. Even less overt personal data such as a birthdate or postal code has 1178 | the ability to result in correlation and de-anonymization. 1179 |
1180 |1181 | Implementers are strongly advised to avoid constructing schemas with any personally 1182 | identifiable information (PII). 1183 |
1184 |1185 | If such personally identifiable information is necessary in a schema, or a credential 1186 | schema, implementers are strongly advised to use mechanisms while storing and 1187 | transporting verifiable credentials that protect the data from those who should 1188 | not access it such as Transportation Layer Security (TLS) or other means of encrypting 1189 | the data whether in transit or at rest. 1190 |
1191 |1195 | Since schemas are immutable, they are highly cachable. 1196 | It is possible for verifiers to increase the privacy of the 1197 | holder whose verifiable credential is being checked by caching 1198 | schemas that have been fetched from remote servers. By caching the 1199 | content locally, less correlatable information can be inferred from 1200 | verifier-based access patterns on the schema. 1201 |
1202 |1206 | Schema resolution is the process of dereferencing a credential schema's identifier in order to fetch a 1207 | credential schema. 1208 |
1209 |1210 | Issuers can increase the privacy of holders by using 1211 | content distribution networks to reduce or eliminate requests for the 1212 | schemas from the issuer. Often, a request for a schema 1213 | will be served by an edge device and thus be faster and reduce the load 1214 | on the server as well as cloaking verifiers and holders 1215 | from issuers. 1216 |
1217 |1218 | Furthermore, the use of Oblivious HTTP 1219 | can prevent linkage of schema requests made by holders. Implementers are encouraged to allow configuration 1220 | of an Oblivious Relay Resource 1221 | for use during schema resolution. 1222 |
1223 |1224 | When using credential schema identifiers that are unique to the issued credential, it is possible 1225 | to correlate schema resolution of a credential with an IP address. Implementers are encouraged to prevent such 1226 | correlation by selecting identifiers which are shared among a class of credentials. 1227 |
1228 |1232 | Data minimization refers to the principle of sharing the minimum necessary data for any given data request, such 1233 | as a verifier requesting one or more verifiable credentials from 1234 | a holder. 1235 |
1236 |
1237 | When using a credential schema with a credential that supports selective disclosure, it may be
1238 | possible for a verifier to deduce additional attributes that would be available but were not presented
1239 | when verifying a credential from a holder. To mitigate data leakage, holders may
1240 | choose to reject verification requests that could disclose such additional attributes, or, if the capability is
1241 | available, to selectively disclose properties in the associated credential schema. To enable this functionality,
1242 | issuers can use selective disclosure schemes when creating credential schemas using
1243 | the JsonCredentialSchema
type
.
1244 |
1250 | There are a number of security considerations that implementers should be 1251 | aware of when processing data described by this specification. Ignoring or 1252 | not understanding the implications of this section can result in 1253 | security vulnerabilities. 1254 |
1255 |
1256 | When using the JsonSchemaCredential
1257 | type
, implementers are advised to review the
1258 | Security Considerations outlined in the [[VC-DATA-MODEL-2.0]].
1259 |
1263 | It is possible for a schema to become authoritative, such as a schema
1264 | provided by a recognized industry group like a consortium of financial
1265 | companies. To avoid confusion as to the authorship of credential schemas,
1266 | it is advised that they be packaged as verifiable credentials using the
1267 | JsonSchemaCredential
type
.
1268 |
1274 | There are a number of accessibility considerations implementers should be 1275 | aware of when processing data described in this specification. As with any web 1276 | standards or protocols implementation, ignoring accessibility issues makes 1277 | this information unusable to a large subset of the population. It is important 1278 | to follow accessibility guidelines and standards, such as [[WCAG21]], to ensure 1279 | all people, regardless of ability, can make use of this data. This is 1280 | especially important when establishing systems utilizing cryptography, which 1281 | have historically created problems for assistive technologies. 1282 |
1283 |1284 | JSON Schemas are designed to be a machine-readable format which provides static 1285 | validation. As such, human readability is a secondary concern. When using a 1286 | verifiable credential to represent a schema, we recommend following the 1287 | guidance in the VC Data Model. 1288 |
1289 |1293 | JSON Schemas are JSON text intended primarily for machines to read, since they 1294 | are used for strict static validation of data. Language and text direction concerns 1295 | are addressed by the noted specification documents 1296 | for JSON Schema itself. 1297 |
1298 |1299 | When using a verifiable credential to represent a schema, we recommend following the 1300 | guidance in the VC Data Model. 1301 |
1302 |JsonSchema
1310 | The media type application/schema+json
, as defined in
1311 | [[JSON-SCHEMA]], SHOULD be used when transmitting a [[JSON-SCHEMA]] expressed
1312 | as JSON over HTTP. Clients receiving [[JSON-SCHEMA]] files over HTTP MAY accept content
1313 | using either the application/schema+json
media type or the
1314 | application/json
media type as defined in [[JSON]].
1315 |
1317 | When using the JsonSchema type with a [[YAML]]
1318 | representation of a [[JSON-SCHEMA]], defined by [[[OPENAPIS-3.1.0]]], the types
1319 | application/openapi+yaml
or application/yaml
MAY be used.
1320 |
JsonSchemaCredential
1325 | The media types application/vc
, application/vc+jwt
, or
1326 | application/vc+sd-jwt
, as defined in the [[VC-DATA-MODEL-2.0]],
1327 | [[VC-JOSE-COSE]], or [[SD-JWT]] specification, respectively, SHOULD be used when
1328 | transmitting a [[JSON-SCHEMA]] represented as a verifiable credential with the
1329 | JsonSchemaCredential type. Clients receiving credential schemas
1330 | files over HTTP MAY accept content using any of these types.
1331 |
1338 | This section contains the substantive changes that have been made to 1339 | this specification over time. 1340 |
1341 |2 | The following terms are used to describe concepts in this specification. 3 |
4 | 5 |did:example:123456abcdef
.
36 |