Verifying signatures

Every webhook delivery includes an Aviowiki-Signature header that you should use to verify the request is genuinely from aviowiki.

The header format is:

Aviowiki-Signature: t=1715782200000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8f9
Part
Description

t

Unix timestamp in milliseconds when the signature was generated

v1

HMAC-SHA256 signature in lowercase hex

Verification Steps

  1. Extract the timestamp (t) and signature (v1) from the header

  2. Construct the signed message: {timestamp}.{raw_request_body}

  3. Compute HMAC-SHA256 of the message using your subscription's secret as the key

  4. Compare your computed signature with v1

  5. Optionally, check that the timestamp is within an acceptable tolerance (e.g. 5 minutes) to prevent replay attacks

import hmac
import hashlib
import time

def verify_signature(payload, signature_header, secret, tolerance_ms=300000):
    parts = dict(item.split("=", 1) for item in signature_header.split(","))
    timestamp = int(parts["t"])
    expected_sig = parts["v1"]

    # Check timestamp tolerance (5 minutes)
    if time.time() * 1000 - timestamp > tolerance_ms:
        return False

    message = f"{timestamp}.{payload}"
    computed = hmac.new(
        secret.encode("utf-8"),
        message.encode("utf-8"),
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(computed, expected_sig)