SSI Issuance Integration

This documentation will guide you through the process of integrating Gataca Studio with your application for an issuance process, providing you with step-by-step instructions, code snippets, and other helpful resources.

The integration consists of several API calls, so we will guide you through the structure of the API endpoint and the data structure necessary to understand the request.

Sequence Diagram

The diagram below illustrates the SSI Verifiable Credential Issuance flow. This documentation will only focus on the steps relevant to the integration process.

  • User Wallet: Gataca

  • Relying Party App (also known as a service provider): refers to the web or mobile application that requires authentication from a user - this is your organization.

  • Certify: Issuance component in Gataca Studio

Integration process

Authentication request

To start the integration process, you must have already created an issuance template and an API Key in Gataca Studio.

The majority of Gataca endpoints are protected to avoid unauthorized access and security issues. This protection is based on access tokens issued using basic authentication.

To obtain the corresponding access token to use any of the protected endpoints, it is necessary to use the following API call in your application:

curl --request POST 'https://nucleus.gataca.io/admin/v1/api_keys/login' \
    --header 'Authorization: Basic [AUTH]'
  • AUTH: base64(api-key id:api-key secret) - You must provide the API Key ID (UUID) and secret given when creating the API Key in Studio, encoded in base64 format in the HTTP request header.

The response of this endpoint is:

{
    "message": "SUCCESS"
}
  • Status code: 200. If the authentication is rejected, the status code will be 403.

  • Header.Token: Access token received to access the protected endpoints.

  • Header.Token_type: Type of token used by Gataca. By default, it is jwt (JSON Web Token).

You will need the access token in the following steps, so make sure to copy it.

Generate Issuance Process (Sequence diagram Step 2)

The token received in the previous step must be used to generate a new session.

curl --request POST 'https://certify.gataca.io/api/v1/issuanceRequests' \
    --header 'Authorization: [TOKEN_TYPE] [APP_TOKEN]' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "group": "[SSI_TEMPLATE_ID]"
    }'
  • TOKEN_TYPE: Type of token received from the authentication call. Currently, GATACA always uses jwt.

  • APP_TOKEN: Access token received from the authentication call (This authentication must be executed by an application linked to that TENANT, not an administrator).

  • SSI_TEMPLATE_ID: Identifier of the template used for this verification. These identifiers are configured in Studio.

The response (Step 3) is:

{
    "additionalData": "[VC_TYPE]",
    "callback": "https://[CALLBACK_HOST]",
    "id": "2xuEMaSrrxsTMyaioJuSMKejfCyBim7g",
    "nonce": "25rbiezf6aKoZzRLkfLYH72DgYWDwdNG",
    "proof": [
        {
            "challenge": "31CAw5WKkZk3dFfwGv32WgLddchHUonf",
            "created": "2021-06-07T10:24:28Z",
            "creator": "did:gatc:29YTmCCBDg...Wrs8zkVs7s#keys-1",
            "domain": "gataca.io",
            "proofPurpose": "authentication",
            "proofValue": "jPwJKhJWUk...7ysbWJWUkJgmu7--",
            "type": "Ed25519Signature2018",
            "verificationMethod": "did:gatc:29YTmCCB...rs8zkVs7s#keys-1"
        }
    ],
    "requested": [
        {
            "mandatory": true,
            "purpose": "authentication",
            "trustLevel": 2,
            "type": "academicInstitutionCredential"
        },
        {
            "mandatory": true,
            "purpose": "authentication",
            "trustLevel": 2,
            "type": "studentIdCredential"
        },
        {
            "mandatory": false,
            "purpose": "application",
            "trustLevel": 0,
            "type": "lastNameCredential"
        },
        {
            "mandatory": false,
            "purpose": "application",
            "trustLevel": 0,
            "type": "firstNameCredential"
        }
    ]
}
  • VC_TYPE: the response will specify the credential type we want to issue.

  • CALLBACK_HOST: URL the user wallet will use to share the information with Studio.

This response is too big to be displayed in a QR code, so only the ID is shown to represent the issuance process in the QR code (In this case, 2xuEMaSrrxsTMyaioJuSMKejfCyBim7g). This session identifier is required for the following step, so make sure to copy it.

This response requests four different VC types.

  • University name: academicInstitutionCredential

  • Student identifier: studentIdCredential

  • Student last name: lastNameCredential

  • Student first name: firstNameCredential

The structure of the Verifiable Credential shows the credential type, the trust level (if the credential needs to be issued by a trusted issuer or it can be issued by any or self-attested), the purpose for requesting the credential, and if the credential is requested mandatorily or optionally.

The session generation step can be automatic using GatacaQR, a JavaScript component allowing any relying party to generate a session in a simple way.

You will find the GatacaQR component code repositories at the end of this documentation.

Get information from the issuance process (Sequence diagram Steps 14 & 21)

In order to verify if the relying party has completed the issuance process or to validate any new issuance processes, it is essential to utilize this endpoint, which will provide all issuance requests:

curl --request GET 'https://certify.gataca.io/admin/v1/issuanceRequests' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: [TOKEN_TYPE] [TOKEN]'
  • TOKEN_TYPE: Type of token received from the authentication call. Currently, Gataca always uses jwt.

  • TOKEN: Access token received from the authentication call.

This endpoint could be used to filter the results by status with this query param:

curl --request GET 'https://certify.gataca.io/admin/v1/issuanceRequests?status=ISSUED' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: [TOKEN_TYPE] [TOKEN]'

The response is an array of issuance processes as follows:

[{
    "id": "25shTZfXmens1EYrgLBoTZpSgNKUXnLt",
    "status": "ISSUED",
    "group": "dnidemo",
    "data": [{
        "credentialStatus": {
          "id": "https://certify.gataca.io:9090/api/v1/group/dnidemo/status",
          "type": "CredentialStatusList2017"
        },
        "credentialSubject": {
          "firstName": "Samuel",
          "id": "did:gatc:M2VhNjU2MzI...kOTdiNWMzZGI1"
        },
        "id": "cred:gatc:g6hn7m...nvd4ukr61j43d",
        "issuer": "did:gatc:32Zn2...yfVJvRcwikVFu1Pa",
        "type": [
          "VerifiableCredential",
          "firstNameCredential"
        ]
      }
    ],
    "validator": {
      "id": "25shTZfXmens1EYrgLBoTZpSgNKUXnLt",
      "securityMechanisms": {
        "@context": [
          "https://www.w3.org/2018/credentials/v1"
        ],
        "proof": [],
        "type": [
          "VerifiablePresentation",
          "GatacaCredentialPresentation"
        ]
      },
      "verifiablePresentation": {
        "@context": [
          "https://www.w3.org/2018/credentials/v1"
        ],
        "proof": [{
          "created": "2020-10-09T08:12:46Z",
          "creator": "did:gatc:M2VhNjU2MzI3NT...WMzZGI1#keys-1",
          "proofPurpose": "authentication",
          "proofValue": "9tEN6NmIovJxk9v7gChoVy...HbckK8ZXh9tMrCQ",
          "type": "Ed25519Signature2018"
        }],
        "type": [
          "VerifiablePresentation",
          "GatacaCredentialPresentation"
        ],
        "verifiableCredential": [{
          "credentialSubject": {
            "email": "samuel@gataca.io",
            "id": "did:gatc:M2VhNjU2...kOTdiNWMzZGI1"
          },
          "id": "cred:gatc:ZGU5NGQ4MzFi...TMzNWQwODky",
          "issuanceDate": "2020-10-07T10:15:03Z",
          "issuer": "did:gatc:acYseLtTEVeqF8...77uCKqyM3imEJH",
          "proof": [{
            "created": "2020-10-07T10:15:03Z",
            "creator": "did:gatc:24gsRbsURij3edo...hggrnR#keys-1",
            "proofPurpose": "authentication",
            "proofValue": "wpQJlNwZfHUNesE...2KpGt4ygTJfzdBA",
            "type": "Ed25519Signature2018"
          }],
          "type": [
            "VerifiableCredential",
            "emailCredential"
          ]
        }]
      }
    },
    "createdAt": "2020-10-09T08:12:29.134017Z",
    "updatedAt": "2020-10-09T08:24:54.53356Z"
  }
]

Information structure:

  • Issuance process metadata: Identifier, type, dates, and status

  • Status meaning:

    • PENDING: Session has been created, but there is no info associated.

    • ISSUED: Verifiable Credentials (VCs) associated with a specific issuance process have been downloaded.

    • REJECTED: The issuance process has been rejected by the issuer.

  • Data: This field includes the new verifiable credentials issued by the relying party. This field is filled when the issuance process is updated to an ISSUED status.

  • Validator: This field includes all the information shared by the end user and requested by the relying party to be authenticated into Studio.

Alternative - Get information from the issuance process (Steps 14 and 21)

Getting the information from a specific issuance process is also possible using the command below. Instead of getting the information from a set of issuance processes, this command gets the information from a specific issuance process (using the process identifier).

curl --request GET 'https://certify.gataca.io/admin/v1/issuanceRequests/[ISSUANCE_PROCESS_ID]' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: [TOKEN_TPE] [APP_TOKEN]'
  • ISSUANCE_PROCESS_ID: Issuance process identifier used by the end user to request new VCs.

  • TOKEN_TYPE: Type of token received from the authentication call. Currently, GATACA always uses jwt.

  • APP_TOKEN: Access token received from the authentication call. (This authentication must be executed by an app related to that issuance process, not an administrator).

The response contains an issuance process instead of an issuance process array:

{
  "id": "25shTZfXmens1EYrgLBoTZpSgNKUXnLt",
  "status": "ISSUED",
  "group": "dnidemo",
  "data": [{
    "credentialStatus": {
      "id": "https://certify.gataca.io:9090/api/v1/group/dnidemo/status",
      "type": "CredentialStatusList2017"
    },
    "credentialSubject": {
      "firstName": "Samuel",
      "id": "did:gatc:M2VhNjU2MzI...kOTdiNWMzZGI1"
    },
    "id": "cred:gatc:g6hn7m...nvd4ukr61j43d",
    "issuer": "did:gatc:32Zn2...yfVJvRcwikVFu1Pa",
    "type": [
      "VerifiableCredential",
      "firstNameCredential"
    ]
  }],
  "validator": {
    "id": "25shTZfXmens1EYrgLBoTZpSgNKUXnLt",
    "securityMechanisms": {
      "@context": [
        "https://www.w3.org/2018/credentials/v1"
      ],
      "proof": [],
      "type": [
        "VerifiablePresentation",
        "GatacaCredentialPresentation"
      ]
    },
    "verifiablePresentation": {
      "@context": [
        "https://www.w3.org/2018/credentials/v1"
      ],
      "proof": [{
        "created": "2020-10-09T08:12:46Z",
        "creator": "did:gatc:M2VhNjU2MzI3NT...WMzZGI1#keys-1",
        "proofPurpose": "authentication",
        "proofValue": "9tEN6NmIovJxk9v7gChoVy...HbckK8ZXh9tMrCQ",
        "type": "Ed25519Signature2018"
      }],
      "type": [
        "VerifiablePresentation",
        "GatacaCredentialPresentation"
      ],
      "verifiableCredential": [{
        "credentialSubject": {
          "email": "samuel@gataca.io",
          "id": "did:gatc:M2VhNjU2...kOTdiNWMzZGI1"
        },
        "id": "cred:gatc:ZGU5NGQ4MzFi...TMzNWQwODky",
        "issuanceDate": "2020-10-07T10:15:03Z",
        "issuer": "did:gatc:acYseLtTEVeqF8...77uCKqyM3imEJH",
        "proof": [{
          "created": "2020-10-07T10:15:03Z",
          "creator": "did:gatc:24gsRbsURij3edo...hggrnR#keys-1",
          "proofPurpose": "authentication",
          "proofValue": "wpQJlNwZfHUNesE...2KpGt4ygTJfzdBA",
          "type": "Ed25519Signature2018"
        }],
        "type": [
          "VerifiableCredential",
          "emailCredential"
        ]
      }]
    }
  },
  "createdAt": "2020-10-09T08:12:29.134017Z",
  "updatedAt": "2020-10-09T08:24:54.53356Z"
}

Information structure:

  • Issuance process metadata: Identifier, type, dates, and status

  • Status meaning:

    • PENDING: Session has been created, but there is no info associated.

    • ISSUED: Verifiable Credentials (VCs) associated with a specific issuance process have been downloaded.

    • REJECTED: The issuance process has been rejected by the issuer.

  • Data: This field includes the new verifiable credentials issued by the relying party. This field is filled when the issuance process is updated to an ISSUED status.

  • Validator: This field includes all the information shared by the end user and requested by the relying party to be authenticated into Studio.

Issuing a new verifiable credential (Sequence Diagram Steps 18 and 23)

Once the Relying Party has validated the information, it should issue the new VC. To do this, the relying party fills in the information related to the new VCs based on the issuance process.

To fill the new VC, it is necessary to call the following endpoint:

curl --request PATCH 'https://certify.gataca.io/admin/v1/issuanceRequests/[ISSUANCE_PROCESS_ID]/credentials' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: [TOKEN_TYPE] [APP_TOKEN]' \
    --data-raw '[
        {
          "credentialSubject": {
            "documentType": "Passport",
            "firstName": "Luke",
            "lastName": "Skywalker",
            "identifier": "XXXXXXXXX",
            "dateOfBirth": "25-05-1977"
          },
        }
    ]'
 

The schema for each verifiable credential type is in Studio. Getting the schema from the Studio responses (credential schema) is also possible.

Each VC is composed of the following:

  • credentialSubject: This is a map of fields that includes the values for that credential. Inside this object is the option to attach the id of the holder (DID) and the properties for that kind of credential.

It is also possible to get the holder's DID from the previous steps (Steps 14 and 21). This is included in the property validator (Presentation Response).

Ref: verifiablePresentationproofcreator

Note: It’s important to remove the last part #keys-n

In the example: did:gatc:M2VhNjU2MzI3NT...WMzZGI1

For each VC credential, it is possible to have the following information:

  • id (optional): Identifier of the VC created. It MUST be unique, so creating a new random string for each VC is necessary.

  • issuer (optional): DID of the issuer issuing the VC.

  • issuanceDate (optional): Date when the VC has been issued.

  • validFrom (optional): Date when the VC takes value.

  • credentialSchema (optional): Schema used to issue the VC, instead of using the type. In that case, the type should be VerifiableID or VerifiableAttestation.

  • evidence (optional): Property to note how the identification has been made before issuing the VC.

  • context (optional): Indicates the context used to issue the VC. There are some of them by default, but they can be overridden.

Studio will add some of the optional information if the Relying Party does not specify these.

The response is an array of issuance process as follows:

[{
    "id": "25shTZfXmens1EYrgLBoTZpSgNKUXnLt",
    "status": "ISSUED",
    "group": "dnidemo",
    "data": [{
      "@context": ["https://www.w3.org/2018/credentials/v1"],
      "id": "cred:gatc:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "type": [
        "VerifiableCredential",
        "vIdCredential"
      ],
      "issuer": "did:gatc:acYseLtTEVeqF8...77uCKqyM3imEJH",
      "issuanceDate": "2018-06-21T17:05:23Z",
      "validFrom": "2018-06-21T17:05:23Z",
      "credentialSubject": {
        "id": "did:gatc:M2VhNjU2MzI...kOTdiNWMzZGI1",
        "documentType": "Passport",
        "firstName": "Luke",
        "lastName": "Skywalker",
        "identifier": "XXXXXXXXX",
        "dateOfBirth": "25-05-1977"
      },
      "credentialStatus": {
        "id": "https://base-uri/api/v1/group/dnidemo/status",
        "type": "CredentialStatusList2020"
      },
      "credentialSchema": {
        "id": "https://base-uri/tsr/verifiableid1.json",
        "type": "JsonSchemaValidator2018"
      },
      "evidence": {
        "id": "https://base-uri/evidence/fsdakflasdjlfkas",
        "type": [
          "DocumentVerification",
          "PassportVerification"
        ],
        "verifier": "did:ebsi:32Zn2k5DJPG5oxiFyfVJvRcwikVFu1Pa",
        "subjectPresence": "Physical",
        "documentPresence": "Physical",
        "evidenceDocument": {
          "type": "Passport",
          "documentCode": "P",
          "documentNumber": "SPECI2014",
          "documentIssuingState": "NLD",
          "documentExpirationDate": "2031-06-25T15:06:07Z"
        }
      }
    }],
    "validator": {
      "id": "25shTZfXmens1EYrgLBoTZpSgNKUXnLt",
      "securityMechanisms": {
        "@context": [
          "https://www.w3.org/2018/credentials/v1"
        ],
        "proof": [],
        "type": [
          "VerifiablePresentation",
          "GatacaCredentialPresentation"
        ]
      },
      "verifiablePresentation": {
        "@context": [
          "https://www.w3.org/2018/credentials/v1"
        ],
        "proof": [{
          "created": "2020-10-09T08:12:46Z",
          "creator": "did:gatc:M2VhNjU2MzI3NT...WMzZGI1#keys-1",
          "proofPurpose": "authentication",
          "proofValue": "9tEN6NmIovJxk9v7gChoVy...HbckK8ZXh9tMrCQ",
          "type": "Ed25519Signature2018"
        }],
        "type": [
          "VerifiablePresentation",
          "GatacaCredentialPresentation"
        ],
        "verifiableCredential": [{
          "credentialSubject": {
            "email": "samuel@gataca.io",
            "id": "did:gatc:M2VhNjU2...kOTdiNWMzZGI1"
          },
          "id": "cred:gatc:ZGU5NGQ4MzFi...TMzNWQwODky",
          "issuanceDate": "2020-10-07T10:15:03Z",
          "issuer": "did:gatc:acYseLtTEVeqF8...77uCKqyM3imEJH",
          "proof": [{
            "created": "2020-10-07T10:15:03Z",
            "creator": "did:gatc:24gsRbsURij3edo...hggrnR#keys-1",
            "proofPurpose": "authentication",
            "proofValue": "wpQJlNwZfHUNesE...2KpGt4ygTJfzdBA",
            "type": "Ed25519Signature2018"
          }],
          "type": [
            "VerifiableCredential",
            "emailCredential"
          ]
        }]
      }
    },
    "createdAt": "2020-10-09T08:12:29.134017Z",
    "updatedAt": "2020-10-09T08:24:54.53356Z"
  }
]

Each entry result is divided in the following manner:

  • Issuance process metadata: Identifier, type, dates, and status (PENDING, ISSUED, REJECTED).

  • Data: This field includes the new verifiable credentials issued by the relying party. This field is filled when the issuance process is updated to a status of ISSUED.

  • Validator: This field includes all the information shared by the end user and requested by the relying party to be authenticated into Studio.


GatacaQR component

Instead of manually doing the previous process, you can also use GatacaQR. This JavaScript component implements a set of features to allow any relying party to execute the session generation in a simple way.

These repositories contain developer manuals on using the GatacaQR component:

GitHub: GitHub - gataca-io/gataca-QR


API Documentation with Swagger

Last updated