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
POST
document to/upload
endpoint 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
....