Skip to main content
European CommissionEBSI European Blockchain

Issue VC for Trusted Issuer

The hierarchy to issue verifiable credentials is the following:

  • Support Office issues a credential to register a Root Trusted Accreditation Organisations (RootTAO).
  • A RootTAO is the root of a trusted chain and it can issue credentials to register new Trusted Accreditation Organizations (TAO).
  • A TAO can issue credentials to register other Trusted Issuers.

Load the issuer

Load the keys of the Trusted Issuer:

Command
==> using user ES256K did1 <ISSUER_PRIVATE_KEY_ES256K> <ISSUER_DID>
==> using user ES256 did1 <ISSUER_PRIVATE_KEY_ES256> <ISSUER_DID>

Before issuing the credential, run the following commands to set the user accreditation URL and accreditation ID.

Command
==> set user.accreditationUrl ACCREDITATION_URL
==> set user.accreditationId ACCREDITATION_ID
info

ACCREDITATION_URL is the link (located in the Trusted Issuers Registry) to the credential that authorises the entity to issue other credentials.

ACCREDITATION_ID is the terminal segment of the URL, only the identifier.

Now connect the wallet with the pilot environment:

Command
==> env pilot

Define VC payload

Create the reservedAttributeId by computing a random ID:

Command
==> reservedAttributeId: compute randomID
Output - value saved in 'reservedAttributeId'
4ec090a8a660a4bd431cc6d5e50b229cf0812ea8b8f4f642c2f3ad69eb84375f

Now create create a JSON file with the payload of the verifiable credential and set the reservedAttributeId there. The payload of the credential depends on its type. Here are the most typical cases:

  1. VerifiableAuthorisationForTrustChain: VC for RootTAOs
{
"@context": ["https://www.w3.org/2018/credentials/v1"],
"type": [
"VerifiableCredential",
"VerifiableAttestation",
"VerifiableAuthorisationForTrustChain"
],
"issuer": "did:ebsi:zZeKyEJfUTGwajhNyNX928z",
"credentialSubject": {
"id": "did:ebsi:zzcJJuM4Z4AUKdL8kdMEKNw",
"reservedAttributeId": "54bba7597eb82a28ea4e709ac0df2decae02a50a34fb8bb8e46ca87363f55daf"
},
"termsOfUse": {
"id": "https://api-pilot.ebsi.eu/trusted-issuers-registry/v4/issuers/did:ebsi:zZeKyEJfUTGwajhNyNX928z/14bd0d26f3b05d825b91cede8b31068f4d3a3dfda7673e7d36ecfe9f9d402509",
"type": "IssuanceCertificate"
},
"credentialSchema": {
"id": "https://api-pilot.ebsi.eu/trusted-schemas-registry/v2/schemas/z3MgUFUkb722uq4x3dv5yAJmnNmzDFeK5UC8x83QoeLJM",
"type": "FullJsonSchemaValidator2021"
}
}
  1. VerifiableAccreditationToAccredit: VC for TAOs
{
"@context": ["https://www.w3.org/2018/credentials/v1"],
"type": [
"VerifiableCredential",
"VerifiableAttestation",
"VerifiableAccreditation",
"VerifiableAccreditationToAccredit"
],
"issuer": "did:ebsi:zZeKyEJfUTGwajhNyNX928z",
"credentialSubject": {
"id": "did:ebsi:zzcJJuM4Z4AUKdL8kdMEKNw",
"reservedAttributeId": "54bba7597eb82a28ea4e709ac0df2decae02a50a34fb8bb8e46ca87363f55daf"
"accreditedFor": [
{
"schemaId": "https://api-pilot.ebsi.eu/trusted-schemas-registry/v2/schemas/z3MgUFUkb722uq4x3dv5yAJmnNmzDFeK5UC8x83QoeLJM",
"types": [
"VerifiableCredential",
"VerifiableAttestation",
"CTRevocable"
],
"limitJurisdiction": "https://publications.europa.eu/resource/authority/atu/FIN"
}
]
},
"termsOfUse": [
{
"id": "https://api-pilot.ebsi.eu/trusted-issuers-registry/v4/issuers/did:ebsi:zZeKyEJfUTGwajhNyNX928z/14bd0d26f3b05d825b91cede8b31068f4d3a3dfda7673e7d36ecfe9f9d402509",
"type": "IssuanceCertificate"
}
],
"credentialSchema": {
"id": "https://api-pilot.ebsi.eu/trusted-schemas-registry/v2/schemas/zjVFNvbEBPAr3a724DttioZpgZmNr75BBtRzZqk7pkDe",
"type": "FullJsonSchemaValidator2021"
}
}
  1. VerifiableAccreditationToAttest: VC for TIs
{
"@context": ["https://www.w3.org/2018/credentials/v1"],
"type": [
"VerifiableCredential",
"VerifiableAttestation",
"VerifiableAccreditation",
"VerifiableAccreditationToAttest"
],
"issuer": "did:ebsi:zZeKyEJfUTGwajhNyNX928z",
"credentialSubject": {
"id": "did:ebsi:zzcJJuM4Z4AUKdL8kdMEKNw",
"reservedAttributeId": "54bba7597eb82a28ea4e709ac0df2decae02a50a34fb8bb8e46ca87363f55daf"
"accreditedFor": [
{
"schemaId": "https://api-pilot.ebsi.eu/trusted-schemas-registry/v2/schemas/z3MgUFUkb722uq4x3dv5yAJmnNmzDFeK5UC8x83QoeLJM",
"types": [
"VerifiableCredential",
"VerifiableAttestation",
"CTRevocable"
],
"limitJurisdiction": "https://publications.europa.eu/resource/authority/atu/FIN"
}
]
},
"termsOfUse": [
{
"id": "https://api-pilot.ebsi.eu/trusted-issuers-registry/v4/issuers/did:ebsi:zZeKyEJfUTGwajhNyNX928z/14bd0d26f3b05d825b91cede8b31068f4d3a3dfda7673e7d36ecfe9f9d402509",
"type": "IssuanceCertificate"
}
],
"credentialSchema": {
"id": "https://api-pilot.ebsi.eu/trusted-schemas-registry/v2/schemas/zjVFNvbEBPAr3a724DttioZpgZmNr75BBtRzZqk7pkDe",
"type": "FullJsonSchemaValidator2021"
}
}

Now import it in the CLI tool:

Command
==> payloadVc: load path-to-file.json

Create and sign the VC

Use this payload to create and sign the VC:

==> vcIssuer: compute createVcJwt payloadVc {} ES256
Output - value saved in 'vcIssuer'
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImRpZDplYnNpOnpaZUt5RUpmVVRHd2FqaE55Tlg5Mjh6I2tleXMtMiJ9.eyJpYXQiOjE3MDAyMjc0NjMsImp0aSI6InVybjp1dWlkOmQzNDQzMmFkLWQzZjgtNDhhYy05NjBkLTNjNTgzYzAwMDdiZSIsIm5iZiI6MTcwMDIyNzQ2MywiZXhwIjoxNzMxNzYzNDYzLCJzdWIiOiJkaWQ6ZWJzaTp6emNKSnVNNFo0QVVLZEw4a2RNRUtOdyIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIl0sImlkIjoidXJuOnV1aWQ6ZDM0NDMyYWQtZDNmOC00OGFjLTk2MGQtM2M1ODNjMDAwN2JlIiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlZlcmlmaWFibGVBdHRlc3RhdGlvbiIsIlZlcmlmaWFibGVBY2NyZWRpdGF0aW9uIiwiVmVyaWZpYWJsZUFjY3JlZGl0YXRpb25Ub0F0dGVzdCJdLCJpc3N1ZXIiOiJkaWQ6ZWJzaTp6WmVLeUVKZlVUR3dhamhOeU5YOTI4eiIsImlzc3VhbmNlRGF0ZSI6IjIwMjMtMTEtMTdUMTM6MjQ6MjNaIiwiaXNzdWVkIjoiMjAyMy0xMS0xN1QxMzoyNDoyM1oiLCJ2YWxpZEZyb20iOiIyMDIzLTExLTE3VDEzOjI0OjIzWiIsImV4cGlyYXRpb25EYXRlIjoiMjAyNC0xMS0xNlQxMzoyNDoyM1oiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDplYnNpOnp6Y0pKdU00WjRBVUtkTDhrZE1FS053IiwiYWNjcmVkaXRlZEZvciI6W3sic2NoZW1hSWQiOiJodHRwczovL2FwaS1waWxvdC5lYnNpLmV1L3RydXN0ZWQtc2NoZW1hcy1yZWdpc3RyeS92Mi9zY2hlbWFzL3ozTWdVRlVrYjcyMnVxNHgzZHY1eUFKbW5ObXpERmVLNVVDOHg4M1FvZUxKTSIsInR5cGVzIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVmVyaWZpYWJsZUF0dGVzdGF0aW9uIiwiQ1RSZXZvY2FibGUiXSwibGltaXRKdXJpc2RpY3Rpb24iOiJodHRwczovL3B1YmxpY2F0aW9ucy5ldXJvcGEuZXUvcmVzb3VyY2UvYXV0aG9yaXR5L2F0dS9FVVIifV0sInJlc2VydmVkQXR0cmlidXRlSWQiOiI0ZWMwOTBhOGE2NjBhNGJkNDMxY2M2ZDVlNTBiMjI5Y2YwODEyZWE4YjhmNGY2NDJjMmYzYWQ2OWViODQzNzVmIn0sInRlcm1zT2ZVc2UiOnsiaWQiOiJodHRwczovL2FwaS1waWxvdC5lYnNpLmV1L3RydXN0ZWQtaXNzdWVycy1yZWdpc3RyeS92NC9pc3N1ZXJzL2RpZDplYnNpOnpaZUt5RUpmVVRHd2FqaE55Tlg5Mjh6L2F0dHJpYnV0ZXMvMTRiZDBkMjZmM2IwNWQ4MjViOTFjZWRlOGIzMTA2OGY0ZDNhM2RmZGE3NjczZTdkMzZlY2ZlOWY5ZDQwMjUwOSIsInR5cGUiOiJJc3N1YW5jZUNlcnRpZmljYXRlIn0sImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2FwaS1waWxvdC5lYnNpLmV1L3RydXN0ZWQtc2NoZW1hcy1yZWdpc3RyeS92Mi9zY2hlbWFzL3ozTWdVRlVrYjcyMnVxNHgzZHY1eUFKbW5ObXpERmVLNVVDOHg4M1FvZUxKTSIsInR5cGUiOiJGdWxsSnNvblNjaGVtYVZhbGlkYXRvcjIwMjEifX0sImlzcyI6ImRpZDplYnNpOnpaZUt5RUpmVVRHd2FqaE55Tlg5Mjh6In0.51wxF6sasQeNmWt-f8uDhek_To8V3qpzudnZX2COe5t6j8H07lMH6coYVWuQm5xqx09zSNJ0NVm-uSWeBcUCqA

By default, the tool defines the current date as issuance date and 5 years for expiration. If you want to set specific dates, override the payload of the JWT:

Command
==> vcIssuer: compute createVcJwt payloadVc {"iat":1704392000, "exp":1705392000} ES256

Also note that these credentials are signed that these credentials are signed with the ES256 key (not the ES256K key), which is the key that should be used in all credentials.

Request an access token

Request an access token to the authorisation API with the scope tir_write:

Command
==> resAuthTIR: authorisation auth tir_write_presentation ES256
Output - value saved in 'resAuthTIR'
{
"access_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6Inh6bzBsZmQ2TXpJbWRTNGVHbWtDY2hCUVBGbDh5emU1ZjREZFNGWTlxSFEiLCJ0eXAiOiJKV1QifQ.eyJpYXQiOjE3MDAyMjc0NjcsImV4cCI6MTcwMDIzNDY2Nywic3ViIjoiZGlkOmVic2k6elplS3lFSmZVVEd3YWpoTnlOWDkyOHoiLCJhdWQiOiJodHRwczovL2FwaS1waWxvdC5lYnNpLmV1L2F1dGhvcmlzYXRpb24vdjMiLCJzY3AiOiJvcGVuaWQgdGlyX3dyaXRlIiwianRpIjoiYjQyMDdjNGItZDg3Zi00NTk2LWEwNWItZmM2NjRjMjJlNDJiIiwiaXNzIjoiaHR0cHM6Ly9hcGktcGlsb3QuZWJzaS5ldS9hdXRob3Jpc2F0aW9uL3YzIn0.KuX_SUVlrlzh0j_d3Lh0-GGjkjCI4MtRRrDunRu5K-qoD-rimgW90YTvl_x2E2nnXpzWVeL2JrJX6vRx4URVuA",
"token_type": "Bearer",
"expires_in": 7200,
"scope": "openid tir_write",
"id_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6Inh6bzBsZmQ2TXpJbWRTNGVHbWtDY2hCUVBGbDh5emU1ZjREZFNGWTlxSFEiLCJ0eXAiOiJKV1QifQ.eyJpYXQiOjE3MDAyMjc0NjcsImV4cCI6MTcwMDIzNDY2Nywic3ViIjoiZGlkOmVic2k6elplS3lFSmZVVEd3YWpoTnlOWDkyOHoiLCJhdWQiOiJkaWQ6ZWJzaTp6WmVLeUVKZlVUR3dhamhOeU5YOTI4eiIsImp0aSI6IjlhZmYwOTlhLTRmZDMtNDI3Yi04ZmE4LTc3ZjFmOWUzYzQ0NCIsIm5vbmNlIjoiZjkzZmIwZmItN2Q5NS00ZDg1LWJhOTUtMTlmY2E1NTk1ZGZhIiwiaXNzIjoiaHR0cHM6Ly9hcGktcGlsb3QuZWJzaS5ldS9hdXRob3Jpc2F0aW9uL3YzIn0.OBv2Jii94F4PlYPuA5LR0_EXCcrdU3lMmbYBnmHwiVJJluRTVkjJ24nfSBRXVPbwmgcSQN1lkyKxza4Z-mIsbA"
}

Now load the access token:

==> using token resAuthTIR.access_token

Pre-register the VC

Now make the preregistration of the credential in the Trusted Issuers Registry:

Command
==> tir setAttributeMetadata <NEW_ISSUER_DID> reservedAttributeId <ISSUER_TYPE> user.did <USER_ATTRIBUTE_ID>
Output
Issuer did:ebsi:zzcJJuM4Z4AUKdL8kdMEKNw
{
"attributeId": "4ec090a8a660a4bd431cc6d5e50b229cf0812ea8b8f4f642c2f3ad69eb84375f",
"issuerType": "ti"
}

where NEW_ISSUER_DID is the DID of the new issuer, ISSUER_TYPE must be roottao, tao, or ti depending on the case, and USER_ATTRIBUTE_ID is your attribute ID that accredits you to issue this type of credentials.

Congratulations!

You have issued and preregister a new credential for a Trusted Issuer. Now share the credential with the issuer so he can register it.

Script to issue a VC for a Trusted Issuer

The CLI tool is equipped with a script to simplify the process to issue and preregister a VC for a Trusted Issuer. First, setup your wallet and run:

For Root TAO:

Command
==> vcRootTAO: run issueVcRootTAO DID_SUBJECT
==> run preregisterIssuer DID_SUBJECT roottao vcRootTAO

For TAO:

Command
==> vcTAO: run issueVcTAO DID_SUBJECT
==> run preregisterIssuer DID_SUBJECT tao vcTAO

For TI:

Command
==> vcTI: run issueVcTI DID_SUBJECT
==> run preregisterIssuer DID_SUBJECT ti vcTI