Work in progress
This documentation is WIP and is updated continuously
Integrating Authentic Source with Datastore
This instruction explains how to integrate your Authentic Source (AS) with the vc-up-and-running Datastore using API specification version 2.8 and is using vc_up_and_running TAG 0.5.4.
Prerequisites
- vc-up-and-running is set up locally or the lab environment hosted by SUNET is used
Testing and validating
Here, find good-to-know information when using or testing the API.
TBD: Testing with Mock AS UI
A Mock AS will be provided that can simulate an AS and create credentials.
TBD: Testing with Postman
A Postman collection will be created to simulate an AS for easy testing.
Swagger UI
You can also use the Swagger UI at /swagger/index.html to review the API, and test the various endpoints.
Formatting and validating documents
All documents need to be formatted according to corresponding schema in the document_data{} object. Currently, there is no document verification performed at the API. Using the corresponding JSON schema for your document type, you can validate your created document before sending it to the datastore using check-jsonschema CLI tool (or by other means if preferred):
Schema files are also provided in schemas/.
Validating with check-jsonschema
To install check-jsonschema, follow the instructions provided at PyPI.
Example validating document with check-jsonschema:
check-jsonschema --schemafile schemas/ehic-schema.md /path/to/ehic-document.json
If validation is ok, you will receive the following message:
ok -- validation done
Use cases covered
The following use cases are covered by this instruction:
- Creating EHIC and PD A1 document at datastore for issuance,
- Call notification endpoint to receive data for QR code creation,
- Revoking, and deleting document at datastore,
- Optionally, storing and querying status of consent from pilot test subjects
Creating document at data store /upload
The /upload endpoint handles all document upload to the datastore. For more information, see the API specification.
To create and make a document available for issuance, we will need to perform the following:
- Create EHIC document JSON
- Extend the EHIC document JSON with additional relevant information
POSTdocument to/uploadendpoint at API gateway
Create a JSON object for an EHIC documentÂ
Below is an example EHIC document issued by a german health insurance institution, for subject John Doe, with a unique document_id for this issuer and document_type used later for identity mapping and credential issuance.
{
"competent_institution": {
"institution_country": "DE",
"institution_id": "DE:123456",
"institution_name": "German Health Insurance"
},
"document_id": "EHIC-DE-2024-123456",
"period_entitlement": {
"ending_date": "2025-01-01",
"starting_date": "2024-01-01"
},
"social_security_pin": "1234567890",
"subject": {
"date_of_birth": "1990-05-15",
"family_name": "Doe",
"forename": "John",
"other_elements": {
"family_name_at_birth": "Doe",
"forename_at_birth": "Johnathan",
"sex": "01"
}
}
}
Extend the EHIC document JSON with additional relevant information
Below is the above EHIC document inserted as document_data object alongside required attributes meta and document_data_version. Optional attribute identities included for later identity mapping (this can be excluded and later added using PUT /document/identity.
{
"document_data": {
"competent_institution": {
"institution_country": "DE",
"institution_id": "DE:123456",
"institution_name": "German Health Insurance"
},
"document_id": "EHIC-DE-2024-123456",
"period_entitlement": {
"ending_date": "2025-01-01",
"starting_date": "2024-01-01"
},
"social_security_pin": "1234567890",
"subject": {
"date_of_birth": "1990-05-15",
"family_name": "Doe",
"forename": "John",
"other_elements": {
"family_name_at_birth": "Doe",
"forename_at_birth": "Johnathan",
"sex": "01"
}
}
},
"document_data_version": "1.0.0",
"document_display": {
"description_structured": {
"description_long": "European Health Insurance Card (EHIC) issued by the German health insurance authority",
"valid_from": "1738368800",
"valid_to": "1788368800"
},
"type": "EHIC",
"version": "1.0.0"
},
"identities": [
{
"authentic_source_person_id": "12345",
"birth_city": "Berlin",
"birth_country": "Germany",
"birth_date": "1990-05-15",
"family_name": "John",
"given_name": "Doe",
"schema": {
"name": "DE",
"version": "1.0.0"
}
}
],
"meta": {
"authentic_source": "DE-AS",
"collect": {
"id": "COLL-987654",
"valid_until": 1750000000
},
"credential_valid_from": 1738368800,
"credential_valid_to": 1758368800,
"document_id": "EHIC-DE-2024-123456",
"document_type": "EHIC",
"document_version": "1.0.0",
"real_data": false
}
}
The collect attribute id set will be used in later stage for creating the credential. If this value is omitted, the document_id value will be used instead.
Note: currently in 0.5.4, not including collect information in meta attribute results in 500 internal server error.
POST document to /upload endpoint at API gateway
Now we can post the document to the API gateway for storage in data store. Save the previous JSON data as a json file, i.e. data.json.
curl -X 'POST' \ 'http://localhost:8080/api/v1/upload' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d @data.json
Get created document for verification
To verify document upload, you can use POST /document to retrieve information about your newly created document.
The POST /document requires the following attributes:
{
"authentic_source": "DE-AS",
"document_id": "EHIC-DE-2024-123456",
"document_type": "EHIC"
}
Now send POST with the above contents matching your created document to /document endpoint:
curl -X 'POST' \ 'http://localhost:8080/api/v1/document' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d @get.json
This will return 200 OK with the following contents:
{
"data": {
"meta": {
"authentic_source": "DE-AS",
"document_version": "1.0.0",
"document_type": "EHIC",
"document_id": "EHIC-DE-2024-123456",
"real_data": false,
"collect": {
"id": "COLL-987654",
"valid_until": 1750000000
},
"revocation": {
"id": "EHIC-DE-2024-123456",
"reference": {}
},
"credential_valid_from": 1738368800,
"credential_valid_to": 1758368800
},
"document_data": {
"competent_institution": {
"institution_country": "DE",
"institution_id": "DE:123456",
"institution_name": "German Health Insurance"
},
"document_id": "EHIC-DE-2024-123456",
"period_entitlement": {
"ending_date": "2025-01-01",
"starting_date": "2024-01-01"
},
"social_security_pin": "1234567890",
"subject": {
"date_of_birth": "1990-05-15",
"family_name": "Doe",
"forename": "John",
"other_elements": {
"family_name_at_birth": "Doe",
"forename_at_birth": "Johnathan",
"sex": "01"
}
}
}
}
}
Create credential from document
Now that the document is created, we can create an issuable SD-JWT credential by sending a POST to /credential endpoint and including the collect_id previously created. If previously omitted in the upload, the document_id is used.
Save your contents in the below format as credential.json
{
"authentic_source": "DE-AS",
"collect_id": "COLL-987654",
"credential_type": "SD-JWT",
"document_type": "EHIC",
"identity": {
"authentic_source_person_id": "12345",
"schema": {
"name": "DE",
"version": "1.0.0"
}
}
}
POST the file to /credential endpoint
curl -X 'POST' \ 'http://localhost:8080/api/v1/credential' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d @credential.json
This will return 200 OK with the created SD-JWT credential:
{
"jwt": "eyJhbGciOiJFUzI1NiIsInR5cCI6InNkLWp3dCJ9.eyJfc2RfYWxnIjoic2hhLTI1NiIsImNhcmRIb2xkZXIiOnsiX3NkIjpbIllUTTVaV0kyTTJaa1kyVTNZVGMxTW1SaVltUmlPVEJsTnpWaE1HVXhaRFV4WkdWaU5tTmxOVEZrTkRWaVpHWXpObVF6WWpjeFptWXhNRGxqTVdJeFl3IiwiWm1NMllUUmxNRFF5WmprME1HWTRPR016TVdJeU5ERmtNamd5WkdNMFlUbG1ZV1kxTURrMVltWTBabUV6TTJKalpUUmpORGswTWpOaU1qazROVFEwWkEiLCJaVEF5WlRjd1pUSmtZak0xWTJZNE9XUmxORE14TVRnM00yTTJNekF4TkRGak56YzJOR1UzTTJFeE4yTXhaR0ZqTXpkbVpHVmxOMlk1T1dVeE9UUm1PQSJdLCJjYXJkaG9sZGVyU3RhdHVzIjoiIiwiaWQiOiIifSwiY2FyZEluZm9ybWF0aW9uIjp7ImV4cGlyeURhdGUiOiIiLCJpZCI6IiIsImludmFsaWRTaW5jZSI6IiIsImlzc3VhbmNlRGF0ZSI6IiIsInNpZ25hdHVyZSI6eyJpc3N1ZXIiOiIiLCJzZWFsIjoiIn0sInZhbGlkU2luY2UiOiIifSwiY25mIjp7Imp3ayI6eyJjcnYiOiJQLTI1NiIsImQiOiJhZ2VTenJITm1yeTVCblFlSHRwRDRQamV3OHljY0tXY1pjTUw0ejNOcmM4Iiwia2lkIjoic2luZ2luZ18iLCJrdHkiOiJFQyIsIngiOiI5X3RBRVB1cVJBR2lLZmxKbHJYREtVRU1nc0ZXN3dWZWNvazQ4bW9mTW9VIiwieSI6Ik9BWFZIaG4wZGpqYzYwNm9WbGlWQzR4aTZvNGd6TXdkcEVpa2FPejV1QUkifX0sImNvbXBldGVudEluc3RpdHV0aW9uIjp7ImlkIjoiIiwiaW5zdGl0dXRpb25OYW1lIjoiIn0sImV4cCI6MTczMDIxNjQ4NiwiaXNzIjoiaHR0cHM6Ly9pc3N1ZXIuc3VuZXQuc2UiLCJuYmYiOjE3MzAyMTI4ODYsInBpZCI6eyJleGhpYml0b3JJRCI6IiIsImZpcnN0TmFtZSI6IiIsImdlbmRlciI6IiIsImxhc3ROYW1lIjoiIn0sInNpZ25hdHVyZSI6eyJpc3N1ZXIiOiIiLCJzZWFsIjoiIn0sInN0YXR1cyI6IiIsInZjdCI6Imh0dHBzOi8vY3JlZGVudGlhbC5zdW5ldC5zZS9pZGVudGl0eV9jcmVkZW50aWFsIn0.n7HqVZ69HyWwNxnhjO7Io2PDTVnjo-GS159w0Z0HklxTAcNMq1MC82FK1UuLmDyw3Ibj4fqbbjuO7ummDSNxtA",
"disclosures": [
"WyJPVXhDSW54ek5DeDRaM3hSV0U5N1VWZyIsImZhbWlseU5hbWUiLCIiXQ",
"WyJQUzlIUGtOblhESWhaU0ZIWENKWWJGRSIsImJpcnRoRGF0ZSIsIiJd",
"WyJTa3RiYUNaaFBERnBRU1kwUlc0dUlsQSIsImdpdmVuTmFtZSIsIiJd"
]
}
Get QR code from /notification
....