Verify the Standard Webhooks signature (https://www.standardwebhooks.com/)
an HTTP sink with a secret adds to every delivery.
webhook-signature holds space-separated v1,<base64> entries, each an
HMAC-SHA256 over <webhook-id>.<webhook-timestamp>.<body>. A delivery passes
when any v1 entry matches any configured secret (several during a
rotation), compared in constant time with MessageDigest/isEqual, and
webhook-timestamp is within the tolerance of now. Secrets are whsec_ +
base64, or any other string used as its own UTF-8 bytes.
A failure throws :ankusa.sdk/InvalidSignatureError with :code
("invalid_secret", "missing_header", "invalid_timestamp",
"timestamp_out_of_tolerance", "no_matching_signature") and :field
(the header at fault, nil for "invalid_secret"). It is never
retryable: answer 401.
Verify the Standard Webhooks signature (https://www.standardwebhooks.com/) an HTTP sink with a `secret` adds to every delivery. `webhook-signature` holds space-separated `v1,<base64>` entries, each an HMAC-SHA256 over `<webhook-id>.<webhook-timestamp>.<body>`. A delivery passes when any `v1` entry matches any configured secret (several during a rotation), compared in constant time with `MessageDigest/isEqual`, and `webhook-timestamp` is within the tolerance of now. Secrets are `whsec_` + base64, or any other string used as its own UTF-8 bytes. A failure throws `:ankusa.sdk/InvalidSignatureError` with `:code` (`"invalid_secret"`, `"missing_header"`, `"invalid_timestamp"`, `"timestamp_out_of_tolerance"`, `"no_matching_signature"`) and `:field` (the header at fault, `nil` for `"invalid_secret"`). It is never retryable: answer `401`.
How far either side of now webhook-timestamp may be, by default.
How far either side of now `webhook-timestamp` may be, by default.
(verify headers body secrets)(verify headers
body
secrets
{:keys [tolerance-seconds now]
:or {tolerance-seconds default-tolerance-seconds}})Verify one delivery and return {:id :timestamp} (the webhook-id, and
webhook-timestamp as unix seconds).
headers is a map (Ring's :headers) or a seq of [name value] pairs,
matched case-insensitively; body the raw bytes received (byte[] or a
String, taken as UTF-8); secrets one secret or a seq of them. Options:
:tolerance-seconds (default 300) and :now (unix seconds; default the
clock).
The checks run in this order: invalid_secret, missing_header
(webhook-id, webhook-timestamp, webhook-signature),
invalid_timestamp, timestamp_out_of_tolerance,
no_matching_signature.
Verify one delivery and return `{:id :timestamp}` (the `webhook-id`, and
`webhook-timestamp` as unix seconds).
`headers` is a map (Ring's `:headers`) or a seq of `[name value]` pairs,
matched case-insensitively; `body` the raw bytes received (`byte[]` or a
String, taken as UTF-8); `secrets` one secret or a seq of them. Options:
`:tolerance-seconds` (default 300) and `:now` (unix seconds; default the
clock).
The checks run in this order: `invalid_secret`, `missing_header`
(`webhook-id`, `webhook-timestamp`, `webhook-signature`),
`invalid_timestamp`, `timestamp_out_of_tolerance`,
`no_matching_signature`.cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |