Introduction
Verifiable credentials are crucial in establishing trust and authenticity in the digital world. Whether you’re a student receiving a university diploma or an employee obtaining a professional certification, verifiable credentials provide a secure way to prove your qualifications. This guide breaks down the key components of Verifiable Credentials (VCs) and Verifiable Presentations (VPs) and explains their verification processes using EBSI libraries.
Key components
Term | Description | Example |
---|---|---|
Credential Subject | The individual or entity to whom the credential applies. | The recipient of a diploma is the credential subject. |
Issuer | The organisation that issues the credential. | Think of it as the university granting the diploma or the certification authority validating the skills. |
Issuance Date | Indicates when the credential was issued. | Similar to the timestamp on a diploma or certificate. |
Proofs (Signatures) | Cryptographic signatures that ensure the credential’s authenticity and integrity. | Imagine it as a digital seal from the issuer, guaranteeing authenticity. |
Expiration Date | (Optional) Specifies when the credential becomes invalid. | Professional certifications may need renewal after a certain period. |
Status | Indicates whether the credential is still valid. | If the issuer revokes the credential, its status changes. |
Custom Properties | Provides specific details about the credential. | If a verifier needs to determine whether a subject is older than 21 years of age, they might rely on a specific birthdate property or more abstract properties, such as ageOver. |
For more information on the data fields used by verifiers in the validation process, refer to this page.
Verifiable Credential JWT Verification Process
The verification process involves examining various data fields and properties of the VC. The following requirements and checks should be considered when verifying the credential:
1. Header
- Ensure the algorithm (
alg
) is ES256, ES256K, Ed25519, or EdDSA. - The
kid
property must contain the issuer’s DID and the fragment identifier for the verification method.
2. Validating VC payload properties
- Verify the VC payload
- The payload must contain a
vc
property with an EBSI Verifiable Attestation. It's advisable to implement extra validation checks here. Some examples include:- Validation of
@context
: This provides essential context information for interpreting the credential. Take into account that the first value in the@context
set must be "https://www.w3.org/2018/credentials/v1" (as defined here). - Validation of
type
: Determines the purpose and usage of the VC. Please note that the first value of thetype
set must beVerifiableCredential
(for further details, please refer here). - Validation of dates: Ensure dates (e.g., issuance date, valid-from date, expiration date) are consistent and within acceptable ranges. Invalid or inconsistent dates may indicate tampering or errors.
- Validation of
- 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 must refer to the date in VC expiration date (vc.expirationDate
), if defined.
- The payload must contain a
3. Signature Validation
- Validate the signature against the verification method from the DID document corresponding to the VC JWT
kid
header.
4. Issuer as a Legal Entity in Trusted Issuer Registry
- If the issuer is a Legal Entity, ensure the issuer is registered in the Trusted Issuers Registry (TIR). This registry ensures that only authorised entities issue VCs.
- Additionally, if the VC is an attestation with accreditation:
- The VC must contain a
termsOfUse
property pointing to the accreditations of the issuer. - The issuer must be accredited to issue the types present in the credential.
- The VC must contain a
5. Credential Subject
- The credential subject must be a valid Decentralised Identifier (DID). Choose either:
6. Credential Schema
- The VC credential schema(s) must link to valid EBSI credential schemas registered in the Trusted Schemas Registry (TSR). The VC must extend the EBSI base Verifiable Attestation schema. These schemas define the structure and properties of the credentials.
To verify VCs in JSON Web Token (JWT) format, you can either leverage EBSI's Verifiable Credential library or develop your own solution.
The library simplifies the process and ensures optimal security. If you choose not to use the library, follow the VC verification process described above. The example below demonstrates how to verify a VC using the verifyCredentialJwt function in EBSI's library.
Verifying a VC JWT using the verifyCredentialJwt
function in VC library
Expand for the VC example
import {
verifyCredentialJwt,
type VerifyCredentialOptions,
} from "@cef-ebsi/verifiable-credential";
const vcJwt =
"eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QiLCJraWQiOiJkaWQ6ZWJzaTp6eGFZYVV0Yjhwdm9BdFlOV2JLY3ZlZyNDSHhZek9xdDM4U3g2WUJmUFloaUVkZ2N3eldrOXR5N2swTEJhNmg3MG5jIn0.eyJqdGkiOiJ1cm46dXVpZDowMDNhMWRkOC1hNWQyLTQyZWYtODE4Mi1lOTIxYzBhOWYyY2QiLCJzdWIiOiJkaWQ6a2V5OnoyZG16RDgxY2dQeDhWa2k3SmJ1dU1tRllyV1BnWW95dHlrVVozZXlxaHQxajlLYnNOZ2V6dEJGWEVCOUZVWkNvdWZUalhpVFVaWUtrY1AzNmkyWEFRQ3BoZnhCd3ZYRzRkQWFGNnBkd2hyTUd5YUxNQzgxZlU1RUNNbnQ0VmdNUXB3aDNzbjV2U2JVcHdvYVRCTUU3OG5vWEphVExna0N2NUtrTTZWZ0dUZldVakg4WjIiLCJpc3MiOiJkaWQ6ZWJzaTp6eGFZYVV0Yjhwdm9BdFlOV2JLY3ZlZyIsIm5iZiI6MTYzNTcyNDgwMCwiZXhwIjoxOTUzNzYzMjAwLCJpYXQiOjE2MzU1NTIwMDAsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIl0sImlkIjoidXJuOnV1aWQ6MDAzYTFkZDgtYTVkMi00MmVmLTgxODItZTkyMWMwYTlmMmNkIiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlZlcmlmaWFibGVBdHRlc3RhdGlvbiJdLCJpc3N1ZXIiOiJkaWQ6ZWJzaTp6eGFZYVV0Yjhwdm9BdFlOV2JLY3ZlZyIsImlzc3VhbmNlRGF0ZSI6IjIwMjEtMTEtMDFUMDA6MDA6MDBaIiwidmFsaWRGcm9tIjoiMjAyMS0xMS0wMVQwMDowMDowMFoiLCJ2YWxpZFVudGlsIjoiMjA1MC0xMS0wMVQwMDowMDowMFoiLCJleHBpcmF0aW9uRGF0ZSI6IjIwMzEtMTEtMzBUMDA6MDA6MDBaIiwiaXNzdWVkIjoiMjAyMS0xMC0zMFQwMDowMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDprZXk6ejJkbXpEODFjZ1B4OFZraTdKYnV1TW1GWXJXUGdZb3l0eWtVWjNleXFodDFqOUtic05nZXp0QkZYRUI5RlVaQ291ZlRqWGlUVVpZS2tjUDM2aTJYQVFDcGhmeEJ3dlhHNGRBYUY2cGR3aHJNR3lhTE1DODFmVTVFQ01udDRWZ01RcHdoM3NuNXZTYlVwd29hVEJNRTc4bm9YSmFUTGdrQ3Y1S2tNNlZnR1RmV1VqSDhaMiJ9LCJjcmVkZW50aWFsU2NoZW1hIjp7ImlkIjoiaHR0cHM6Ly9hcGktcGlsb3QuZWJzaS5ldS90cnVzdGVkLXNjaGVtYXMtcmVnaXN0cnkvdjMvc2NoZW1hcy96M01nVUZVa2I3MjJ1cTR4M2R2NXlBSm1uTm16REZlSzVVQzh4ODNRb2VMSk0iLCJ0eXBlIjoiRnVsbEpzb25TY2hlbWFWYWxpZGF0b3IyMDIxIn0sInRlcm1zT2ZVc2UiOnsiaWQiOiJodHRwczovL2FwaS1waWxvdC5lYnNpLmV1L3RydXN0ZWQtaXNzdWVycy1yZWdpc3RyeS92NS9pc3N1ZXJzL2RpZDplYnNpOnp4YVlhVXRiOHB2b0F0WU5XYktjdmVnL2F0dHJpYnV0ZXMvYjQwZmQ5YjQwNDQxOGE0NGQyZDk5MTEzNzdhMDMxMzBkZGU0NTBlYjU0NmM3NTViNWI4MGFjZDc4MjkwMmU2ZCIsInR5cGUiOiJJc3N1YW5jZUNlcnRpZmljYXRlIn19fQ.I8Im8azp0pSnM4z_jqGTTfYUg7K802POR2LTJftVfjYtMt82Cik2Z_KGOG7dHhx13R6VGVZKg9134ke1bKhtPw";
const options = {
// REQUIRED. EBSI URI Authority ([userinfo "@"] host [":" port])
ebsiAuthority: "api-pilot.ebsi.eu",
// OPTIONAL. EBSI environment configuration.
// This option allows you to override the default URLs (TIR, DIDR, TSR).
ebsiEnvConfig: {
didRegistry: "https://api-pilot.ebsi.eu/did-registry/v5/identifiers",
trustedIssuersRegistry:
"https://api-pilot.ebsi.eu/trusted-issuers-registry/v5/issuers",
trustedPoliciesRegistry:
"https://api-pilot.ebsi.eu/trusted-policies-registry/v3/users",
},
// OPTIONAL. Timeout after which the requests made by the library will fail. Default: 15 seconds
timeout: 15_000,
// OPTIONAL. List of trusted hostnames. To be used if the Core Services APIs are hosted on a custom host for instance.
// If `trustedHostnames` is not defined, the default trusted domains are: "api-test.ebsi.eu", "api-conformance.ebsi.eu", and "api-pilot.ebsi.eu"
trustedHostnames: ["api.example.net"],
// OPTIONAL. Unix timestamp. Optional comparison date.
// For the JWT to be valid, `nbf` ≤ `validAt` ≤ `exp`.
validAt: 1686048193,
// OPTIONAL. Determines whether or not to validate the issuer's accreditations when `termsOfUse` is missing. Default: false
validateAccreditationWithoutTermsOfUse: false,
// OPTIONAL. Determines whether to validate the accreditations of the VC issuer or not.
// Validation is active by default.
skipAccreditationsValidation: false,
// OPTIONAL. Determines whether to validate the credential status or not.
// Validation is active by default.
skipStatusValidation: false,
} satisfies VerifyCredentialOptions;
const verifiedVc = await verifyCredentialJwt(vcJwt, options);
console.log(verifiedVc);
/*
{
'@context': [ 'https://www.w3.org/2018/credentials/v1' ],
id: 'urn:uuid:003a1dd8-a5d2-42ef-8182-e921c0a9f2cd',
type: [ 'VerifiableCredential', 'VerifiableAttestation' ],
issuer: 'did:ebsi:zxaYaUtb8pvoAtYNWbKcveg',
issuanceDate: '2021-11-01T00:00:00Z',
validFrom: '2021-11-01T00:00:00Z',
validUntil: '2050-11-01T00:00:00Z',
expirationDate: '2031-11-30T00:00:00Z',
issued: '2021-10-30T00:00:00Z',
credentialSubject: {
id: 'did:key:z2dmzD81cgPx8Vki7JbuuMmFYrWPgYoytykUZ3eyqht1j9KbsNgeztBFXEB9FUZCoufTjXiTUZYKkcP36i2XAQCphfxBwvXG4dAaF6pdwhrMGyaLMC81fU5ECMnt4VgMQpwh3sn5vSbUpwoaTBME78noXJaTLgkCv5KkM6VgGTfWUjH8Z2'
},
credentialSchema: {
id: 'https://api-pilot.ebsi.eu/trusted-schemas-registry/v3/schemas/z3MgUFUkb722uq4x3dv5yAJmnNmzDFeK5UC8x83QoeLJM',
type: 'FullJsonSchemaValidator2021'
},
termsOfUse: {
id: 'https://api-pilot.ebsi.eu/trusted-issuers-registry/v5/issuers/did:ebsi:zxaYaUtb8pvoAtYNWbKcveg/attributes/b40fd9b404418a44d2d9911377a03130dde450eb546c755b5b80acd782902e6d',
type: 'IssuanceCertificate'
}
}
*/
Verifiable Presentation JWT Verification Process
The verification process involves examining various data fields and properties of the VP. The following requirements and checks should be considered when validating the presentation:
1. Header
- Ensure the algorithm (
alg
) is ES256, ES256K, Ed25519, or EdDSA. - The
kid
property contains the holder’s DID and the fragment identifier for the verification method.
2. Validating VP payload properties
- Verify the VP payload
id
(optional): Provides a unique identifier for the presentation.type
: Expresses the type of presentation (e.g., VerifiablePresentation). Please note that the first value of thetype
set must beVerifiablePresentation
.verifiableCredential
: Constructed from one or more VC JWTs, all validated individually. Check VC verification process explained above.holder
: A URI for the entity generating the presentation.
For more information on VP properties, refer to this page.
3. Signature Validation
- Validate the signature against the verification method from the DID document corresponding to the VP JWT
kid
header.
4. Credential Subject
- The credential subject must be a valid Decentralised Identifier (DID). Choose either:
The VP subject should match the subject of the credentials included in the VP.
5. Credential Schema
- The VC credential schema(s) must link to valid EBSI credential schemas registered in the TSR. The VP must extend the EBSI base Verifiable Presentation schema. These schemas define the structure and properties of the credentials.
To verify VPs in JSON Web Token (JWT) format, you can either leverage EBSI's Verifiable Presentation library or develop your own solution.
The library simplifies the process and ensures optimal security. If you choose not to use the library, follow the VP verification process described above. The example below demonstrates how to verify a VP using the verifyPresentationJwt function in EBSI's library.
6. Verifying a VP JWT using the verifyPresentationJwt
function in VP library
Expand for the VP example
import {
verifyPresentationJwt,
type VerifyPresentationJwtOptions,
} from "@cef-ebsi/verifiable-presentation";
const vpJwt =
"eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QiLCJraWQiOiJkaWQ6a2V5OnpCaEJMbVlteWlodG9tUmRKSk5FS3piUGo1MW80YTNHWUZlWm9SSFNBQktVd3FkamlRUFkyY3EzTFRHUnEzNlJob1pScWl4MWVxNHVBNDMzUUpheUhkVGk4c3htOHFkYkFiblR5Zzlkc1hDakQ4Tk43RXRjcjRmNTVtUmhuOVQxZDNkNkVjNkhndHBjVWZlbWI0WlZLU0NEYUJyQnlkc3JLQUIzVEtXTlhBa2duejFoc2VlcWY4WSN6QmhCTG1ZbXlpaHRvbVJkSkpORUt6YlBqNTFvNGEzR1lGZVpvUkhTQUJLVXdxZGppUVBZMmNxM0xUR1JxMzZSaG9aUnFpeDFlcTR1QTQzM1FKYXlIZFRpOHN4bThxZGJBYm5UeWc5ZHNYQ2pEOE5ON0V0Y3I0ZjU1bVJobjlUMWQzZDZFYzZIZ3RwY1VmZW1iNFpWS1NDRGFCckJ5ZHNyS0FCM1RLV05YQWtnbnoxaHNlZXFmOFkifQ.eyJqdGkiOiJ1cm46ZGlkOjEyMzQ1NiIsInN1YiI6ImRpZDprZXk6ekJoQkxtWW15aWh0b21SZEpKTkVLemJQajUxbzRhM0dZRmVab1JIU0FCS1V3cWRqaVFQWTJjcTNMVEdScTM2UmhvWlJxaXgxZXE0dUE0MzNRSmF5SGRUaThzeG04cWRiQWJuVHlnOWRzWENqRDhOTjdFdGNyNGY1NW1SaG45VDFkM2Q2RWM2SGd0cGNVZmVtYjRaVktTQ0RhQnJCeWRzcktBQjNUS1dOWEFrZ256MWhzZWVxZjhZIiwiaXNzIjoiZGlkOmtleTp6QmhCTG1ZbXlpaHRvbVJkSkpORUt6YlBqNTFvNGEzR1lGZVpvUkhTQUJLVXdxZGppUVBZMmNxM0xUR1JxMzZSaG9aUnFpeDFlcTR1QTQzM1FKYXlIZFRpOHN4bThxZGJBYm5UeWc5ZHNYQ2pEOE5ON0V0Y3I0ZjU1bVJobjlUMWQzZDZFYzZIZ3RwY1VmZW1iNFpWS1NDRGFCckJ5ZHNyS0FCM1RLV05YQWtnbnoxaHNlZXFmOFkiLCJpYXQiOjE3MDE3ODE5MTUsImF1ZCI6ImRpZDplYnNpOnp3TkFFNXhUaEJwbUdKVVdBWTIza2d4IiwidnAiOnsiaWQiOiJ1cm46ZGlkOjEyMzQ1NiIsIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIl0sInR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiJdLCJob2xkZXIiOiJkaWQ6a2V5OnpCaEJMbVlteWlodG9tUmRKSk5FS3piUGo1MW80YTNHWUZlWm9SSFNBQktVd3FkamlRUFkyY3EzTFRHUnEzNlJob1pScWl4MWVxNHVBNDMzUUpheUhkVGk4c3htOHFkYkFiblR5Zzlkc1hDakQ4Tk43RXRjcjRmNTVtUmhuOVQxZDNkNkVjNkhndHBjVWZlbWI0WlZLU0NEYUJyQnlkc3JLQUIzVEtXTlhBa2duejFoc2VlcWY4WSIsInZlcmlmaWFibGVDcmVkZW50aWFsIjpbImV5SmhiR2NpT2lKRlV6STFOa3NpTENKMGVYQWlPaUpLVjFRaUxDSnJhV1FpT2lKa2FXUTZaV0p6YVRwNmVHRlpZVlYwWWpod2RtOUJkRmxPVjJKTFkzWmxaeU5EU0hoWmVrOXhkRE00VTNnMldVSm1VRmxvYVVWa1oyTjNlbGRyT1hSNU4yc3dURUpoTm1nM01HNWpJbjAuZXlKcWRHa2lPaUoxY200NmRYVnBaRG93TUROaE1XUmtPQzFoTldReUxUUXlaV1l0T0RFNE1pMWxPVEl4WXpCaE9XWXlZMlFpTENKemRXSWlPaUprYVdRNmEyVjVPbnBDYUVKTWJWbHRlV2xvZEc5dFVtUktTazVGUzNwaVVHbzFNVzgwWVROSFdVWmxXbTlTU0ZOQlFrdFZkM0ZrYW1sUlVGa3lZM0V6VEZSSFVuRXpObEpvYjFwU2NXbDRNV1Z4TkhWQk5ETXpVVXBoZVVoa1ZHazRjM2h0T0hGa1lrRmlibFI1Wnpsa2MxaERha1E0VGs0M1JYUmpjalJtTlRWdFVtaHVPVlF4WkROa05rVmpOa2huZEhCalZXWmxiV0kwV2xaTFUwTkVZVUp5UW5sa2MzSkxRVUl6VkV0WFRsaEJhMmR1ZWpGb2MyVmxjV1k0V1NJc0ltbHpjeUk2SW1ScFpEcGxZbk5wT25wNFlWbGhWWFJpT0hCMmIwRjBXVTVYWWt0amRtVm5JaXdpYm1KbUlqb3hOak0xTnpJME9EQXdMQ0psZUhBaU9qRTVOVE0zTmpNeU1EQXNJbWxoZENJNk1UVTVNamd6TlRFd05Dd2lkbU1pT25zaVFHTnZiblJsZUhRaU9sc2lhSFIwY0hNNkx5OTNkM2N1ZHpNdWIzSm5Mekl3TVRndlkzSmxaR1Z1ZEdsaGJITXZkakVpWFN3aWFXUWlPaUoxY200NmRYVnBaRG93TUROaE1XUmtPQzFoTldReUxUUXlaV1l0T0RFNE1pMWxPVEl4WXpCaE9XWXlZMlFpTENKMGVYQmxJanBiSWxabGNtbG1hV0ZpYkdWRGNtVmtaVzUwYVdGc0lpd2lWbVZ5YVdacFlXSnNaVUYwZEdWemRHRjBhVzl1SWwwc0ltbHpjM1ZsY2lJNkltUnBaRHBsWW5OcE9ucDRZVmxoVlhSaU9IQjJiMEYwV1U1WFlrdGpkbVZuSWl3aWFYTnpkV0Z1WTJWRVlYUmxJam9pTWpBeU1TMHhNUzB3TVZRd01Eb3dNRG93TUZvaUxDSjJZV3hwWkVaeWIyMGlPaUl5TURJeExURXhMVEF4VkRBd09qQXdPakF3V2lJc0luWmhiR2xrVlc1MGFXd2lPaUl5TURVd0xURXhMVEF4VkRBd09qQXdPakF3V2lJc0ltVjRjR2x5WVhScGIyNUVZWFJsSWpvaU1qQXpNUzB4TVMwek1GUXdNRG93TURvd01Gb2lMQ0pwYzNOMVpXUWlPaUl5TURJd0xUQTJMVEl5VkRFME9qRXhPalEwV2lJc0ltTnlaV1JsYm5ScFlXeFRkV0pxWldOMElqcDdJbWxrSWpvaVpHbGtPbXRsZVRwNlFtaENURzFaYlhscGFIUnZiVkprU2twT1JVdDZZbEJxTlRGdk5HRXpSMWxHWlZwdlVraFRRVUpMVlhkeFpHcHBVVkJaTW1OeE0weFVSMUp4TXpaU2FHOWFVbkZwZURGbGNUUjFRVFF6TTFGS1lYbElaRlJwT0hONGJUaHhaR0pCWW01VWVXYzVaSE5ZUTJwRU9FNU9OMFYwWTNJMFpqVTFiVkpvYmpsVU1XUXpaRFpGWXpaSVozUndZMVZtWlcxaU5GcFdTMU5EUkdGQ2NrSjVaSE55UzBGQ00xUkxWMDVZUVd0bmJub3hhSE5sWlhGbU9Ga2lmU3dpWTNKbFpHVnVkR2xoYkZOamFHVnRZU0k2ZXlKcFpDSTZJbWgwZEhCek9pOHZZWEJwTFhCcGJHOTBMbVZpYzJrdVpYVXZkSEoxYzNSbFpDMXpZMmhsYldGekxYSmxaMmx6ZEhKNUwzWXpMM05qYUdWdFlYTXZlak5OWjFWR1ZXdGlOekl5ZFhFMGVETmtkalY1UVVwdGJrNXRla1JHWlVzMVZVTTRlRGd6VVc5bFRFcE5JaXdpZEhsd1pTSTZJa1oxYkd4S2MyOXVVMk5vWlcxaFZtRnNhV1JoZEc5eU1qQXlNU0o5TENKMFpYSnRjMDltVlhObElqcDdJbWxrSWpvaWFIUjBjSE02THk5aGNHa3RjR2xzYjNRdVpXSnphUzVsZFM5MGNuVnpkR1ZrTFdsemMzVmxjbk10Y21WbmFYTjBjbmt2ZGpVdmFYTnpkV1Z5Y3k5a2FXUTZaV0p6YVRwNmVHRlpZVlYwWWpod2RtOUJkRmxPVjJKTFkzWmxaeTloZEhSeWFXSjFkR1Z6TDJJME1HWmtPV0kwTURRME1UaGhORFJrTW1RNU9URXhNemMzWVRBek1UTXdaR1JsTkRVd1pXSTFORFpqTnpVMVlqVmlPREJoWTJRM09ESTVNREpsTm1RaUxDSjBlWEJsSWpvaVNYTnpkV0Z1WTJWRFpYSjBhV1pwWTJGMFpTSjlmWDAuZktDUkVzd0c0M184NjJWcjhMM2xKT1JnRk56dk1aMmhSN3A5M2dmRWtoTS1xaElJbFNsUDBBY0FneTBjNnF1Ml8ydUFJQzdtT0duajlBWjNBdTJuTHciXX0sIm5iZiI6MTYzNTcyNDgwMCwiZXhwIjoxOTUzNzYzMjAwfQ.hp99g7ue2m0e2XAJd0Z707UGSpL2kVNGFFaK7CtzUuk0POMPUJBZ6vCKa4AxseQV6dDYSulZMTkOlMNAFdZnxw";
const audience = "did:ebsi:zwNAE5xThBpmGJUWAY23kgx";
const options = {
// REQUIRED. EBSI URI Authority ([userinfo "@"] host [":" port])
ebsiAuthority: "api-pilot.ebsi.eu",
// OPTIONAL. EBSI environment configuration.
// This option allows you to override the default URLs (TIR, DIDR, TSR).
ebsiEnvConfig: {
didRegistry: "https://api-pilot.ebsi.eu/did-registry/v5/identifiers",
trustedIssuersRegistry:
"https://api-pilot.ebsi.eu/trusted-issuers-registry/v5/issuers",
trustedPoliciesRegistry:
"https://api-pilot.ebsi.eu/trusted-policies-registry/v3/users",
},
// OPTIONAL. Timeout after which the requests made by the library will fail. Default: 15 seconds
timeout: 15_000,
// OPTIONAL. List of trusted hostnames. To be used if the Core Services APIs are hosted on a custom host for instance.
// If `trustedHostnames` is not defined, the default trusted domains are: "api-test.ebsi.eu", "api-conformance.ebsi.eu", and "api-pilot.ebsi.eu"
trustedHostnames: ["api.example.net"],
// OPTIONAL. Unix timestamp. Optional comparison date.
// For the JWT to be valid, `nbf` ≤ `validAt` ≤ `exp`.
validAt: 1686048193,
// OPTIONAL. Determines whether or not to validate the issuer's accreditations when `termsOfUse` is missing. Default: false
validateAccreditationWithoutTermsOfUse: false,
// OPTIONAL. Determines whether to validate the accreditations of the VC issuer or not.
// Validation is active by default.
skipAccreditationsValidation: false,
// OPTIONAL. Determines whether to validate the credential status or not.
// Validation is active by default.
skipStatusValidation: false,
// OPTIONAL. Determines whether to validate the signature of the VP JWT or not.
// Validation is active by default.
skipSignatureValidation: false,
// OPTIONAL. Determines whether to validate the resolution of the VP holder DID or not.
// Validation is active by default.
skipHolderDidResolutionValidation: false,
// OPTIONAL. Verification relationship.
// One of "assertionMethod" | "authentication" | "capabilityDelegation" | "capabilityInvocation"
// Default: "authentication"
proofPurpose: "authentication",
} satisfies VerifyPresentationJwtOptions;
const verifiedVp = await verifyPresentationJwt(vpJwt, audience, options);
console.log(verifiedVp);
/*
{
id: 'urn:did:123456',
'@context': [ 'https://www.w3.org/2018/credentials/v1' ],
type: [ 'VerifiablePresentation' ],
holder: 'did:key:zBhBLmYmyihtomRdJJNEKzbPj51o4a3GYFeZoRHSABKUwqdjiQPY2cq3LTGRq36RhoZRqix1eq4uA433QJayHdTi8sxm8qdbAbnTyg9dsXCjD8NN7Etcr4f55mRhn9T1d3d6Ec6HgtpcUfemb4ZVKSCDaBrBydsrKAB3TKWNXAkgnz1hseeqf8Y',
verifiableCredential: [
'eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QiLCJraWQiOiJkaWQ6ZWJzaTp6eGFZYVV0Yjhwdm9BdFlOV2JLY3ZlZyNDSHhZek9xdDM4U3g2WUJmUFloaUVkZ2N3eldrOXR5N2swTEJhNmg3MG5jIn0.eyJqdGkiOiJ1cm46dXVpZDowMDNhMWRkOC1hNWQyLTQyZWYtODE4Mi1lOTIxYzBhOWYyY2QiLCJzdWIiOiJkaWQ6a2V5OnpCaEJMbVlteWlodG9tUmRKSk5FS3piUGo1MW80YTNHWUZlWm9SSFNBQktVd3FkamlRUFkyY3EzTFRHUnEzNlJob1pScWl4MWVxNHVBNDMzUUpheUhkVGk4c3htOHFkYkFiblR5Zzlkc1hDakQ4Tk43RXRjcjRmNTVtUmhuOVQxZDNkNkVjNkhndHBjVWZlbWI0WlZLU0NEYUJyQnlkc3JLQUIzVEtXTlhBa2duejFoc2VlcWY4WSIsImlzcyI6ImRpZDplYnNpOnp4YVlhVXRiOHB2b0F0WU5XYktjdmVnIiwibmJmIjoxNjM1NzI0ODAwLCJleHAiOjE5NTM3NjMyMDAsImlhdCI6MTU5MjgzNTEwNCwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiXSwiaWQiOiJ1cm46dXVpZDowMDNhMWRkOC1hNWQyLTQyZWYtODE4Mi1lOTIxYzBhOWYyY2QiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVmVyaWZpYWJsZUF0dGVzdGF0aW9uIl0sImlzc3VlciI6ImRpZDplYnNpOnp4YVlhVXRiOHB2b0F0WU5XYktjdmVnIiwiaXNzdWFuY2VEYXRlIjoiMjAyMS0xMS0wMVQwMDowMDowMFoiLCJ2YWxpZEZyb20iOiIyMDIxLTExLTAxVDAwOjAwOjAwWiIsInZhbGlkVW50aWwiOiIyMDUwLTExLTAxVDAwOjAwOjAwWiIsImV4cGlyYXRpb25EYXRlIjoiMjAzMS0xMS0zMFQwMDowMDowMFoiLCJpc3N1ZWQiOiIyMDIwLTA2LTIyVDE0OjExOjQ0WiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmtleTp6QmhCTG1ZbXlpaHRvbVJkSkpORUt6YlBqNTFvNGEzR1lGZVpvUkhTQUJLVXdxZGppUVBZMmNxM0xUR1JxMzZSaG9aUnFpeDFlcTR1QTQzM1FKYXlIZFRpOHN4bThxZGJBYm5UeWc5ZHNYQ2pEOE5ON0V0Y3I0ZjU1bVJobjlUMWQzZDZFYzZIZ3RwY1VmZW1iNFpWS1NDRGFCckJ5ZHNyS0FCM1RLV05YQWtnbnoxaHNlZXFmOFkifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHBzOi8vYXBpLXBpbG90LmVic2kuZXUvdHJ1c3RlZC1zY2hlbWFzLXJlZ2lzdHJ5L3YzL3NjaGVtYXMvejNNZ1VGVWtiNzIydXE0eDNkdjV5QUptbk5tekRGZUs1VUM4eDgzUW9lTEpNIiwidHlwZSI6IkZ1bGxKc29uU2NoZW1hVmFsaWRhdG9yMjAyMSJ9LCJ0ZXJtc09mVXNlIjp7ImlkIjoiaHR0cHM6Ly9hcGktcGlsb3QuZWJzaS5ldS90cnVzdGVkLWlzc3VlcnMtcmVnaXN0cnkvdjUvaXNzdWVycy9kaWQ6ZWJzaTp6eGFZYVV0Yjhwdm9BdFlOV2JLY3ZlZy9hdHRyaWJ1dGVzL2I0MGZkOWI0MDQ0MThhNDRkMmQ5OTExMzc3YTAzMTMwZGRlNDUwZWI1NDZjNzU1YjViODBhY2Q3ODI5MDJlNmQiLCJ0eXBlIjoiSXNzdWFuY2VDZXJ0aWZpY2F0ZSJ9fX0.fKCREswG43_862Vr8L3lJORgFNzvMZ2hR7p93gfEkhM-qhIIlSlP0AcAgy0c6qu2_2uAIC7mOGnj9AZ3Au2nLw'
]
}
*/
Mapping JWT to VC/VP properties
For backward compatibility with JWT processors, use the following mappings:
exp
: Represents the expirationDate property (encoded as a UNIX timestamp).iss
: Represents the issuer property of a VC or the holder property of a VP.nbf
: Represents the issuance date (encoded as a UNIX timestamp).jti
: Represents the ID property of the VC or VP.sub
: Represents the ID property contained in the credential subject.aud
: Represents (i.e., identify) the intended audience of the verifiable presentation (i.e., the verifier intended by the presenting holder to receive and verify the verifiable presentation).
The following rules apply to JOSE headers in the context of this specification:
alg
MUST be set for digital signatures. If only the proof property is needed for the chosen signature method (that is, if there is no choice of algorithm within that method), the alg header MUST be set to none.kid
MAY be used if there are multiple keys associated with the issuer of the JWT. The key discovery is outside the scope of this specification. For example, thekid
can refer to a key in a DID document or can be the identifier of a key inside a JWKS.typ
, if present, MUST be set to"JWT"
.
For more information on JWT encoding, please refer here.