Verify HMAC webhook signature: doing it correctly
What HMAC actually proves
The exact scheme Olmira uses
X-Aether-Signature, X-Aether-Webhook-Id, and X-Aether-Event. (The header prefix reads Aether rather than Olmira — a naming holdover from the platform's internal codename; it doesn't affect anything about how the scheme works, only what the header is literally called.)Verifying a delivery, in plain terms
crypto module covers all of it without a single dependency; the pre-flight checks below are where correct implementations actually differ from broken ones.The mistakes that break verification
. prefix — is the second most common, and it's an easy one to make because it's the more "obvious" thing to hash.Before you trust it in production
Check the timestamp window first
Reject anything outside a small tolerance (Olmira publishes 300 seconds, five minutes, as its own reference figure) before spending any CPU time hashing — a stale signature doesn't deserve the comparison.
Compare in constant time
Use your language's constant-time comparison primitive, not a plain equality check, so a mismatch never leaks timing information about how close a guess was.
Confirm you're hashing the raw body
Log the exact string your code is about to hash at least once during setup and compare it, byte for byte, against what a test delivery actually sent.
Plan for a rotated secret
Wherever you store the secret, make it a one-line config change — rotating in the dashboard without updating it in the same moment means every delivery starts failing until you catch up.
How Olmira handles this
Source IPs shift — behind load balancers, across provider infrastructure changes, over time — and allowlisting them is brittle in practice. A cryptographic signature proves authenticity regardless of network path, which is a stronger and more stable guarantee than "the request came from a range we recognised today."
No — the scheme is identical everywhere. What differs per endpoint is only the secret itself, since each one is generated independently.
No — verify the signature, acknowledge quickly, and do anything slow (database writes, calls to other systems) asynchronously afterwards. A webhook sender that times out waiting for your endpoint will generally treat that as a failure and retry, which you don't want to trigger by being slow rather than actually failing.
Reject before processing anything else — a 4xx response and nothing else. Don't describe why it failed in the response body; an attacker probing your endpoint shouldn't get free feedback on which part of a forged signature was wrong.