Skip to content

Commit

Permalink
Add JSON Schema for Verifiable Credentials (#977)
Browse files Browse the repository at this point in the history
* first draft of schema

* tests and readme

* pr comments

* add proof chain and proof arrays

* add vp schema and tests

* remove unused dep

* update readme

* Update schema/verifiable-presentation/verifiable-presentation-schema-test.js

Co-authored-by: Ted Thibodeau Jr <[email protected]>

* Update schema/README.md

Co-authored-by: Ted Thibodeau Jr <[email protected]>

* Update schema/README.md

Co-authored-by: Ted Thibodeau Jr <[email protected]>

Co-authored-by: Ted Thibodeau Jr <[email protected]>
  • Loading branch information
Gabe and TallTed authored Nov 15, 2022
1 parent 6bfde2b commit cb05564
Show file tree
Hide file tree
Showing 20 changed files with 982 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
**/node_modules
**/.DS_Store
**/.vscode

**/package-lock.json
11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,14 @@
"bugs": {
"url": "https://github.com/w3c/vc-data-model/issues"
},
"homepage": "https://github.com/w3c/vc-data-model"
"homepage": "https://github.com/w3c/vc-data-model",
"dependencies": {
"ajv": "^8.11.0",
"assert": "^2.0.0",
"fs": "^0.0.1-security",
"mocha": "^10.1.0"
},
"scripts": {
"test-schema": "mocha 'schema/**/*.js'"
}
}
25 changes: 25 additions & 0 deletions schema/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Verifiable Credentials JSON Schema

This directory defines [JSON Schemas](https://json-schema.org/) for the Verifiable Credentials Data Model.

Currently, this implementation makes use of **JSON Schema version 2020-12**:
- [JSON Schema Core](https://json-schema.org/draft/2020-12/json-schema-core.html)
- [JSON Schema Validation](https://json-schema.org/draft/2020-12/json-schema-validation.html)
- [Relative JSON Pointers](https://json-schema.org/draft/2020-12/relative-json-pointer.html)

# Schemas

There are two schemas provided, each with associated tests:

- [Verifiable Credential JSON Schema](verifiable-credential/verifiable-credential-schema.json)
- [Verifiable Presentation JSON Schema](verifiable-presentation/verifiable-presentation-schema.json)

# Tests

A limited set of tests against examples in the specification are included. To run these tests, you can use the following command, after `npm i`:

```bash
npm run test-schemas
```

The tests rely on examples featured in the spec. Currently these examples have been copy-pasted, and there is no guarantee they are in sync with the spec. This should be improved!
3 changes: 3 additions & 0 deletions schema/__fixtures__/ajv.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const Ajv2020 = require("ajv/dist/2020");
const ajv = new Ajv2020({allErrors: true});
module.exports = ajv;
30 changes: 30 additions & 0 deletions schema/verifiable-credential/example-1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"id": "http://example.edu/credentials/1872",
"type": ["VerifiableCredential", "AlumniCredential"],
"issuer": "https://example.edu/issuers/565049",
"issuanceDate": "2010-01-01T19:23:24Z",
"credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"alumniOf": {
"id": "did:example:c276e12ec21ebfeb1f712ebc6f1",
"name": [{
"value": "Example University",
"lang": "en"
}, {
"value": "Exemple d'Université",
"lang": "fr"
}]
}
},
"proof": {
"type": "RsaSignature2018",
"created": "2017-06-18T21:19:10Z",
"proofPurpose": "assertionMethod",
"verificationMethod": "https://example.edu/issuers/565049#key-1",
"jws": "eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..TCYt5XsITJX1CxPCT8yAV-TVkIEq_PbChOMqsLfRoPsnsgw5WEuts01mq-pQy7UJiN5mgRxD-WUcX16dUEMGlv50aqzpqh4Qktb3rk-BuQy72IFLOqV0G_zS245-kronKb78cPN25DGlcTwLtjPAYuNzVBAh4vGHSrQyHUdBBPM"
}
}
24 changes: 24 additions & 0 deletions schema/verifiable-credential/example-11.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"id": "http://example.gov/credentials/3732",
"type": ["VerifiableCredential", "UniversityDegreeCredential"],
"issuer": "https://example.edu",
"issuanceDate": "2010-01-01T19:23:24Z",
"credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"degree": {
"type": "BachelorDegree",
"name": "Bachelor of Science and Arts"
}
},
"proof": {
"type": "Ed25519Signature2020",
"created": "2021-11-13T18:19:39Z",
"verificationMethod": "https://example.edu/issuers/14#key-1",
"proofPurpose": "assertionMethod",
"proofValue": "z58DAdFfa9SkqZMVPxAQpic7ndSayn1PzZs6ZjWp1CktyGesjuTSwRdoWhAfGFCF5bppETSTojQCrfFPP2oumHKtz"
}
}
18 changes: 18 additions & 0 deletions schema/verifiable-credential/example-12.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"id": "http://example.edu/credentials/3732",
"type": ["VerifiableCredential", "UniversityDegreeCredential"],
"issuer": "https://example.edu/issuers/14",
"issuanceDate": "2010-01-01T19:23:24Z",
"expirationDate": "2020-01-01T19:23:24Z",
"credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"degree": {
"type": "BachelorDegree",
"name": "Bachelor of Science and Arts"
}
}
}
21 changes: 21 additions & 0 deletions schema/verifiable-credential/example-13.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"id": "http://example.edu/credentials/3732",
"type": ["VerifiableCredential", "UniversityDegreeCredential"],
"issuer": "https://example.edu/issuers/14",
"issuanceDate": "2010-01-01T19:23:24Z",
"credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"degree": {
"type": "BachelorDegree",
"name": "Bachelor of Science and Arts"
}
},
"credentialStatus": {
"id": "https://example.edu/status/24",
"type": "CredentialStatusList2017"
}
}
21 changes: 21 additions & 0 deletions schema/verifiable-credential/example-18.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"id": "http://example.edu/credentials/3732",
"type": ["VerifiableCredential", "UniversityDegreeCredential"],
"issuer": "https://example.edu/issuers/14",
"issuanceDate": "2010-01-01T19:23:24Z",
"credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"degree": {
"type": "BachelorDegree",
"name": "Bachelor of Science and Arts"
}
},
"credentialSchema": {
"id": "https://example.org/examples/degree.json",
"type": "JsonSchemaValidator2018"
}
}
21 changes: 21 additions & 0 deletions schema/verifiable-credential/example-20.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"id": "http://example.edu/credentials/3732",
"type": ["VerifiableCredential", "UniversityDegreeCredential"],
"issuer": "https://example.edu/issuers/14",
"issuanceDate": "2010-01-01T19:23:24Z",
"credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"degree": {
"type": "BachelorDegree",
"name": "Bachelor of Science and Arts"
}
},
"refreshService": {
"id": "https://example.edu/refresh/3732",
"type": "ManualRefreshService2018"
}
}
28 changes: 28 additions & 0 deletions schema/verifiable-credential/example-21.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"id": "http://example.edu/credentials/3732",
"type": ["VerifiableCredential", "UniversityDegreeCredential"],
"issuer": "https://example.edu/issuers/14",
"issuanceDate": "2010-01-01T19:23:24Z",
"credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"degree": {
"type": "BachelorDegree",
"name": "Bachelor of Science and Arts"
}
},
"termsOfUse": [{
"type": "IssuerPolicy",
"id": "http://example.com/policies/credential/4",
"profile": "http://example.com/profiles/credential",
"prohibition": [{
"assigner": "https://example.edu/issuers/14",
"assignee": "AllVerifiers",
"target": "http://example.edu/credentials/3732",
"action": ["Archival"]
}]
}]
}
26 changes: 26 additions & 0 deletions schema/verifiable-credential/example-23.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"id": "http://example.edu/credentials/3732",
"type": ["VerifiableCredential", "UniversityDegreeCredential"],
"issuer": "https://example.edu/issuers/14",
"issuanceDate": "2010-01-01T19:23:24Z",
"credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"degree": {
"type": "BachelorDegree",
"name": "Bachelor of Science and Arts"
}
},
"evidence": [{
"id": "https://example.edu/evidence/f2aeec97-fc0d-42bf-8ca7-0548192d4231",
"type": ["DocumentVerification"],
"verifier": "https://example.edu/issuers/14",
"evidenceDocument": "DriversLicense",
"subjectPresence": "Physical",
"documentPresence": "Physical",
"licenseNumber": "123AB4567"
}]
}
17 changes: 17 additions & 0 deletions schema/verifiable-credential/example-4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"id": "http://example.edu/credentials/3732",
"type": ["VerifiableCredential", "UniversityDegreeCredential"],
"issuer": "https://example.edu/issuers/565049",
"issuanceDate": "2010-01-01T00:00:00Z",
"credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"degree": {
"type": "BachelorDegree",
"name": "Bachelor of Science and Arts"
}
}
}
92 changes: 92 additions & 0 deletions schema/verifiable-credential/verifiable-credential-schema-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
const fs = require('fs');
const assert = require('assert');
const ajv = require('../__fixtures__/ajv');

const verifiableCredentialSchema = "/verifiable-credential-schema.json";
const schema = JSON.parse(fs.readFileSync(__dirname + verifiableCredentialSchema));

describe('Verifiable Credential', function () {
describe('JSON Schema', function () {

it('should validate example 1 using JSON Schema 2020-12 ', function () {
const data = JSON.parse(fs.readFileSync(__dirname + '/example-1.json'));
const validate = ajv.compile(schema);
const valid = validate(data);

assert.equal(null, validate.errors);
assert.equal(true, valid);
});

it('should validate example 4 using JSON Schema 2020-12 ', function () {
const data = JSON.parse(fs.readFileSync(__dirname + '/example-4.json'));
const validate = ajv.compile(schema);
const valid = validate(data);

assert.equal(null, validate.errors);
assert.equal(true, valid);
});

it('should validate example 11 using JSON Schema 2020-12 ', function () {
const data = JSON.parse(fs.readFileSync(__dirname + '/example-11.json'));
const validate = ajv.compile(schema);
const valid = validate(data);

assert.equal(null, validate.errors);
assert.equal(true, valid);
});

it('should validate example 12 using JSON Schema 2020-12 ', function () {
const data = JSON.parse(fs.readFileSync(__dirname + '/example-12.json'));
const validate = ajv.compile(schema);
const valid = validate(data);

assert.equal(null, validate.errors);
assert.equal(true, valid);
});

it('should validate example 13 using JSON Schema 2020-12 ', function () {
const data = JSON.parse(fs.readFileSync(__dirname + '/example-13.json'));
const validate = ajv.compile(schema);
const valid = validate(data);

assert.equal(null, validate.errors);
assert.equal(true, valid);
});

it('should validate example 18 using JSON Schema 2020-12 ', function () {
const data = JSON.parse(fs.readFileSync(__dirname + '/example-18.json'));
const validate = ajv.compile(schema);
const valid = validate(data);

assert.equal(null, validate.errors);
assert.equal(true, valid);
});

it('should validate example 20 using JSON Schema 2020-12 ', function () {
const data = JSON.parse(fs.readFileSync(__dirname + '/example-20.json'));
const validate = ajv.compile(schema);
const valid = validate(data);

assert.equal(null, validate.errors);
assert.equal(true, valid);
});

it('should validate example 21 using JSON Schema 2020-12 ', function () {
const data = JSON.parse(fs.readFileSync(__dirname + '/example-21.json'));
const validate = ajv.compile(schema);
const valid = validate(data);

assert.equal(null, validate.errors);
assert.equal(true, valid);
});

it('should validate example 23 using JSON Schema 2020-12 ', function () {
const data = JSON.parse(fs.readFileSync(__dirname + '/example-23.json'));
const validate = ajv.compile(schema);
const valid = validate(data);

assert.equal(null, validate.errors);
assert.equal(true, valid);
});
});
});
Loading

0 comments on commit cb05564

Please sign in to comment.