# Webhook signature validation # Generate signature and set authentication This step must be completed to setup webhooks on your app Before creating a webhook, you need to generate a signature digest key. This key will be used to validate the HMAC signature in each incoming webhook request, confirming the request’s authenticity and integrity. ```curl Request curl -X PUT "https://api.staging.adfin.com/api/apps/{client_id}/webhooks/digest" ``` ```json Example Response { "secretKey": "_4ATIyq0Y8LyOGG_oxOXj8_9YqoGf64i1fmMPADeJkk_" } ``` Explanation 1. **URL**: Replace {client_id} with the unique `client_id` of your app. 2. **Response**: This request will return a secret key that should be securely stored and used to validate incoming webhook signatures. Make sure this key is handled and stored with strict security measures. You need to set up an authentication method for the webhook to ensure that only requests with valid credentials are accepted by your platform. Use any of the following: - Basic Auth - API Key ```curl Basic Auth curl -X PUT "https://api.staging.adfin.com/api/apps/{client_id}/webhooks/auth" \ -H "Content-Type: application/json" \ -d '{ "basicAuthentication": { "username": "{{exampleValue}}", "password": "{{exampleValue}}" } }' ``` ```curl API Key curl -X PUT "https://api.staging.adfin.com/api/apps/{client_id}/webhooks/auth" \ -H "Content-Type: application/json" \ -d '{ "apiKeyAuthentication": { "headerKey": "x-api-key", "headerValue": "{{exampleApiKey}}" } }' ``` ```json Example Response { "statusCode": "200" } ``` br # Verify incoming webhook requests (optional) With the signature digest key and authentication method set up, you can now verify incoming webhook requests. br ### Webhook request headers Every webhook request from Adfin includes these headers: * `adfin-webhook-signature`: The HMAC signature of the payload. * `adfin-webhook-signature-timestamp`: The timestamp of when the request was generated. Example Headers: ```yaml adfin-webhook-signature: H63TRZj13EwxnpRFg454yLH92bm3jZyv31= adfin-webhook-signature-timestamp: 2024-10-01T09:01:35Z ``` br ### Signature Verification Process To verify the webhook, follow these steps: 1. **Concatenate**: Combine the request payload (body) and the signature timestamp (`adfin-webhook-signature-timestamp`). 2. **Generate HMAC**: Use the signature digest key generated in Step 1 to create an HMAC SHA-256 hash of the concatenated data. 3. **Compare**: Verify that the HMAC hash matches the `adfin-webhook-signature` header. br ### Java example for signature verification Here’s a Java example to verify the signature: ```java private String generateVerificationSignature(String data, String key) { final String algorithm = "HmacSHA256"; if (data == null || key == null) { throw new IllegalArgumentException("data and secretKey must not be null"); } try { Mac hmacSHA256 = Mac.getInstance(algorithm); SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm); hmacSHA256.init(secretKeySpec); byte[] dataBytes = hmacSHA256.doFinal(data.getBytes(StandardCharsets.UTF_8)); return new String(Base64.getEncoder().encode(dataBytes)); } catch (NoSuchAlgorithmException | InvalidKeyException e) { throw new RuntimeException("Signature verification failed", e); } } private boolean isSignatureValid(String signatureTimestampHeader, String signatureHeader, String eventPayload, String secretKey) { String SEPARATOR = "||"; String data = signatureTimestampHeader + SEPARATOR + eventPayload; String verificationSignature = generateVerificationSignature(data, secretKey); return signatureHeader.equals(verificationSignature); } ``` br # Handling authentication in webhook requests Based on the configured authentication method: * **Basic Authentication**: Check for `Authorization: Basic base64(username:password)`. * **API Key Authentication**: Verify that the request includes the correct header and value pair (e.g., `x-api-key: testApiKey`). br # Respond to the webhook After validating the signature and authentication, respond to the webhook with a` 2XX` status code if successful. If validation fails, respond with an appropriate error code (e.g., `400 Bad Request` or `401 Unauthorized`). br # Security best practices * **Securely Store Credentials**: Ensure both the signature digest key and authentication credentials are stored securely and rotated periodically. * **Log Events**: Log webhook validation attempts and responses for audit and troubleshooting. * **Rate Limiting**: Apply rate limiting to your webhook endpoint to prevent abuse.