For the complete documentation index, see llms.txt. This page is also available as Markdown.

Signature

Overview

This document provides guidance on webhook message signatures and how to validate the X-Caf-Signature header that is included in all webhook requests made by Certta services.

Message signatures

Since webhook URLs are exposed to the internet, your application needs a secure mechanism to verify that requests are genuinely from Certta. We implement a signature validation header for this purpose, which we call the message signature.

Signature header

Each webhook request includes a X-Caf-Signature header with the following format:

X-Caf-Signature: 5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

The header contains the HMAC SHA-256 signature value generated from the raw request body using your client secret.

How to validate

Certta implements a keyed-hash message authentication code (HMAC) mechanism with SHA256 to generate a signature for each message sent, with the final encoding in hexadecimal.

This signature is generated using your application's client secret (the same one used to generate tokens) found in Trust, the platform that manages the configurations. The signature is sent through the X-Caf-Signature header in each HTTP request.

To validate this signature, your integration should:

  1. Generate the HMAC of the received message using your secret (stored in a secure location)

  2. Compare it with the received signature using a secure comparison algorithm

Important security considerations

As fields can be added to any event at any time without being a breaking change, message validation should be done before the content is transformed into a language object. This means using the body's byte array "as-is" to generate the comparison signature, without any transformation.

This is also important because when dealing with JSONs, {"prop1": "value1", "prop2": "value2"} is equivalent to {"prop2": "value2", "prop1": "value1"} for parsers/encoders since property ordering is not part of a JSON definition, but the byte arrays formed by the two objects are different. Also, some characters may be encoded differently depending on the library or language being used.

Implementation examples

Many programming languages include secure HMAC implementations in their standard libraries:

Format variations

All these examples are valid for the same JSON but with different formatting and must be supported by your integration:

Without spaces or line breaks

The X-Caf-Signature value is calculated from these exact bytes and your webhook secret.

With spaces, no line breaks

Even though this JSON represents the same object, its signature differs because its raw bytes differ.

With spaces and line breaks

This formatted body also produces a different signature.

With properties in different order

Changing property order also changes the signature.

Code examples

Node.js

Java

Go

Security best practices

Obtaining your webhook secret

You can find your webhook secret in Trust, the platform that manages configurations, under the webhook configuration settings. If you believe your secret has been compromised, you can generate a new one at any time.

Last updated