Skip to main content

Authenticating events

To ensure the integrity and security of an integration, all incoming webhook events must be authenticated before they are processed. This prevents forged, modified or otherwise unauthorized requests from being accepted by the integration.

note

For event subscriptions using the legacy HMAC signature, also refer to the documenation on legacy event authentication in addition to the information in this article.

Why authentication matters

Webhooks are HTTP callbacks, which means they can be exposed to the public internet. Without proper authentication:

  • Malicious actors could send fake events
  • Sensitive data could be compromised
  • An integration could perform unintended actions

Signature validation

Each event is signed using a secret key shared between Future Ordering and the integration. It is essential to validate the event signature before processing the event.

Validation steps:

  1. Retrieve the signature from the Authorization header
  2. Retrieve the signed event timestamp from the X-Authorization-Timestamp header
  3. Compute the HMAC of the request body using your secret key
  4. Compare the computed signature with the signature from the header

Payload for signature validation

The payload which is hashed to validate the event signature is:

<HTTP Method (uppercase)>
<Request URL (including scheme, host and path)>
<X-Authorization-Timestamp header value>
<Base64 encoded SHA256 hashed HTTP request body>

The signature parts are delimited by a single newline character \n.

Request validation example

The following example event HTTP request is sent to an HMAC subscription endpoint:

POST /event/listener/endpoint HTTP/1.1
Host: mydomain.com
Authorization: HMAC-SHA256 42qxmXW7eVEe8z1sos78JesoTSMN6kA3KRoE/OOHVi8=
X-Authorization-Timestamp: 1746629654
... // other HTTP headers removed for brevity

{"specversion":"1.0","data":{"userId":"6465bacd-5695-46e6-860c-f22b509d8827","tenantId":"demo"},"dataContentType":"application/json","id":"a212c861-0cb1-46ba-ac26-3247709bbc8a","source":"https://api.futureordering.com","time":"2025-05-07T14:54:14.6865307+00:00","type":"com.futureordering.user.logged_in"}

Using this example data, the payload used to calculate the signature is:

POST
https://mydomain.com/event/listener/endpoint
1746629654
RCbyhSUTBtcZAHevl6MvHOxkImHIQau9f3u8X1B1XlU=

After hashing the payload, the resulting byte sequence encoded as a Base64 string is

42qxmXW7eVEe8z1sos78JesoTSMN6kA3KRoE/OOHVi8=

which matches the signature in the Authorization header.

info

See Example: Signature validation (.NET) for an example signature validation code snippet.