Signing
PainChek webhooks support signing to ensure that a request has originated from PainChek and that the payload contents have not been altered.
When the webhook subscription is registered, PainChek can generate and record unique secret for that subscription. If there is a secret recorded, a hash-based message authentication code (HMAC) is used to sign each outgoing payload.
The entire body of the payload is hashed using SHA-256 and the secret. This hash is added to the headers of each outgoing webhook request and takes this form:
X-PainChek-WH-Signature: sha256=779bcda841e00e4f97ceafeb8ed09a02f62cd8598e3d286b8fb6494d53f65a99
To verify the signatures on the payloads from PainChek, the consuming application must securely store the secret and use it to compute a HMAC using the received payload. The computed HMAC and the received signature are then compared to determine if the message is valid.
Example of Signature Computation
Here is an example of how to compute the signature in Python:
import hmac import hashlib def hmac_sha256(key, payload): return hmac.new( key.encode("utf-8"), payload.encode("utf-8"), hashlib.sha256 ).hexdigest() def is_signature_valid(payload, received_signature, shared_secret): computed_signature = hmac_sha256(shared_secret, payload) if received_signature == computed_signature: return True else: return False shared_secret = "0DpAOwQAZw4CFwpEiNyGaoTkb5tyARds" payload = '{"data": {"uuid": "6ef946ca-cb31-4e6b-92ff-bcf61d505cd9", "patient": "f0e00e69-532a-4670-b32c-3dbeeb8ecf4f", "...": "..."}, "event": "assessment_add"}' received_signature = "6e81791ce640f33a831bffe2daa70b2e68f664fea7038d25790dcf82d10488a6" if is_signature_valid(payload, received_signature, shared_secret): print("Valid message") else: print(f"Invalid message")
Authentication
Although we don't generally recommend it, the client may optionally save an Authorization header when subscribing to a webhook.
If supplied, the details are passed via the Authorization request header
All of the standard authentication schemes are supported - basic, bearer, digest, etc - and the authentication type must be included when configuring the webhook - e.g. "Basic YWxhZGRpbjpvcGVuc2VzYW1l"
Note
Relying on an Authorization header alone should be avoided where possible as it can open the recipient system up to impersonated attacks if the token is breached.