Verify a Credential using the API

Introduction

In order to perform some basic verification checks on a Verifiable Credential that has either been issued by your tenant on the MATTR Platform, or obtained from external sources, we’ve created an endpoint that allows you to Verify a Credential using a simple API call.

Pre-requisites

  • Have a JSON-LD verifiable credential available, if you want to try out the endpoint then simply follow the Issue a JSON-LD Credential tutorial.

Verify the Credential

Provide the JSON-LD Credential in the request payload for the endpoint.

Note if you are obtaining the Credential from the Create a Verifiable Credential only copy the "credential": {} field and body, not the entire response.

http
Copy to clipboard.
1POST
2https://tenant.vii.mattr.global/core/v1/credentials/verify

Request

Feel free to use the example below against the endpoint on your tenant.

json
Copy to clipboard.
1{
2 "credential":{   
3    "@context": [
4      "https://www.w3.org/2018/credentials/v1",
5      {
6        "@vocab": "https://w3id.org/security/undefinedTerm#"
7      },
8      "https://schema.org"
9    ],
10    "type": [
11      "VerifiableCredential",
12      "Course"
13    ],
14    "issuer": {
15      "id": "did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj",
16      "name": "tenant"
17    },
18    "issuanceDate": "2020-08-30T23:24:54.876Z",
19    "credentialSubject": {
20      "id": "did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi",
21      "givenName": "Chris",
22      "familyName": "Shin",
23      "educationalCredentialAwarded": "Certificate Name"
24    },
25    "proof": {
26      "type": "Ed25519Signature2018",
27      "created": "2020-08-30T23:24:55Z",
28      "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..BSHdalZrYml0slwgAXFVF5uAcg2DbPMfwatturKs8TnuxBxylQDnS3JkORORVmO73Ruh7h8KJvVvHO4pE5NsCQ",
29      "proofPurpose": "assertionMethod",
30      "verificationMethod": "did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj#z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj"
31    }
32 }
33}

Platform checks

The platform will run a set of standard checks to confirm the validity of the Verifiable Credential.

Checks include:

  • The Credential is not in a revoked status as per RevocationList2020

  • Issuer DID can be resolved, this means that the DID Document is valid and the public key is obtainable

  • JSON-LD context is valid for subject claims

  • Proof is valid & the expanded JSON-LD Credential has not been tampered with

Remember these checks apply to any JSON-LD Credential provided, so the Issuer DID check and the Revocation Status check are not dependent on any setup in your tenant (unless the credential you are verifying is from your tenant).

Verified Response

As long as the payload has been formatted correctly the platform will respond with a 200 response with a body indicating if the provided credential is verified or not.

If all is well the platform will respond with a 200 status code:

json
Copy to clipboard.
1{
2  "verified": true
3}

This means you can be confident the Credential has not been revoked, has been issued by the Issuer DID described in the credential, and the Credential holds true to its original semantic meaning and has not been tampered with.

Non-verified Response

As long as the payload has been formatted correctly the platform will respond with a 200 status code with a body indicating the provided credential is not verified and an applicable reason.

Revoked credential

If the credential has been revoked, then a 200 response is returned with the verified boolean set to false and a clear reason why the verification failed.

json
Copy to clipboard.
1{
2  "verified": false,
3  "reason": "Credential has been revoked"
4}

Issuer DID Document not resolvable

Likewise. if the Issuer DID cannot be resolved to find the DID Document, then the Verifiable Credential cannot be proven to be from the Issuer.

Resolvable contexts and tampering

As the Platform will check for any tampering of the Credential, it may be useful to understand a bit more about JSON-LD based Credentials and Linked Data Proofs.

First, when the Credential is originally signed, the JSON body is expanded using the dereferenced @context vocabularies.

You can explore what this looks like at the JSON-LD Playground, simply paste in the body of the credential (not the credential field).

This is the Credential above in an N-Quads representation:

Copy to clipboard.
1<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/educationalCredentialAwarded> "Certificate Name" .
2<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/familyName> "Shin" .
3<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/givenName> "Chris" .
4<did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj> <http://schema.org/name> "tenant" .
5_:b0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Course> .
6_:b0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.w3.org/2018/credentials#VerifiableCredential> .
7_:b0 <https://w3id.org/security#proof> _:b1 .
8_:b0 <https://www.w3.org/2018/credentials#credentialSubject> <did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> .
9_:b0 <https://www.w3.org/2018/credentials#issuanceDate> "2020-08-30T23:24:54.876Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
10_:b0 <https://www.w3.org/2018/credentials#issuer> <did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj> .
11_:b2 <http://purl.org/dc/terms/created> "2020-08-30T23:24:55Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> _:b1 .
12_:b2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/security#Ed25519Signature2018> _:b1 .
13_:b2 <https://w3id.org/security#jws> "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..BSHdalZrYml0slwgAXFVF5uAcg2DbPMfwatturKs8TnuxBxylQDnS3JkORORVmO73Ruh7h8KJvVvHO4pE5NsCQ" _:b1 .
14_:b2 <https://w3id.org/security#proofPurpose> <https://w3id.org/security#assertionMethod> _:b1 .
15_:b2 <https://w3id.org/security#verificationMethod> <did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj#z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj> _:b1 .

It is this expanded view of the Credential that is signed using the keys from the Issuer’s identifier (DID).

The schema in @context is expanded using a ‘last term wins’ process, i.e. if two different schemas define the same terms, it’s the lower context in the list that defines the expanded terms used in the LD-Proof.

Any JSON-LD term that is not defined in a standard schema will get picked up by the use of the @vocab context.

json
Copy to clipboard.
1{"@vocab": "https://w3id.org/security/undefinedTerm#"}

Note if there is an @vocab referenced in other schema lower in the list (e.g. "@vocab": "http://schema.org") this will override the credential’s default context.

Using this knowledge, testing the Proof becomes more meaningful from an application logic perspective.

Example 1:

Changing the givenName to Bob fails the verification, because the expanded term has clearly changed.

"givenName": "Bob",
Copy to clipboard.
1<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/givenName> "Bob" .
json
Copy to clipboard.
1{
2  "verified": false,
3  "reason": "Credential is invalid"
4}

Example 2:

Adding a new resolvable context to the payload, in the middle of the list, results in the verification being true, because, for this credential, any terms in this context are overwritten by the schema.org context lower in the list, so the resulting expanded terms have not changed.

json
Copy to clipboard.
1"@context": [
2      "https://www.w3.org/2018/credentials/v1",
3      {
4        "@vocab": "https://w3id.org/security/undefinedTerm#"
5      },
6            "https://www.w3.org/2018/credentials/examples/v1",
7            "https://schema.org"
8    ],
Copy to clipboard.
1<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/educationalCredentialAwarded> "Certificate Name" .
2<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/familyName> "Shin" .
3<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/givenName> "Chris" .
4<did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj> <http://schema.org/name> "tenant" .
5...
json
Copy to clipboard.
1{
2  "verified": true
3}

Example 3

Moving the new resolvable context to the bottom of the list leads to the verification being false because the expanded view shows that the semantic meaning of the Credential has been altered since it was issued (in this case a format change on the name term but other scenarios could be more impactful).

json
Copy to clipboard.
1"@context": [
2      "https://www.w3.org/2018/credentials/v1",
3      {
4        "@vocab": "https://w3id.org/security/undefinedTerm#"
5      },
6      "https://schema.org",
7      "https://www.w3.org/2018/credentials/examples/v1"
8    ],
Copy to clipboard.
1<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/educationalCredentialAwarded> "Certificate Name" .
2<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/familyName> "Shin" .
3<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/givenName> "Chris" .
4<did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj> <http://schema.org/name> "tenant"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#HTML> .
5...
json
Copy to clipboard.
1{
2  "verified": false,
3  "reason": "Credential is invalid"
4}