Events API

Webhooks

13min

Events are exposed and dispatched through our webhooks service where the vendor platform user can configure an endpoint listener and a list of events happening in your LicenseSpring account which will be dispatched to that endpoint URL. HTTPS is used to send webhook events to your app as a JSON payload.

This is Enterprise feature only. For more information, please contact sales.

Setup

Webhooks can be configured in the vendor platform under Settings > Webhooks.

To start receiving webhook events in your app you need to create and register a webhook endpoint using the webhooks dashboard. Set up an HTTPS endpoint function that can accept webhook requests so that it handles POST requests with a JSON payload consisting of an event object.

Webhook configuration panel
Webhook configuration panel


Along with configuration view, the webhooks panel will display history of sent events and option to rollover the secret key needed to verify the webhook data authenticity.

Webhook details view
Webhook details view


Instructions

Handle duplicate events

Webhook endpoints might occasionally receive the same event more than once. You can guard against duplicated event receipts by making your event processing idempotent. One way of doing this is logging the events you’ve processed, and then not processing already-logged events.

Only listen to event types your integration requires

Configure your webhook endpoints to receive only the types of events required by your integration. Listening for extra events (or all events) puts undue strain on your server and we don’t recommend it.

Receive events with an HTTPS server

If you use an HTTPS URL for your webhook endpoint, LicenseSpring validates that the connection to your server is secure before sending your webhook data. For this to work, your server must be correctly configured to support HTTPS with a valid server certificate.

Roll endpoint signing secrets periodically

The secret key used for verifying that events come from LicenseSpring is rollable. You can choose to immediately expire the current secret key or delay its expiration for up to 24 hours to allow yourself time to update the verification code on your server. During this time, multiple secrets are active for the endpoint. LicenseSpring generates one signature per secret until expiration. To keep them safe, we recommend that you roll secret keys periodically, or when you suspect a compromised secret key.

Verify events are sent from LicenseSpring

Verify webhook signatures to confirm that received events are sent from LicenseSpring. LicenseSpring signs webhook events it sends to your endpoints by including a signature in each event’s Licensespring-Signature header. This allows you to verify that the events were sent by LicenseSpring, not by a third party. You can verify signatures either using our official libraries, or verify manually using your own solution. The secret key for each endpoint can be found in the webhooks dashboard.

Verifying signatures using our official SDKs

At the moment, verification of a webhook signature is included in Python SDK only.

You perform the verification by providing the event payload, the Licensespring-Signature header, and the endpoint’s secret. If verification fails, you get an error. LicenseSpring requires the raw body of the request to perform signature verification. If you’re using a framework, make sure it doesn’t manipulate the raw body. Any manipulation to the raw body of the request causes the verification to fail.

Python


Verifying signatures manually

The Licensespring-Signature header included in each signed event contains a timestamp and one or more signatures that you must verify. The timestamp is prefixed by t=, and each signature is prefixed by a scheme. Schemes start with v, followed by an integer. Currently, the only valid live signature scheme is v1.

Text


LicenseSpring generates signatures using a hash-based message authentication code (HMAC) with SHA-256. To prevent downgrade attacks, ignore all schemes that are not v1.

You can have multiple signatures with the same scheme-secret pair when you roll an endpoint’s secret, and keep the previous secret active for up to 24 hours. During this time, your endpoint has multiple active secrets and LicenseSpring generates one signature for each secret.

To create a manual solution for verifying signatures, you must complete the following steps:

Step 1: Extract the timestamp and signatures from the header

Split the header using the , character as the separator to get a list of elements. Then split each element using the = character as the separator to get a prefix and value pair.

The value for the prefix t corresponds to the timestamp, and v1 corresponds to the signature (or signatures). You can discard all other elements.

Step 2: Prepare the string

The signed_payload string is created by concatenating:

  • The timestamp (as a string)
  • The character .
  • The actual JSON payload (that is, the request body)

Step 3: Determine the expected signature

Compute an HMAC with the SHA256 hash function. Use the endpoint’s signing secret as the key, and use the signed_payload string as the message.

Step 4: Compare the signatures

Compare the signature (or signatures) in the header to the expected signature. For an equality match, compute the difference between the current timestamp and the received timestamp, then decide if the difference is within your tolerance.

Python
JS


Preventing replay attacks

A replay attack is when an attacker intercepts a valid payload and its signature, then re-transmits them. To mitigate such attacks, LicenseSpring includes a timestamp in the Licensespring-Signature header. Because this timestamp is part of the signed payload, it’s also verified by the signature, so an attacker can’t change the timestamp without invalidating the signature. If the signature is valid but the timestamp is too old, you can have your application reject the payload.

Our SDKs have a default tolerance of 5 minutes between the timestamp and the current time. You can change this tolerance by providing an additional parameter when verifying signatures.

Quickly return a 2xx response

Quickly return a successful status code (2xx) prior to any complex logic that could cause a timeout (timeout occurs after 20 seconds). In the event of a timeout the webhook will be logged with 408 Request Timeout status code.

Updated 06 Feb 2024
Doc contributor
Did this page help you?