Validate event notifications
This guide explains how to verify that the events you receive through webhooks are genuinely from Griffin using HTTP message signatures.
Why verify webhooks?
Verifying webhooks ensures that the data you receive comes from Griffin and hasn't been tampered with. This helps protect your systems from potential security issues.
Prerequisites
- You have created a webhook for your organisation.
- You have a basic understanding of HTTP Message Signatures.
Verifying signatures
1. Retrieve Griffin's public keys
When users register with Griffin, they add their public keys to verify the messages they send. Similarly, Griffin publishes its public keys for webhook verification.
Griffin uses the JSON Web Key (JWK) specification to specify the keys.
curl https://api.griffin.com/v0/security/public-keys
{
"keys": [
{
"alg": "ES512",
"crv": "P-521",
"kid": "griffin-2025-05-23-1",
"kty": "EC",
"use": "sig",
"x": "YLDk2jvRelEEeMcacVQK5E98a-OrTLzqIYLwwNW5Nu8rsokvMNRFLLgNDrwGlGMELVzhbkI9rGchfJauv07SF3I",
"y": "APiLzGWJRnYqv3YdK8bIuoDZ4GB5yyEFeUEGCCIRpPzRvIEX4RHmjRy9hIr1BzOedbD_tzJqVVO_JgSWlrqSO-xk"
}
],
"links": {
"prev": null,
"next": null
}
}
You should cache these keys - do not fetch them on every webhook validation. Keys are immutable: once published, a Key ID (kid
) parameter will always resolve to the same key value. However, only active keys are returned by the JWKS endpoint. Deactivated keys will no longer appear in responses and won't be used for signing new webhooks, so ensure your caching implementation handles cases where a previously cached key is no longer available.
2. Extract the signature information
When you receive a webhook, extract the signature components from the headers:
signature-input: griffin-2025-05-23-1=("date" "@method" "@path" "@authority" "content-type" "content-length" "content-digest");created=1748006254;expires=1748006554;nonce="2885d616-ff20-42ce-8be4-e5949e5619e4";keyid="griffin-2025-05-23-1"
signature: griffin-2025-05-23-1=:MIGIAkIAtXHkTXhrbH0XG3UuG54Digyrm876gfM3GjjzfGdjhrIrqsbfhj23Iu5OHzQZc6gdDg7nf6IEDe3ZdrmxjSrewf8CQgHWuEI1h1IqgqoLEzFPT9EMdzPJ9lGTbb2wiuYLSuYgHrmSbaeI/ftiKvaoIUC5fqL+Sihby6pLKAHqNJPu2Y90sw==:
content-digest: sha-512=:8fgCNp47ZpD3ZGH91657mbG445gYWlOAiKmVja2Krl2OiXfp0AutI7WxYe0Csf7ad0+/kxkG8Llxm0nsRMDfCQ==:
content-length: 567
signature-input
: Describes how the signature is constructedsignature
: Contains the actual cryptographic signaturecontent-digest
: A SHA-512 hash of the request bodycontent-length
: The size of the request body in bytes
The keyid
parameter identifies which of Griffin's public keys was used to sign this webhook. Griffin rotate keys periodically for security, but any key that appears in a webhook signature will be available from our public keys endpoint.
For more information on the signature components, see the Derived Components section in the HTTP Message Signatures RFC.
3. Signature verification
To verify the signature, you'll need to:
- Reconstruct the signature base. See Creating the Signature Base in the HTTP Message Signature RFC.
- Verify the signature: Use the public key to verify that the signature in the signature header matches the signature base you constructed.
Most programming languages provide cryptographic libraries that support signature verification.
Best practices
- Always verify webhooks before processing them in your production environment.
- Cache public keys to avoid having to to make additional request on each webhook event. All keys are immutable and an id will always match a specific key.
- If you encounter an unknown
keyid
, refresh your cached keys from our public keys endpoint. If thekeyid
still can’t be found, reject the message and contact Griffin support immediately. - Respond quickly to webhook deliveries with a 2xx status code and process the request asynchronously.
- Monitor verification failures as they could indicate a security issue. If the verification fails, you can use the Events API to confirm the event ID exists in our system and contact Griffin support immediately.
Troubleshooting
If you're having trouble verifying webhooks:
- Check that you're using the correct public key matching the
keyid
in the signature. - Ensure you're constructing the signature base with the exact components listed in the
signature-input
header, in the correct order. - Verify you're using the correct signature algorithm as indicated in the public key.
- Make sure your content digest calculation matches the one in the header.
- Confirm that header values haven't been modified by intermediate proxies or your web framework.
If you need additional help with webhook verification, contact us at support@griffin.com.