The Provide KYC API gateway implements fault-tolerant KYC remediation. When the status of a KYC application changes, your application can be configured to receive notifications at a configured HTTP webhook_url. Webhook notifications requests sent to this URL include a signature in the X-Request-Signature header. This allows you to verify that the requests were sent by Provide and not by a third party. Signatures can only be verified manually at this time as described below.

Preventing replay attacks

A replay attack is when an attacker intercepts a valid payload and its signature and retransmits them. To mitigate such attacks, Provide includes a timestamp in the X-Request-Signature header. Because this timestamp is also part of the signed payload, it is verified by the signature. An attacker cannot 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 at your discretion.

We recommend that you use Network Time Protocol (NTP) to ensure that your server's clock is accurate and synchronizes with the time on Provide's servers.

Provide generates the timestamp and signature each time we send an notification to your endpoint. If a notification is retried (i.e., in the event your configured endpoint previously issued a non-2xx response), then a new signature and timestamp is generated for the retry attempt.

Verifying signatures

We may release webhook signature verification examples using one of our official libraries in the future. Please use the following instructions to implement signature verification in your configured webhook endpoint.

The X-Request-Signature header contains a timestamp and signature. The timestamp and signature are prefixed by t= and s=, respectively, and comma-delimited.

X-Request-Signature: t=1257894000,s=5b5e838f593e1bae355109bce56939f5ccae74586635f4f95d68bb6b526c40ac

Provide generates signatures using a hash-based message authentication code (HMAC) with SHA-256.

It is not currently possible to have multiple active secrets for generating signatures.

Step 1: Extract the timestamp and signatures from the header

Split the header, using the , character as the delimiter to split on, to get a list of key/value pair strings. Then split each raw string, using the = character as the separator, to arrive at each key and its associated value.

The value for the prefix t corresponds to the timestamp, and s corresponds to the signature.

Step 2: Generate the signed payload string

You achieve this by concatenating:

  • The timestamp (as a string)

  • The character .

  • The raw JSON payload (i.e., the request body)

Step 3: Determine the expected signature

Compute an HMAC with the SHA-256 hash function. Use the application's signing secret as the key, and use the signed payload string generated in step (2) above as the message.

Step 4: Compare signatures

Compare the signature in the header to the expected signature. If the signatures match, compute the difference between the current and received timestamps. It is up to you to determine if the difference is within your tolerance. A higher tolerance is more susceptible to replay attacks.

To protect against timing attacks, use a constant-time string comparison to compare the expected signature to the received signature.