Tamper proofing

As part of the Web Credentials verification process, MATTR VII checks for any tampering of the credential, based on Linked Data Proofs (opens in a new tab). When the credential is signed, the JSON body is expanded using the referenced @context vocabularies. You can explore what this looks like in the JSON-LD Playground (opens in a new tab).

This expanded credential view is then signed using keys from the Issuer DID document.

The same process happens during verification. The claims are expanded based on the referenced contexts, and it is the expanded version that is being verified.

The @context schema is expanded using a "last term wins" process. That means that when two different schemas define the same terms, the lower context in the list 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 @vocab context. When there is a @vocab referenced lower in the list (e.g. "@vocab": "http://schema.org") it will override the credential’s default context.

JSON
{ "@vocab": "https://w3id.org/security/undefinedTerm#" }

Example 1

Changing the givenName from Chris to Bob will result in verification failure because the expanded term has clearly changed:

Credential payload

JSON
{ "givenName": "Bob" }

NQUAD

<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/givenName> "Bob" .

Example 2

Inserting a new resolvable context to the credential payload in the middle of the list results in no change to the result, so verification will be successful.

This is because for this credential, the terms in this context givenName , familyName etc. are overwritten by the schema.org context lower in the list, so the resulting expanded terms have not changed.

Credential payload

JSON
"@context": [
    "https://www.w3.org/2018/credentials/v1",
    {
        "@vocab": "https://w3id.org/security/undefinedTerm#"
    },
    "https://www.w3.org/2018/credentials/examples/v1",
    "https://schema.org"
]

NQUAD

<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/educationalCredentialAwarded> "Certificate Name" .
<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/familyName> "Shin" .
<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/givenName> "Chris" .
<did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj> <http://schema.org/name> "tenant" .
...

Example 3

Inserting the same resolvable context to the bottom of the @Context list leads to the verification failing 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).

Credential payload

JSON
"@context": [
    "https://www.w3.org/2018/credentials/v1",
    {
        "@vocab": "https://w3id.org/security/undefinedTerm#"
    },
    "https://schema.org",
    "https://www.w3.org/2018/credentials/examples/v1"
]

NQUAD

<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/educationalCredentialAwarded> "Certificate Name" .
<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/familyName> "Shin" .
<did:key:z6MkfxQU7dy8eKxyHpG267FV23agZQu9zmokd8BprepfHALi> <http://schema.org/givenName> "Chris" .
<did:key:z6MkndAHigYrXNpape7jgaC7jHiWwxzB3chuKUGXJg2b5RSj> <http://schema.org/name> "tenant"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#HTML> .
...