Chapter 2

Security

TLS/SSL

The endpoint must be with tls/ssl 1.2 or higher and have a valid certificate. The Matchi webhook will not send events to an endpoint does not support tls/ssl 1.2 or higher or have a invalid certificate. This is to ensure that the data that is sent with the webhook event is encrypted and secure.

Event Verification / Signature

Each message that are published to the webhook is signed with a HMAC-SHA256 signature. The signature is calculated using the secret that is provided when creating the webhook subscription. The signature is sent in the headerx-matchi-signature.

This is in place so that the client can verify that the message is from Matchi and not from a malicious source.

When you registered the webhook subscription you will receive a secret, this secret is used to verify the signature of the webhook event.

The secret should be kept confidential and should not be shared with anyone.

Bearers: x-matchi-signature

Algorithm: HMAC-SHA256

Example of Signature:

x-matchi-signature:65f11e5ad5a39a32185b8b652785851341205d09a1a09b5ce674ee828c24e722

Verify the signature

The server should use the secret to verify the signature of the webhook event. The signature is verified by computing the HMAC-SHA256 hash of the message and comparing it with the expected signature. Recommendation to store the secret within a secure environment, such as a secret manager and should not be hard coded in the source code.

Below is an example of how to verify the signature in different programming languages, should not be used in production.

Example code:
import hmac
import hashlib

def verify_signature(message, secret, expected_signature):
    signature = hmac.new(secret.encode(), message.encode(), hashlib.sha256).hexdigest()
    return signature == expected_signature

# Usage
message = 'Your webhook message'
secret = 'your-secret'
received_signature = 'signature-from-header'

if verify_signature(message, secret, received_signature):
    print('Signature is valid.')
else:
    print('Signature is invalid.')
#!/bin/bash

# Function to verify HMAC-SHA256 signature
verify_signature() {
    local message="$1"
    local secret="$2"
    local expected_signature="$3"

    # Compute the HMAC-SHA256 hash
    computed_signature=$(echo -n "$message" | openssl dgst -sha256 -hmac "$secret" | sed 's/^.* //')

    # Compare the computed signature with the expected signature
    if [ "$computed_signature" = "$expected_signature" ]; then
        echo "Signature is valid."
    else
        echo "Signature is invalid."
    fi
}

# Usage
message="Your webhook message"
secret="your-secret"
received_signature="signature-from-header"

verify_signature "$message" "$secret" "$received_signature"
const crypto = require('crypto');

function verifySignature(message, secret, expectedSignature) {
    const hash = crypto.createHmac('sha256', secret)
                       .update(message)
                       .digest('hex');

    return hash === expectedSignature;
}

// Usage
const message = 'Your webhook message';
const secret = 'your-secret';
const receivedSignature = 'signature-from-header';

if (verifySignature(message, secret, receivedSignature)) {
    console.log('Signature is valid.');
} else {
    console.log('Signature is invalid.');
}