Webhook Security
Authenticate Optacy webhooks with HMAC SHA-256 signatures using your private API key.
Every webhook request must be validated so you only accept data from Optacy. The signature object on each request includes three fields:
- a random token
- a timestamp (milliseconds since January 1, 1970)
- a signature: HMAC SHA-256 of the timestamp concatenated with the random token, keyed with your private API key from the Webhooks tab in the dashboard
How to authenticate
- Concatenate
timestampandtokeninto a single string with no spaces. - Compute HMAC SHA-256 of that string using your private API key.
- Compare the hex digest to the
signaturefield in the request. - If they match, accept the request; otherwise reject it.
Store and access your private API key securely, typically via an environment variable.
Ruby on Rails example
token = params["signature"]["random_token"]
timestamp = params["signature"]["timestamp"]
signature = params["signature"]["signature"]
signed_test_data = OpenSSL::HMAC.hexdigest(
"SHA256",
ENV["OPTACY_WEBHOOK_PRIVATE_API_TOKEN"],
"#{timestamp}#{token}"
)
if signed_test_data == signature
# the request is accepted
else
raise "Optacy webhook did not authenticate"
end
Replay protection
You may reject timestamps older than a few minutes to mitigate replay attacks. Replay risk is already low over HTTPS; this check is optional and not shown in the example above.