├── .pr-preview.json ├── w3c.json ├── LICENSE.md ├── README.md ├── common.js └── index.html /.pr-preview.json: -------------------------------------------------------------------------------- 1 | { 2 | "src_file": "index.html", 3 | "type": "respec" 4 | } 5 | -------------------------------------------------------------------------------- /w3c.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": [ 3 | "98922" 4 | ], 5 | "contacts": [ 6 | "ashimura" 7 | ], 8 | "shortName": "vc-imp-guide", 9 | "repo-type": "note" 10 | } 11 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | All documents in this Repository are licensed by contributors 2 | under the 3 | [W3C Software and Document License](https://www.w3.org/Consortium/Legal/copyright-software). 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # W3C Verifiable Claims Working Group - Verifiable Credentials Implementation Guideline 1.0 2 | 3 | [HTML rendered version](https://w3c.github.io/vc-imp-guide/) 4 | 5 | ### Other Verifiable Claims github repos 6 | * [Data Model](https://github.com/w3c/vc-data-model) 7 | * [Test Suite](https://github.com/w3c/vc-test-suite) 8 | * [Use Cases](https://github.com/w3c/vc-use-cases) 9 | -------------------------------------------------------------------------------- /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 | "REST": { 9 | title: "Architectural Styles and the Design of Network-based Software Architectures", 10 | date: "2000", 11 | href: "http://www.ics.uci.edu/~fielding/pubs/dissertation/", 12 | authors: [ 13 | "Fielding, Roy Thomas" 14 | ], 15 | publisher: "University of California, Irvine." 16 | }, 17 | "VC-USECASES": { 18 | title: "Verifiable Claims Use Cases", 19 | href: "https://www.w3.org/TR/verifiable-claims-use-cases/", 20 | authors: [ 21 | "Shane McCarron", 22 | "Daniel Burnett", 23 | "Gregg Kellogg", 24 | "Brian Sletten", 25 | "Manu Sporny" 26 | ], 27 | status: "FPWD", 28 | publisher: "Verifiable Claims Working Group" 29 | }, 30 | "VC-STATUS-REGISTRY": { 31 | title: "Verifiable Credentials Status Scheme Registry", 32 | href: "https://w3c-ccg.github.io/vc-status-registry/", 33 | authors: [ 34 | "Manu Sporny" 35 | ], 36 | status: "CG-DRAFT", 37 | publisher: "Credentials Community Group" 38 | }, 39 | "LD-PROOFS": { 40 | title: "Linked Data Proofs", 41 | href: "https://w3c-dvcg.github.io/ld-proofs/", 42 | authors: [ 43 | "Manu Sporny", 44 | "Dave Longley" 45 | ], 46 | status: "CG-DRAFT", 47 | publisher: "Digital Verification Community Group" 48 | }, 49 | "LD-SIGNATURES": { 50 | title: "Linked Data Signatures", 51 | href: "https://w3c-dvcg.github.io/ld-signatures/", 52 | authors: [ 53 | "Manu Sporny", 54 | "Dave Longley" 55 | ], 56 | status: "CG-DRAFT", 57 | publisher: "Digital Verification Community Group" 58 | }, 59 | // aliases to known references 60 | "HTTP-SIGNATURES": { 61 | aliasOf: "http-signatures" 62 | }, 63 | "MACAROONS": { 64 | title: 'Macaroons', 65 | // TODO: create spec 66 | href: 'http://macaroons.io/', 67 | authors: ['Arnar Birgisson', 'Joe Gibbs Politz', 'Úlfar Erlingsson', 68 | 'Ankur Taly', 'Michael Vrable', 'Mark Lentczner'], 69 | status: 'unofficial', 70 | publisher: 'Credentials Community Group' 71 | }, 72 | 'OPEN-BADGES': { 73 | title: 'Open Badges', 74 | href: 'https://github.com/openbadges/openbadges-specification', 75 | authors: ['Brian Brennan', 'Mike Larsson', 'Chris McAvoy', 76 | 'Nate Otto', 'Kerri Lemoie'], 77 | status: 'BA-DRAFT', 78 | publisher: 'Badge Alliance Standard Working Group' 79 | }, 80 | 'RDF-NORMALIZATION': { 81 | title: 'RDF Dataset Normalization', 82 | href: 'http://json-ld.github.io/normalization/spec/', 83 | authors: ['Dave Longley', 'Manu Sporny'], 84 | status: 'CG-DRAFT', 85 | publisher: 'Credentials W3C Community Group' 86 | }, 87 | 'DEMOGRAPHICS': { 88 | title: 'Simple Demographics Often Identify People Uniquely', 89 | href: 'http://dataprivacylab.org/projects/identifiability/paper1.pdf', 90 | authors: ['Latanya Sweeney'], 91 | publisher: 'Data Privacy Lab' 92 | } 93 | } 94 | }; 95 | 96 | 97 | 98 | // We should be able to remove terms that are not actually 99 | // referenced from the common definitions 100 | // 101 | // the termlist is in a block of class "termlist", so make sure that 102 | // has an ID and put that ID into the termLists array so we can 103 | // interrogate all of the included termlists later. 104 | var termNames = [] ; 105 | var termLists = [] ; 106 | var termsReferencedByTerms = [] ; 107 | 108 | function restrictReferences(utils, content) { 109 | "use strict"; 110 | var base = document.createElement("div"); 111 | base.innerHTML = content; 112 | 113 | // New new logic: 114 | // 115 | // 1. build a list of all term-internal references 116 | // 2. When ready to process, for each reference INTO the terms, 117 | // remove any terms they reference from the termNames array too. 118 | $.each(base.querySelectorAll("dfn"), function(i, item) { 119 | var $t = $(item) ; 120 | var titles = $t.getDfnTitles(); 121 | var dropit = false; 122 | // do we have an omitTerms 123 | if (window.hasOwnProperty("omitTerms")) { 124 | // search for a match 125 | $.each(omitTerms, function(j, term) { 126 | if (titles.indexOf(term) !== -1) { 127 | dropit = true; 128 | } 129 | }); 130 | } 131 | // do we have an includeTerms 132 | if (window.hasOwnProperty("includeTerms")) { 133 | var found = false; 134 | // search for a match 135 | $.each(includeTerms, function(j, term) { 136 | if (titles.indexOf(term) !== -1) { 137 | found = true; 138 | } 139 | }); 140 | if (!found) { 141 | dropit = true; 142 | } 143 | } 144 | if (dropit) { 145 | $t.parent().next().remove(); 146 | $t.parent().remove(); 147 | } else { 148 | var n = $t.makeID("dfn", titles[0]); 149 | if (n) { 150 | termNames[n] = $t.parent() ; 151 | } 152 | } 153 | }); 154 | 155 | var $container = $(".termlist",base) ; 156 | var containerID = $container.makeID("", "terms") ; 157 | termLists.push(containerID) ; 158 | 159 | return (base.innerHTML); 160 | } 161 | // add a handler to come in after all the definitions are resolved 162 | // 163 | // New logic: If the reference is within a 'dl' element of 164 | // class 'termlist', and if the target of that reference is 165 | // also within a 'dl' element of class 'termlist', then 166 | // consider it an internal reference and ignore it. 167 | 168 | require(["core/pubsubhub"], function(respecEvents) { 169 | "use strict"; 170 | respecEvents.sub('end', function(message) { 171 | if (message === 'core/link-to-dfn') { 172 | // all definitions are linked; find any internal references 173 | $(".termlist a.internalDFN").each(function() { 174 | var $r = $(this); 175 | var id = $r.attr('href'); 176 | var idref = id.replace(/^#/,"") ; 177 | if (termNames[idref]) { 178 | // this is a reference to another term 179 | // what is the idref of THIS term? 180 | var $def = $r.closest('dd') ; 181 | if ($def.length) { 182 | var $p = $def.prev('dt').find('dfn') ; 183 | var tid = $p.attr('id') ; 184 | if (tid) { 185 | if (termsReferencedByTerms[tid]) { 186 | termsReferencedByTerms[tid].push(idref); 187 | } else { 188 | termsReferencedByTerms[tid] = [] ; 189 | termsReferencedByTerms[tid].push(idref); 190 | } 191 | } 192 | } 193 | } 194 | }) ; 195 | 196 | // clearRefs is recursive. Walk down the tree of 197 | // references to ensure that all references are resolved. 198 | var clearRefs = function(theTerm) { 199 | if ( termsReferencedByTerms[theTerm] ) { 200 | $.each(termsReferencedByTerms[theTerm], function(i, item) { 201 | if (termNames[item]) { 202 | delete termNames[item]; 203 | clearRefs(item); 204 | } 205 | }); 206 | } 207 | // make sure this term doesn't get removed 208 | if (termNames[theTerm]) { 209 | delete termNames[theTerm]; 210 | } 211 | }; 212 | 213 | // now termsReferencedByTerms has ALL terms that 214 | // reference other terms, and a list of the 215 | // terms that they reference 216 | $("a.internalDFN").each(function () { 217 | var $item = $(this) ; 218 | var t = $item.attr('href'); 219 | var r = t.replace(/^#/,"") ; 220 | // if the item is outside the term list 221 | if ( ! $item.closest('dl.termlist').length ) { 222 | clearRefs(r); 223 | } 224 | }); 225 | 226 | // delete any terms that were not referenced. 227 | /* 228 | Object.keys(termNames).forEach(function(term) { 229 | var $p = $("#"+term) ; 230 | if ($p) { 231 | var tList = $p.getDfnTitles(); 232 | $p.parent().next().remove(); 233 | $p.parent().remove() ; 234 | tList.forEach(function( item ) { 235 | console.log("CHECKING ITEM", item, respecConfig); 236 | if (respecConfig.definitionMap[item]) { 237 | delete respecConfig.definitionMap[item]; 238 | } 239 | }); 240 | } 241 | });*/ 242 | } 243 | }); 244 | }); 245 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |108 | This document provides implementation guidance for Verifiable Credentials. 109 |
110 |114 | Comments regarding this document are welcome. Please file issues 115 | directly on GitHub, 116 | or send them to 117 | public-vc-comments@w3.org 118 | (subscribe, 119 | archives). 120 |
121 |128 | This guide provides some examples and resources for implementing 129 | protocols which make use of verifiable credentials, beyond those available in the core specification. 130 |
131 |132 | It may be useful to first familiarize yourself with the official 133 | Use Cases document, 134 | which offers a concise collection of examples of Verifiable Credentials 135 | as they may appear in everyday life, and how they may be used. 136 |
137 |138 | The data model specification 139 | contains the technical details about verifiable credentials. However, the 140 | data model specification does not specify any protocols for using 141 | verifiable credentials, nor any proof formats or additional 142 | identifiers upon which such protocols may depend. 143 |
144 |
150 | When expressing statements about a specific entity, such as a person, product,
151 | or organization, it is often useful to have an identifier for it so that others
152 | can express statements about the same thing. The verifiable credentials
153 | data model specification
154 | contains numerous examples where the identifier is a
155 | decentralized identifier,
156 | also known as a DID. An example of a DID is did:example:123456abcdef.
157 |
159 | There is currently a proposed charter for a W3C 160 | Decentralized Identifier Working Group, which will put DIDs on track to 161 | become a W3C standard. 162 |
163 |164 | As of the publication of the verifiable credentials 165 | data model specification, 166 | DIDs are not necessary for verifiable credentials to be useful. 167 | Specifically, verifiable credentials do not depend on DIDs and 168 | DIDs do not depend on verifiable credentials. However, it is 169 | expected that many verifiable credentials will use DIDs and that 170 | software libraries implementing the 171 | data model specification 172 | will benefit from knowing how to resolve DIDs. DID-based URLs may 173 | be used to express identifiers associated with subjects, issuers, 174 | holders, credential status lists, cryptographic keys, and other 175 | machine-readable information associated with a verifiable credential. 176 |
177 | 178 |194 | Verification is the process a verifier or holder performs 195 | when presented with a verifiable presentation or 196 | verifiable credential. Verification includes checking the 197 | presented item against the core 198 | data model, and may also include validating the provided proof section and 199 | checking the item's status. 200 |
201 | 202 |206 | Conformant tooling that processes Verifiable Credentials will ensure that 207 | the core data model is verified when processing credentials. 208 |
209 |215 | There are many data verification languages, the following approach is one 216 | that should work for most use cases. 217 |
218 |222 | Protecting the integrity of content is an important component of verification. 223 | Verifiers need to have confidence that the content they rely on to 224 | verify credentials doesn't change without their knowledge. This content 225 | may include data schemas, identifiers, public keys, etc. 226 |
227 |228 | There are a number of ways to provide content integrity protection. A few of 229 | these are described in greater detail below. 230 |
231 |235 | Hashlink URLs 236 | can be used to provide content integrity for links to external resources. 237 |
238 |242 | A verifiable data registry can also provide content integrity protection. 243 | One example of a verifiable data registry which provides content 244 | integrity protection is a distributed ledger. 245 |
246 |253 | There are at least two different cases to consider where an entity 254 | wants to dispute a credential issued by an issuer: 255 |
256 | 257 |address property is incorrect or out of date.
261 |
270 | The mechanism for issuing a DisputeCredential is the same as
271 | for a regular credential, except that the credentialSubject
272 | identifier in the DisputeCredential property is the identifier of
273 | the disputed credential.
274 |
277 | For example, if a credential with an identifier of
278 | https://example.org/credentials/245 is disputed, an entity
279 | can issue one of the credentials shown below. In the first example, the
280 | subject might present this to the verifier along with the disputed
281 | credential. In the second example, the entity might publish the
282 | DisputeCredential in a public venue to make it known that the
283 | credential is disputed.
284 |
287 | {
288 | "@context": [
289 | "https://www.w3.org/2018/credentials/v1",
290 | "https://www.w3.org/2018/credentials/examples/v1"
291 | ],
292 | "id": "http://example.com/credentials/123",
293 | "type": ["VerifiableCredential", "DisputeCredential"],
294 | "credentialSubject": {
295 | "id": "http://example.com/credentials/245",
296 | "currentStatus": "Disputed",
297 | "statusReason": {
298 | "@value": "Address is out of date",
299 | "@language": "en"
300 | },
301 | },
302 | "issuer": "https://example.com/people#me",
303 | "issuanceDate": "2017-12-05T14:27:42Z",
304 | "proof": { ... }
305 | }
306 |
307 |
308 |
309 | {
310 | "@context": "https://w3id.org/credentials/v1",
311 | "id": "http://example.com/credentials/321",
312 | "type": ["VerifiableCredential", "DisputeCredential"],
313 | "credentialSubject": {
314 | "id": "http://example.com/credentials/245",
315 | "currentStatus": "Disputed",
316 | "statusReason": {
317 | "@value": "Credential contains disputed statements",
318 | "@language": "en"
319 | },
320 | "disputedClaim": {
321 | "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
322 | "address": "Is Wrong"
323 | }
324 | },
325 | "issuer": "https://example.com/people#me",
326 | "issuanceDate": "2017-12-05T14:27:42Z",
327 | "proof": { ... }
328 | }
329 |
330 |
331 | 332 | In the above verifiable credential, the issuer is claiming that 333 | the address in the disputed verifiable credential is wrong. For example, 334 | the subject might wrongly be claiming to have the same address as that of 335 | the issuer. 336 |
337 |338 | If a credential does not have an identifier, a content-addressed 339 | identifier can be used to identify the disputed credential. Similarly, 340 | content-addressed identifiers can be used to uniquely identify individual 341 | claims. 342 |
343 |
349 | Verifiable credentials may be presented to a verifier by
350 | using a verifiable presentation. A verifiable presentation can
351 | be targeted to a specific verifier by using a Linked Data Proof
352 | that includes a domain and challenge. This also
353 | helps prevent a verifier from reusing a verifiable presentation
354 | as their own.
355 |
358 | The domain value can be any string or URI, and the
359 | challenge should be a randomly generated string.
360 |
363 | The following sample verifiable presentation is for authenticating to
364 | a website, https://example.com.
365 |
368 | {
369 | "@context": [
370 | "https://www.w3.org/2018/credentials/v1"
371 | ],
372 | "type": "VerifiablePresentation,
373 | "verifiableCredential": { ... },
374 | "proof": {
375 | "type": "Ed25519Signature2018",
376 | "created": "2019-08-13T15:09:00Z",
377 | "challenge": "d1b23d3...3d23d32d2",
378 | "domain": "https://example.com",
379 | "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..uyW7Hv
380 | VOZ8QCpLJ63wHode0OdgWjsHfJ0O8d8Kfs55dMVEg3C1Z0bYUGV49s8IlTbi3eXsNvM63n
381 | vah79E-lAg",
382 | "proofPurpose": "authentication"
383 | }
384 | }
385 |
386 |
387 | 395 | The Verifiable Credentials Data Model is designed around an open world 396 | assumption, meaning that any entity can say anything about another entity. 397 | This approach enables permissionless innovation; there is no centralized 398 | registry or authority through which an extension author must register 399 | themselves nor the specific data models and vocabularies they create. 400 |
401 | 402 |403 | Instead, credential data model authors are expected to use machine-readable 404 | vocabularies through the use of [LINKED-DATA]. This implementation guide 405 | provides examples for how to express data models using a data format that 406 | is popular with software developers and web page authors called [JSON-LD]. This 407 | data format provides features that enable authors to express their data models 408 | in idiomatic JSON while also ensuring that their vocabulary terms are 409 | unambigiously understood, even by software that does not implement 410 | JSON-LD processing. 411 |
412 | 413 |414 | The Verifiable Credentials data model also uses a graph-based data model, 415 | which allows authors to model both simple relationships that describe 416 | one or more attributes for a single entity and complex multi-entity 417 | relationships. 418 |
419 | 420 |421 | The rest of this section describes how to author extensions that build on 422 | the Verifiable Credentials Data Model. 423 |
424 | 425 |429 | We expect the most common extensions to the Verifiable Credentials Data Model 430 | to be new credential types. Whenever someone has something to say about one or 431 | more entities and they want their authorship to be verifiable, they should use 432 | a Verifiable Credential. Sometimes there may be an existing credential type, 433 | that someone else has created, that can be reused to make the statements they 434 | want to make. However, there are often cases where new credential types are 435 | needed. 436 |
437 | 438 |439 | New credential types can be created by following a few steps. This guide will 440 | also walk you through creating an example new credential type. At a high level, 441 | the steps to follow are: 442 |
443 | 444 |
460 | So, let's walk through creating a new credential type which we will
461 | call ExampleAddressCredential. The purpose of this credential
462 | will be to express a person's postal address.
463 |
468 | First, we must design a data model for our new credential type. We know that 469 | we will need to be able to express the basics of a postal address, things 470 | like a person's city, state, and zipcode. Of course, those items are quite 471 | US centric, so we should consider internationalizing those terms. But before 472 | we go further, since we're using [LINKED-DATA] vocabularies, there is a good 473 | chance that commonly known concepts may already have a vocabulary that someone 474 | else has created that we can leverage. 475 |
476 | 477 |478 | If we are going to use someone else's vocabulary, we will want to make sure it 479 | is stable and unlikely to change in any significant way. There may even be 480 | technologies that we can make use of that store immutable vocabularies that 481 | we can reference, but those are not the focus of this example. Here we will 482 | rely on the inertia that comes from a very popularly used vocabulary on the 483 | Web, schema.org. It turns out that this vocabulary has just what we need; it 484 | has already modeled a postal address and even has examples for how to express 485 | it using JSON-LD. 486 |
487 | 488 |489 | Using the schema.org vocabulary and JSON-LD we can express a person's address 490 | like so: 491 |
492 | 493 |
494 | {
495 |
496 | "@context": [
497 | "http://schema.org"
498 | ],
499 | "type": "Person",
500 | "address": {
501 | "type": "PostalAddress",
502 | "streetAddress": "123 Main St."
503 | "addressLocality": "Blacksburg",
504 | "addressRegion": "VA",
505 | "postalCode": "24060",
506 | "addressCountry": "US"
507 | }
508 | }
509 |
510 |
511 |
512 | Note the above @context key in the JSON. This @context
513 | refers to a machine-readable file (also expressed in JSON) that provides
514 | term definitions [JSON-LD]. A term definition maps a key or type used in the
515 | JSON, such as address or PostalAddress, to a globally
516 | unique identifier: a URL.
517 |
520 | This ensures that when software sees the @context
521 | http://schema.org, that it will interpret the the keys and types in the
522 | JSON in a globally consistent way, without requiring developers to use full URLs
523 | in the JSON or in the code that may traverse it. As long as the software is
524 | aware of the specific @context used (or if it uses JSON-LD
525 | processing to transform it to some other known @context), then it
526 | will understand the context in which the JSON was written and meant to
527 | be understood. The use of @context also allows [JSON-LD] keywords
528 | such as @type to be aliased to the simpler type as
529 | is done in the above example.
530 |
533 | Note that we could also express the JSON using full URLs, if we want to avoid 534 | using @context. Here is what the example would look like if we did 535 | that: 536 |
537 | 538 |
539 | {
540 | "@type": "http://schema.org/Person",
541 | "http://schema.org/address": {
542 | "@type": "http://schema.org/PostalAddress",
543 | "http://schema.org/streetAddress": "123 Main St."
544 | "http://schema.org/addressLocality": "Blacksburg",
545 | "http://schema.org/addressRegion": "VA",
546 | "http://schema.org/postalCode": "24060",
547 | "http://schema.org/addressCountry": "US"
548 | }
549 | }
550 |
551 |
552 |
553 | While this form is an acceptable way to express the information such that it is
554 | unambiguous, many software developers would prefer to use more idiomatic JSON.
555 | The use of @context enables idiomatic JSON without losing global
556 | consistency and without the need for a centralized registry or authority for
557 | creating extensions. Note that @context can also have more than
558 | one value. In this case, a JSON array is used to express multiple values, where
559 | each value references another context that defines terms. Using this mechanism
560 | we can first bring in the terms defined in the Verifiable Credentials Data Model
561 | specification and then bring in the terms defined by schema.org:
562 |
565 | {
566 |
567 | "@context": [
568 | "https://www.w3.org/2018/credentials/v1",
569 | "http://schema.org"
570 | ],
571 | ...
572 | "credentialSubject": {
573 | "type": "Person",
574 | "address": {
575 | "type": "PostalAddress",
576 | "streetAddress": "123 Main St."
577 | "addressLocality": "Blacksburg",
578 | "addressRegion": "VA",
579 | "postalCode": "24060",
580 | "addressCountry": "US"
581 | }
582 | },
583 | ...
584 | }
585 |
586 |
587 |
588 | Note, however, that each context might have a different definition for
589 | the same term, e.g., the JSON key address might map to a different
590 | URL in each context. By default, [JSON-LD] allows terms in a
591 | @context to be redefined using a last term wins
592 | order. While these changes can be safely dealt with by using JSON-LD
593 | processing, we want to lower the burden on consumers of Verifiable Credentials.
594 | We want consumer software to be able to make assumptions about the meaning of
595 | terms by only having to read and understand the string value associated with
596 | the @context key. We don't want them to have to worry about terms
597 | being redefined in unexpected ways. That way their software can inspect only
598 | the @context values and then be hard coded to understand the
599 | meaning of the terms.
600 |
603 | In order to prevent term redefinition, the [JSON-LD] @protected
604 | feature must be applied to term definitions in the @context. All
605 | terms in the core Verifiable Credentials @context are
606 | already protected in this way. The only time that an existing term is allowed
607 | to be redefined is if the new definition is scoped underneath another new term
608 | that is defined in a context. This matches developer expectations and
609 | ensures that consumer software has strong guarantees about the semantics of the
610 | data it is processing; it can be written such that it is never confused about
611 | the definition of a term. Note that consumers must determine their own risk
612 | profile for how to handle any credentials their software processes that include
613 | terms that it does not understand.
614 |
619 | Given the above, there is at least one reason why we don't want to use
620 | the schema.org context: it is designed to be very flexible and thus
621 | does not use the @protected feature. There are a few additional
622 | reasons we want to create our own [JSON-LD] context though. First, the
623 | schema.org context does not define our new credential type:
624 | ExampleAddressCredential. Second, it is not served via a secure
625 | protocol (e.g., https); rather, it uses http. Note that this
626 | is less of a concern than it may seem, as it is recommended that all Verifiable
627 | Credential consumer software hard code the @context values it
628 | understands and not reach out to the Web to fetch them. Lastly, it is a very
629 | large context, containing many more term definitions than are necessary for our
630 | purposes.
631 |
634 | So, we will create our own [JSON-LD] context that expresses just those term 635 | definitions that we need for our new credential type. Note that this does not 636 | mean that we must mint new URLs; we can still reuse the schema.org vocabulary 637 | terms. All we are doing is creating a more concise and targeted context. Here's 638 | what we'll need in our context: 639 |
640 | 641 |
642 | {
643 | "@version": 1.1,
644 | "@protected": true,
645 |
646 | "ExampleAddressCredential":
647 | "https://example.org/ExampleAddressCredential",
648 |
649 | "Person": {
650 | "@id": "http://schema.org/Person",
651 | "@context": {
652 | "@version": 1.1,
653 | "@protected": true,
654 |
655 | "address": "http://schema.org/address"
656 | }
657 | },
658 | "PostalAddress": {
659 | "@id": "http://schema.org/PostalAddress",
660 | "@context": {
661 | "@version": 1.1,
662 | "@protected": true,
663 |
664 | "streetAddress": "http://schema.org/streetAddress",
665 | "addressLocality": "http://schema.org/addressLocality",
666 | "addressRegion": "http://schema.org/addressRegion",
667 | "postalCode": "http://schema.org/postalCode",
668 | "addressCountry": "http://schema.org/addressCountry"
669 | }
670 | }
671 | }
672 |
673 |
674 | 675 | The above context defines a term for our new credential type 676 | ExampleAddressCredential, mapping it to the URL 677 | https://example.org/ExampleAddressCredential. We could have also 678 | chosen a URI like urn:private-example:ExampleAddressCredential, but 679 | this approach would not allow us to serve up a Web page to describe it, if we 680 | so desire. The context also defines the terms for types Person and 681 | PostalAddress, mapping them to their schema.org vocabulary URLs. 682 | Furthermore, when those types are used, it also defines protected terms for 683 | each of them via a scoped context, mapping terms like address 684 | and streetAddress to their schema.org vocabulary URLs. For more 685 | information on how to write a JSON-LD context or scoped contexts, see 686 | the [JSON-LD] specification. 687 |
688 | 689 |692 | Now that we have a [JSON-LD] context, we must give it a URL. Technically 693 | speaking, we could just use a URI, for example, a private URN such as 694 | urn:private-example:my-extension. However, if we want people to be 695 | able to read and discover it on the Web, we should give it a URL like 696 | https://example.org/example-address-credential-context/v1. 697 |
698 | 699 |700 | When this URL is dereferenced, it should return 701 | application/ld+json by default, to allow JSON-LD processors to process 702 | the context. However, if a user agent requests HTML, it should return 703 | human readable text that explains, to humans, what the term definitions are and 704 | what they map to. Since we're reusing an existing vocabulary, schema.org, we 705 | can also simply link to the definitions of the meaning of our types and terms 706 | via their website. If we had created our own new vocabulary terms, we would 707 | describe them on our own site, ideally including machine readable Information 708 | as well. 709 |
710 | 711 |714 | Now we're ready for our context to be used by anyone who 715 | wishes to issue an ExampleAddressCredential! 716 |
717 | 718 |
719 | {
720 |
721 | "@context": [
722 | "https://www.w3.org/2018/credentials/v1",
723 | "https://example.org/example-address-credential-context/v1"
724 | ],
725 | "id": "https://example.org/credentials/1234",
726 | "type": "ExampleAddressCredential",
727 | "issuer": "https://example.org/people#me",
728 | "issuanceDate": "2017-12-05T14:27:42Z",
729 | "credentialSubject": {
730 | "id": "did:example:1234",
731 | "type": "Person",
732 | "address": {
733 | "type": "PostalAddress",
734 | "streetAddress": "123 Main St."
735 | "addressLocality": "Blacksburg",
736 | "addressRegion": "VA",
737 | "postalCode": "24060",
738 | "addressCountry": "US"
739 | }
740 | },
741 | "proof": { ... }
742 | }
743 |
744 |
745 | 746 | Note that writing this new credential type requires permission from no one, 747 | you must only adhere to the above referenced standards. 748 |
749 | 750 |755 | The JSON-LD Context declaration mechanism is used by implementations to 756 | signal the context in which the data transmission is happening to consuming 757 | applications: 758 |
759 | 760 |
761 | {
762 |
763 | "@context": [
764 | "https://www.w3.org/2018/credentials/v1",
765 | "https://www.w3.org/2018/credentials/examples/v1"
766 | ],
767 | "id": "http://example.edu/credentials/1872",
768 | ...
769 |
770 |
771 |
772 | Extension authors are urged to publish two types of information at the
773 | context URLs. The first type of information is for machines, and is the
774 | machine-readable JSON-LD Context. The second type of information is for
775 | humans, and should be an HTML document. It is suggested that the default
776 | mode of operation is to serve the machine-readable JSON-LD Context as that is
777 | the primary intended use of the URL. If content-negotiation is supported,
778 | requests for text/html should result in a human readable document.
779 | The human readable document should at least contain usage information for the
780 | extension, such as the expected order of URLs associated with the
781 | @context property, specifications that elaborate on the extension,
782 | and examples of typical usage of the extension.
783 |
793 | The verifiable credentials 794 | data model is designed to be 795 | proof format agnostic. The 796 | specification does not normatively require any particular digital proof or 797 | signature format. While the data model is the canonical representation of a 798 | verifiable credential or verifiable presentation, the proving 799 | mechanisms for these are often tied to the syntax used in the transmission of 800 | the document between parties. As such, each proofing mechanism has to specify 801 | whether the validation of the proof is calculated against the state of the 802 | document as transmitted, against the transformed data model, or against another 803 | form. At the time of publication, at least two proof formats are being actively 804 | utilized by implementers, and the Working Group felt that documenting what these 805 | proof formats are and how they are being used would be beneficial to other 806 | implementers. 807 |
808 |809 | This guide provides tables in section Benefits of JWTs and 810 | section Benefits of JSON-LD and LD-Proofs that compare three 811 | syntax and proof format ecosystems; JSON+JWTs, JSON-LD+JWTs, and 812 | JSON-LD+LD-Proofs. 813 |
814 |815 | Because the Verifiable Credentials Data Model is extensible, and agnostic to any 816 | particular proof format, the specification and use of additional proof formats 817 | is supported. 818 |
819 |823 | The Verifiable Credentials Data Model is designed to be compatible with a 824 | variety of existing and emerging syntaxes and digital proof formats. Each 825 | approach has benefits and drawbacks. The following table is intended to 826 | summarize a number of these native trade-offs. 827 |
828 | 829 |830 | The table below compares three syntax and proof format ecosystems; JSON+JWTs, 831 | JSON-LD+JWTs, and JSON-LD+LD-Proofs. 832 |
833 | 834 || Feature | 838 |JSON + JWTs |
839 | JSON‑LD + JWTs |
840 | JSON‑LD + LD‑Proofs |
841 |
|---|---|---|---|
| 847 | PF1a. Proof format supports Zero-Knowledge Proofs. 848 | | 849 |✓ | 850 |✓ | 851 |✓ | 852 |
| 855 | PF2a. Proof format supports arbitrary proofs such as Proof 856 | of Work, Timestamp Proofs, and Proof of Stake. 857 | | 858 |✓ | 859 |✓ | 860 |✓ | 861 |
| 864 | PF3a. Based on existing official standards. 865 | | 866 |✓ | 867 |✖ | 868 |✖ | 869 |
| 872 | PF4a. Designed to be small in size. 873 | | 874 |✓ | 875 |✖ | 876 |✖ | 877 |
| 880 | PF5a. Offline support without further processing. 881 | | 882 |✓ | 883 |✖ | 884 |✖ | 885 |
| 888 | PF6a. Wide adoption in other existing standards. 889 | | 890 |✓ | 891 |✓ | 892 |✖ | 893 |
| 896 | PF7a. No type ambiguity. 897 | | 898 |✓ | 899 |✖ | 900 |✖ | 901 |
| 904 | PF8a. Broad library support. 905 | | 906 |✓ | 907 |✖ | 908 |✖ | 909 |
| 912 | PF9a. Easy to understand what is signed. 913 | | 914 |✓ | 915 |✓ | 916 |✖ | 917 |
| 920 | PF10a. Ability to be used as authn/authz token with existing systems. 921 | | 922 |✓ | 923 |✓ | 924 |✖ | 925 |
| 928 | PF11a. No additional canonicalization required. 929 | | 930 |✓ | 931 |✖ | 932 |✖ | 933 |
| 936 | PF12a. No Internet PKI required. 937 | | 938 |✓ | 939 |✖ | 940 |✖ | 941 |
| 944 | PF13a. No resolution of external documents needed. 945 | | 946 |✓ | 947 |✖ | 948 |✖ | 949 |
955 | Some of the features listed in the table above are debateable, since a feature 956 | can always be added to a particular syntax or digital proof format. The table 957 | is intended to identify native features of each combination such that no 958 | additional language design or extension is required to achieve the identified 959 | feature. Features that all languages provide, such as the ability to express 960 | numbers, have not been included for the purposes of brevity. Find more information 961 | about different proof formats in the next section. 962 |
963 | 964 |@context. This means that
1064 | a verifiable credential system would rely on existing Internet PKI to a certain extend and
1065 | cannot be fully decentralized. A JWT-based system does not need to introduce this dependency.
1066 | 1081 | The Verifiable Credentials Data Model is designed to be compatible with a 1082 | variety of existing and emerging syntaxes and digital proof formats. Each 1083 | approach has benefits and drawbacks. The following table is intended to 1084 | summarize a number of these native trade-offs. 1085 |
1086 | 1087 |1088 | The table below compares three syntax and proof format ecosystems; JSON+JWTs, 1089 | JSON-LD+JWTs, and JSON-LD+LD-Proofs. Readers should be aware that 1090 | Zero-Knowledge Proofs are currently proposed as a sub-type of LD-Proofs and 1091 | thus fall into the final column below. 1092 |
1093 | 1094 || Feature | 1098 |JSON + JWTs |
1099 | JSON‑LD + JWTs |
1100 | JSON‑LD + LD‑Proofs |
1101 |
|---|---|---|---|
| 1107 | PF1b. Support for open world data modelling. 1108 | | 1109 |✖ | 1110 |✓ | 1111 |✓ | 1112 |
| 1115 | PF2b. Universal identifier mechanism for JSON objects via 1116 | the use of URIs. 1117 | | 1118 |✖ | 1119 |✓ | 1120 |✓ | 1121 |
| 1124 | PF3b. A way to disambiguate properties shared among different 1125 | JSON documents by mapping them to IRIs via a context. 1126 | | 1127 |✖ | 1128 |✓ | 1129 |✓ | 1130 |
| 1133 | PF4b. A mechanism to refer to data in an external document, 1134 | where the data may be merged with the local document without a merge conflict 1135 | in semantics or structure. 1136 | | 1137 |✖ | 1138 |✓ | 1139 |✓ | 1140 |
| 1143 | PF5b. The ability to annotate strings with their language. 1144 | | 1145 |✖ | 1146 |✓ | 1147 |✓ | 1148 |
| 1151 | PF6b. A way to associate arbitrary datatypes, such as dates 1152 | and times, with arbitrary property values. 1153 | | 1154 |✖ | 1155 |✓ | 1156 |✓ | 1157 |
| 1160 | PF7b. A facility to express one or more directed graphs, 1161 | such as a social network, in a single document. 1162 | | 1163 |✖ | 1164 |✓ | 1165 |✓ | 1166 |
| 1169 | PF8b. Supports signature sets. 1170 | | 1171 |✖ | 1172 |✖ | 1173 |✓ | 1174 |
| 1177 | PF9b. Embeddable in HTML such that search crawlers will 1178 | index the machine-readable content. 1179 | | 1180 |✖ | 1181 |✖ | 1182 |✓ | 1183 |
| 1186 | PF10b. Data on the wire is easy to debug and serialize to 1187 | database systems. 1188 | | 1189 |✖ | 1190 |✖ | 1191 |✓ | 1192 |
| 1195 | PF11b. Nesting signed data does not cause data size to 1196 | double for every embedding. 1197 | | 1198 |✖ | 1199 |✖ | 1200 |✓ | 1201 |
| 1204 | PF12b. Proof format supports Zero-Knowledge Proofs. 1205 | | 1206 |✖ | 1207 |✖ | 1208 |✓ | 1209 |
| 1212 | PF13b. Proof format supports arbitrary proofs such as Proof 1213 | of Work, Timestamp Proofs, and Proof of Stake. 1214 | | 1215 |✖ | 1216 |✖ | 1217 |✓ | 1218 |
| 1221 | PF14b. Proofs can be expressed unmodified in other data 1222 | syntaxes such as YAML, N-Quads, and CBOR. 1223 | | 1224 |✖ | 1225 |✖ | 1226 |✓ | 1227 |
| 1230 | PF15b. Changing property-value ordering, or introducing 1231 | whitespace does not invalidate signature. 1232 | | 1233 |✖ | 1234 |✖ | 1235 |✓ | 1236 |
| 1239 | PF16b. Designed to easily support experimental signature 1240 | systems. 1241 | | 1242 |✖ | 1243 |✖ | 1244 |✓ | 1245 |
| 1248 | PF17b. Supports signature chaining. 1249 | | 1250 |✖ | 1251 |✖ | 1252 |✓ | 1253 |
| 1256 | PF18b. Does not require pre-processing or post-processing. 1257 | | 1258 |✖ | 1259 |✖ | 1260 |✓ | 1261 |
| 1264 | PF19b. Canonicalization requires only base-64 encoding. 1265 | | 1266 |✖ | 1267 |✖ | 1268 |✓ | 1269 |
1274 | Some of the features listed in the table above are debateable, since a feature 1275 | can always be added to a particular syntax or digital proof format. The table 1276 | is intended to identify native features of each combination such that no 1277 | additional language design or extension is required to achieve the identified 1278 | feature. Features that all languages provide, such as the ability to express 1279 | numbers, have not been included for the purposes of brevity. 1280 |
1281 | 1282 |@context property. JSON has no such feature.
1294 | 1528 | The Verifiable Credentials Data Model is designed to be compatible with a 1529 | variety of existing and emerging digital proof formats. Each 1530 | proof format has benefits and drawbacks. Many proof formats cannot reveal 1531 | only selected attribute values from a verifiable credential; they can only 1532 | reveal all (or none). 1533 |
1534 |1535 | Zero-Knowledge Proofs (ZKPs) are a proof format that enables 1536 | privacy-preserving data-minimization features in verifiable presentations, 1537 | such as selective disclosure and predicate proofs. 1538 |
1539 |1540 | Selective disclosure is the ability of a holder to reveal a subset of 1541 | the attributes of a verifiable credential in a verifiable presentation. 1542 | A presentation based on zero-knowledge proof mechanisms only contains 1543 | those attributes and associated values that are required to satisfy 1544 | the presentation requirements. 1545 |
1546 |1547 | Zero-knowledge predicate proofs are a type of proof associated with 1548 | an attribute. Predicate proofs include comparisons, such as 1549 | "greater than", "less than", "not equal", "range", 1550 | "set membership", and "set non-membership". 1551 | Predicate proofs can be constructed without requiring the issuer 1552 | to create special fields, such as 1553 | "age-under-18", "age-over-21", or "age-over-60", in the verifiable credential 1554 | at the time the credential is issued. 1555 | For example, if a holder has a credential with a "birth-date" claim, 1556 | the holder can create a predicate proof based on "birth-date" in the 1557 | verifiable presentation. A predicate value derived from "birth-date" in 1558 | the verifiable credential can cryptographically prove to the verifier that 1559 | the holder's age is greater (or less) than a specified number, without 1560 | revealing the holder's "birth-date". 1561 |
1562 |1563 | Verifiable credentials based on zero-knowledge proof mechanisms are 1564 | also quantum-resistant after presentation. 1565 |
1566 |1567 | Drawbacks of zero-knowledge proof mechanisms include that they are more complex 1568 | and may require larger proofs than some other proof mechanisms. 1569 |
1570 | 1571 |1578 | Entities that use verifiable credentials and 1579 | verifiable presentations should follow protocols that enable progressive 1580 | trust. Progressive trust refers to enabling individuals to share information 1581 | about themselves only on an as needed basis, slowing building up more trust as 1582 | more information is shared with another party. 1583 |
1584 |1585 | Progressive trust is strongly related to the principle of data minimization, and 1586 | enabled by technologies such as selective disclosure and predicate proofs. We 1587 | encourage the use of progressive trust as a guiding principle for implementers 1588 | as they develop protocols for issuers, holders, and 1589 | verifiers. 1590 | 1591 |
1592 | 1593 |1596 | Data minimization is a principle that encourages verifiers to request the 1597 | minimum amount of data necessary from holders, and for holders to 1598 | only provide the minimum amount of data to verifiers. This "minimum 1599 | amount of data" depends on the situation and may change over the course of a 1600 | holder's interaction with a verifier. 1601 |
1602 |1603 | For example, a holder may apply for a loan, with a bank acting as the 1604 | verifier. There are several points at which the bank may want to determine 1605 | whether the holder is qualified to continue in the process of applying for 1606 | the loan; for instance, the bank may have a policy of only providing loans to 1607 | existing account holders. A protocol that follows the principle of data 1608 | minimization would allow the holder to reveal to the verifier only 1609 | that they are an existing account holder, before the bank requests any additional 1610 | information, such as account balances or employment status. In this way, the 1611 | applicant may progressively entrust the bank with more information, as the data 1612 | needed by the bank to make its determinations is requested a piece at a time, as 1613 | needed, rather than as a complete set, up front. 1614 |
1615 |1621 | Selective disclosure is the ability of a holder to select some elements 1622 | of a verifiable credential to share with a verifier, without 1623 | revealing the rest. There are several different methods which support selective 1624 | disclosure, we provide two examples: 1625 |
1626 |1647 | 1648 |
1649 | 1650 |1654 | Another technique which may be used to support progressive trust is to use 1655 | predicates as the values of revealed claims. Predicates allow a holder to 1656 | provide True/False values to a verifier rather than revealing claim 1657 | values. 1658 |
1659 |
1660 | Predicate proofs may be enabled by verifiable credential issuers
1661 | as claims, e.g., the credentialSubject may include an
1662 | ageOver18 property rather than a birthdate
1663 | property. This would allow holders to provide proof that they are
1664 | over 18 without revealing their birthdates.
1665 |
1667 | Certain signature types enable predicate proofs by allowing claims from a
1668 | standard verifiable credential to be presented as predicates. For
1669 | example, a
1670 | Camenisch-Lysyanskaya signed verifiable credential that contains a
1671 | credentialSubject with a birthdate property may
1672 | be included in a verifiable presentation as a derived credential that
1673 | contains an ageOver18 property.
1674 |
1679 | The examples provided in this section are intended to illustrate some possible 1680 | mechanisms for supporting progressive trust, not provide an exhaustive or 1681 | comprehensive list of all the ways progressive trust may be supported. Research 1682 | in this area continues with the use of cutting-edge proof techniques such as 1683 | zk-SNARKS and 1684 | Bulletproofs, as well as 1685 | different signature protocols. 1686 |
1687 |1688 | A draft report by the 1689 | Credentials Community Group on 1690 | data minimization may 1691 | also be useful reading for implementers looking to enable progressive trust. 1692 |
1693 |1702 | The W3C Verifiable Claims Working Group has produced a 1703 | test suite in order 1704 | for implementers to confirm their conformance with the current specifications. 1705 |
1706 |1707 | You can review the current 1708 | draft implementation report, which contains conformance testing results for submitted 1709 | implementations supporting the Verifiable Credentials Data Model specification. 1710 |
1711 |