How to create and use a Webhook

MATTR VII Webhooks enable retrieving information that is generated during an API interaction but is not included in the request or response payloads.

Prerequisites

  • A configured MATTR VII workflow that utilises a supported Webhook event type:

Overview

Creating and using a Webhook hook comprises the following steps:

  1. Create a MATTR VII Webhook.
  2. Verify the Webhook request.
  3. Use the Webhook payload.

Create a MATTR VII Webhook

Request

Make a request of the following structure to create a Webhook:

HTTP
POST /v1/webhooks

Request body

JSON
{
    "events": ["OpenIdCredentialIssued"],
    "url": "https://example.com"
}
  • events : This array includes the event types that will trigger this Webhook. Currently allowed types:
    • OpenIdCredentialIssued : Triggered upon completion of an OpenID4VCI workflow.
    • OpenIdCredentialIssuedSummary : Triggered upon completion of an OpenID4VCI workflow but only provides a summary of the issuance event, leaving out the credential object.
    • OidcIssuerCredentialIssued : Triggered upon completion of an OIDC Bridge issuance flow.
  • url : This is the URL that will receive the Webhook events data payload when they are triggered by MATTR VII for the specified events:
    • Must be a valid URL.
    • Must use the HTTPS protocol.
    • Must not be an IP address.
    • Must not include query parameters or fragments.
    • Non-ASCII characters are normalised.
    • Must return a 2xx response, otherwise it will go through a retry cycle and eventually fail.

Response

JSON
{
    "id": "0c099611-19c4-4f29-8724-6b9e5ba1ef7c",
    "events": ["OpenIdCredentialIssued"],
    "url": "https://example.com",
    "disabled": false
}
  • id : Unique identifier for the created Webhook. You will need it to verify Webhook events.
  • disabled : Set to false by default, indicating the Webhook is active. When set to true the Webhook is disabled and no events are triggered and sent to the defined url. You can disable an active Webhook by making an update request.

Verify Webhook requests

MATTR strongly encourages verifying each Webhook request:

  1. Compare the Webhook id that is generated when creating a MATTR VII Webhook with the webhookId specified in the event payload.
  2. Verify the request HTTP signature.

Verifying HTTP signatures

All MATTR VII Webhook requests are signed using HTTP Message Signatures (an IETF draft standard). You can retrieve the public keys MATTR VII uses to sign the HTTP and use them to verify the HTTP signature.

Request

Make the following request to retrieve the public keys:

HTTP
GET /v1/webhooks/jwks

This endpoint is publicly available by design and does not require authentication.

Response

JSON
{
    "keys": [
        {
            "kty": "OKP",
            "crv": "Ed25519",
            "kid": "1608085995",
            "x": "1NYsB58B9bNmReXqyQR8R_DeJtoLHSW-JsyZVmV2EWQ"
        }
    ]
}
  • kid : Use this key to identify which key a particular HTTP request is signed with.

    You can cache the response as these public keys are not expected to change often.

Verification implementations

  • To facilitate verification of MATTR VII Webhook request, we provide a typescript based library that can be used for verification or serve as a reference implementation to develop a verification SDK in another programming language.
  • An open-source example of using the @mattrglobal/http-signatures library is also available.
  • To learn more about verifying our Webhook requests, have a look at the Open Source MATTR Http-Signatures library.

Use Webhook events payload

The event payload has a common structure in JSON format:

JSON
{
    "deliveryId": "9a8b0b72-5c4f-4925-b101-528edbb5d75d",
    "deliveryTimestamp": "2022-08-30T01:26:38.325Z",
    "webhookId": "5be4f663-af93-41d8-8542-f5c9a2a2d588",
    "event": {
        "id": "de347800-d56f-4262-9f19-52b34856a933",
        "type": "OpenIdCredentialIssued",
        "payload": "{event payload}",
        "timestamp": "2022-08-30T01:26:38.308Z"
    }
}
  • deliveryId : The unique identifier assigned each time the event is delivered to a Webhook endpoint.

  • deliveryTimestamp : The time when the event was delivered.

  • webhookId : The unique Webhook identifier returned in the response during its creation.

  • event : Includes the following event details:

    • id : Unique event identifier.
    • type : Either OpenIdCredentialIssued, OpenIdCredentialIssuedSummary or OidcIssuerCredentialIssued.
    • payload : Contains the specific event data. Refer to Event payloads below for examples.
    • timestamp : Specifies the date/time when the event was created.

    When a Webhook event is sent from MATTR VII, x-mattr-webhook-id and x-mattr-event-type are added as request headers.

    MATTR VII does not guarantee the delivery of events in the exact order that they are generated or that no duplicate events will be received by the Webhook endpoint. You can safeguard against duplicates by checking the event.id that is provided in the event payload, this is a unique identifier for each event generated by MATTR VII. Alternatively, make your event processing idempotent.

Timeout and retry

When a Webhook fails to send data to the configured url, or when a session timeout occurs, a maximum of three retry attempts are made at set intervals. The interval time increases exponentially according to the number of retries that have been attempted. If the Webhook fails to send following the retry attempts, it will be marked as failed.

By default, the Webhook has a response timeout of three seconds. If the server receiving the Webhook event does not respond within this period it is considered a failure.

Event payload

Below are examples of event payloads:

CWT credentials

JSON
{
    "format": "cwt",
    "userId": "7382276d-ef75-4d17-8fb0-1d3aec4647ab",
    "credentialProfile": "compact",
    "credentialConfigurationId": "1d8c7ad7-84ce-4519-8365-7af986e4ee0e",
    "credentialId": "9613ac5e-a0ba-4512-ba0b-90e91b2744bc",
    "userClaims": {
        "Name": "John"
    },
    "credential": "{base64url_encoded_credential}"
}
  • format : Issued credential format (For CWT Credentials this would always be cwt).
  • userId Unique identifier of the user the credential was issued to on the MATTR VII tenant.
  • credentialProfile : Issued credential profile (For CWT credentials this would always be compact).
  • credentialConfigurationId : Unique identifier of the Credential configuration that was used to issue the credential.
  • credentialId : Unique identifier of the issued credential on the MATTR VII tenant.
  • userClaims : Claims that were collected for this user as part of the issuance workflow and persisted on the MATTR VII tenant.
  • credential : Base64 encoded byte[] of the issued CWT credential.

JSON credentials

JSON
{
    "format": "ldp_vc",
    "userId": "64a39a9d-c15b-4c78-9149-30f6376f1fbc",
    "credentialProfile": "web-semantic",
    "credentialConfigurationId": "bddb2a96-8b67-439a-b5af-2818bcfc716f",
    "credentialId": "9613ac5e-a0ba-4512-ba0b-90e91b2744bc",
    "userClaims": {
        "Name": "John"
    },
    "credential": {
        "type": ["VerifiableCredential", "ExampleCredential"]
        //... rest of credential data
    }
}
  • format : Issued credential format (For JSON credentials this would always be ldp_vc).
  • userId Unique identifier of the user the credential was issued to on the MATTR VII tenant.
  • credentialProfile : Issued credential profile (For JSON credentials this would always be web-semantic).
  • credentialConfigurationId : Unique identifier of the Credential configuration that was used to issue the credential.
  • credentialId : Unique identifier of the issued credential on the MATTR VII tenant.
  • userClaims : Claims that were collected for this user as part of the issuance workflow and persisted on the MATTR VII tenant.
  • credential : Signed credential data.

mDocs

JSON
{
    "format": "mso_mdoc",
    "userId": "7382276d-ef75-4d17-8fb0-1d3aec4647ab",
    "credentialProfile": "mobile",
    "credentialConfigurationId": "1d8c7ad7-84ce-4519-8365-7af986e4ee0e",
    "credentialId": "9613ac5e-a0ba-4512-ba0b-90e91b2744bc",
    "userClaims": {
        "Name": "John"
    },
    "credential": "{base64url_encoded_credential}"
}
  • format : Issued credential format (For mDocs this would always be mso_mdoc).
  • userId Unique identifier of the user the credential was issued to on the MATTR VII tenant.
  • credentialProfile : Issued credential profile (For mDocs this would always be mobile).
  • credentialConfigurationId : Unique identifier of the Credential configuration that was used to issue the credential.
  • credentialId : Unique identifier of the issued credential on the MATTR VII tenant.
  • userClaims : Claims that were collected for this user as part of the issuance workflow and persisted on the MATTR VII tenant.
  • credential : Base64 encoded byte[] of the issued mDoc.

MATTR VII does not guarantee the delivery of events in the exact order that they are generated or that no duplicate events will be received by the Webhook endpoint. You can safeguard against duplicates by checking the deliveryId. Alternatively, make your event processing idempotent.