Skip to main content

Verifiable Credential

Create and verify EBSI-compliant W3C Verifiable Credentials in JWT format with the @cef-ebsi/verifiable-credential library.

This library extends the @transmute/json-web-signature and @transmute/vc.js libraries by applying additional validation rules. For more details, see EBSI Verifiable Credentials Playbook.

Note: this library only supports 2020-12 JSON Schemas.

Installation

Using npm:

$ npm i --save @cef-ebsi/verifiable-credential

Using yarn:

$ yarn add @cef-ebsi/verifiable-credential

Usage

Creating JWTs

Prerequisites

Create an EbsiIssuer object to sign JWTs:

import type { EbsiIssuer } from "@cef-ebsi/verifiable-credential";

const issuer: EbsiIssuer = {
did: "did:ebsi:zgPs5MVWHwJJb4g9kZvYf3e",
kid: "did:ebsi:zgPs5MVWHwJJb4g9kZvYf3e#keys-1",
publicKeyJwk: <JWK>,
privateKeyJwk: <JWK>,
alg: "ES256K",
};

In order to create a valid JWT:

  1. This issuer MUST be registered in the Trusted Issuers Registry.

Creating a Verifiable Credential

Specify a payload matching the EbsiVerifiableAttestation interface:

import { createVerifiableCredentialJwt } from "@cef-ebsi/verifiable-credential";
import type { EbsiVerifiableAttestation } from "@cef-ebsi/verifiable-credential";

const vcPayload: EbsiVerifiableAttestation = {
"@context": ["https://www.w3.org/2018/credentials/v1"],
id: "urn:did:123456",
type: ["VerifiableCredential", "VerifiableAttestation", "VerifiableId"],
issuer: "did:ebsi:zgPs5MVWHwJJb4g9kZvYf3e",
issuanceDate: "2021-11-01T00:00:00Z",
validFrom: "2021-11-01T00:00:00Z",
credentialSubject: {
id: "did:ebsi:zYud7H5Wvf9ksRUrmTrFo9D",
personalIdentifier: "IT/DE/1234",
familyName: "Castafiori",
firstName: "Bianca",
dateOfBirth: "1930-10-01",
},
credentialSchema: {
id: "https://api-pilot.ebsi.eu/trusted-schemas-registry/v2/schemas/0x0f41a1f4934e11f8f98e444ed34fb040645dcc04cead2ae28fca062eabfac181",
type: "FullJsonSchemaValidator2021",
},
expirationDate: "2031-11-30T00:00:00Z",
issued: "2021-10-30T00:00:00Z",
};

Specify the options to validate the issuer and credential:

const options = {
// EBSI URI Authority ([userinfo "@"] host [":" port])
ebsiAuthority: "api-pilot.ebsi.eu",
};

Create a JWT by signing it with the previously configured issuer using the createVerifiableCredentialJwt function:

const vcJwt = await createVerifiableCredentialJwt(vcPayload, issuer, options);
console.log(vcJwt);
// eyJraWQiOiJkaWQ6ZWJzaTp6Z1Bz...j9Pv1HSIR9aPXIVRMGYfjhmQH8oSM03g

Verifying JWTs

Prerequisites

Pass in a VC JWT to verify using the verifyCredentialJwt function:

import { verifyCredentialJwt } from "@cef-ebsi/verifiable-credential";

const vcJwt = "eyJraWQiOiJkaWQ6ZWJzaTp6Z1Bz...j9Pv1HSIR9aPXIVRMGYfjhmQH8oSM03g";

const options = {
// EBSI URI Authority ([userinfo "@"] host [":" port])
ebsiAuthority: "api-pilot.ebsi.eu",
};

const verifiedVc = await verifyCredentialJwt(vcJwt, options);

console.log(verifiedVc);
/*
{
"@context": ["https://www.w3.org/2018/credentials/v1"],
id: "urn:did:123456",
type: ["VerifiableCredential", "VerifiableAttestation", "VerifiableId"],
issuer: "did:ebsi:zgPs5MVWHwJJb4g9kZvYf3e",
issuanceDate: "2021-11-01T00:00:00Z",
validFrom: "2021-11-01T00:00:00Z",
credentialSubject: {
id: "did:ebsi:zYud7H5Wvf9ksRUrmTrFo9D",
personalIdentifier: "IT/DE/1234",
familyName: "Castafiori",
firstName: "Bianca",
dateOfBirth: "1930-10-01",
},
credentialSchema: {
id: "https://api-pilot.ebsi.eu/trusted-schemas-registry/v2/schemas/0x0f41a1f4934e11f8f98e444ed34fb040645dcc04cead2ae28fca062eabfac181",
type: "FullJsonSchemaValidator2021",
},
expirationDate: "2031-11-30T00:00:00Z",
issued: "2021-10-30T00:00:00Z",
}
*/

Verification process

The verification of the credentials is performed using the following process:

  1. Header
  • The alg property must be ES256, ES256K, ES256K-R, Ed25519, or EdDSA.
  • The kid property must contain the DID of a legal entity.
  1. Basic properties in the payload
  • The payload must contain a vc property containing an EBSI Verifiable Attestation.
  • The iss property must match the VC issuer vc.issuer.
  • The sub property must match the VC credential subject vc.credentialSubject.id.
  • The jti property must match the VC ID vc.id.
  • The iat property must refer to the date in VC issued vc.issued.
  • The nbf property must refer to the date in VC valid from vc.validFrom.
  • The exp property mush refer to date in VC expiration date vc.expirationDate in the case it is defined.
  1. Signature
  • The issuer must be registered in the DID Registry.
  • The signature must be validated with the key present in the DID document.
  1. Extra validations to the VC payload
  • Validation of @context.
  • Validation of type.
  • Validation of dates.
  1. Issuer in Trusted Issuers Registry
  • The issuer must be registered in the Trusted Issuers Registry.
  • The VC must contain terms of use pointing to the accreditations of the issuer.
  • The issuer must be accredited to issue the types present in the credential.
  1. Credential subject
  • The subject in VC Credential subject must be a valid DID, either an EBSI DID v1 (Legal Entity) or an EBSI did:key DID (Natural Person).
  1. Credential schema
  • The VC credential schema(s) must link to valid EBSI credential schemas.
  • The credential payload is validated against the aforementioned JSON Schemas.

Try it online

The VC & VP validator tool uses the @cef-ebsi/verifiable-credential to verify VC JWTs.