Notification Authentication
BR-DGE notifications are protected by a signature-based authentication method to enhance the security of webhook notifications. By signing the notification payload, you can ensure that the data received by your system is authentic, was sent by BR-DGE, and has not been tampered with.
This feature is not enabled by default on existing retail channels. To activate signature-based authentication, BR-DGE must update your webhook configuration. To enable this feature please contact our support team.
Authentication Mechanism
Prior to sending a notification to your server BR-DGE generates a signature using a HMAC SHA3-256 algorithm. The signature generation process utilises two primary components:
- The Notification Body: The entire, unformatted JSON body (no whitespace or newlines).
- The Signing Key: A combined string consisting of a shared secret, and the timestamp provided in the notification header.
Headers
Each notification sent by BR-DGE will include at least the following headers:
| Header | Type | Description |
|---|---|---|
signature | string (Base64) | The HMAC SHA3-256 hash of the payload, encoded as a Base64 string. |
timestamp | string (Epoch) | The timestamp used during the signing process. |
The headers should be used as part of the notification authentication process, where the process requires them. You should not alter or edit the headers in any way. Doing so will result in your authentication check failing.
Authentication Shared Secret
To generate the HMAC signature for your notifications, BR-DGE will configure a Shared Secret that is known only by you and BR-DGE. This secret is stored within your webhook configuration and acts as a private key to cryptographically sign every notification sent to your endpoint.
If you are unsure what your shared secret is, please contact our support team.
Shared Secret Rotation
To ensure continuous security, BR-DGE supports a zero downtime key rotation process.
We recommend storing your shared secret keys securely, following industry best practices. To take full advantage of the shared secret rotation mechanism offered by BR-DGE you should support the storage of multiple keys simultaneously.
To request a shared secret rotation please contact our support team who will be able to guide you through the process.
Rotation Process
The following high level steps will be followed when you request a key rotation via our support team.
- You raise a notification key rotation request to the BR-DGE support team.
- BR-DGE generates a new secret key and securely shares it with you.
- You add the new key to your system. Your verification logic should now check both the old and new keys.
- You confirm the new key is active on your side.
- BR-DGE update your notification configuration to use the new key for all future signatures.
- BR-DGE notify you once the switch is complete, at which point you can safely remove the old key from your list.
Authentication Process
To verify a notifications authenticity, your system should perform the following steps for each shared secret you have stored:
Construct the Signing Key
Construct your signing key using both your shared secret and the timestamp sent by BR-DGE in the header of the notification. You then concatenate the two values using a double colon delimiter, ::.
For example, if your shared secret is 0f7956a6-354c-4c2d-8791-04c877ab95fc and the timestamp value is 1767225600000 your signing key for the notification would be: 0f7956a6-354c-4c2d-8791-04c877ab95fc::1767225600000
Generate the Hash
Using your signing key, hash the entire unformatted JSON notification body. Perform this hash using the HMAC SHA3-256 algorithm.
It is critical that the JSON is treated as a raw string with no whitespace, newlines, or extra formatting.
Encode the Hash to Base64
Once the HMAC has been generated, convert the resulting binary hash into a Base64 string. This ensures the format of your locally generated hash matches the format sent by BR-DGE in the notification header.
Compare your Signature
Finally, compare your locally generated Base64 string against the signature value provided in the notification header.
Comparing the locally generated string to the one sent by BR-DGE should result in one of 3 scenarios:
| Scenario | Action | |
|---|---|---|
| ā | Local signature matches header signature. | Consume the notification into your system. |
| ā ļø | Local signature does not match header signature. Additional signing keys are available. | Recalculate the signature using another signing key, and check the result again. |
| ā | Local signature does not match header signature. No additional signing keys are available. | Reject the notification as it may have been tampered with. |
Respond to BR-DGE
After successfully verifying the notification, your system must acknowledge receipt by returning an HTTP 2xx status code (e.g., 200 OK or 204 No Content).
Failure to provide a successful response, whether due to a timeout, a connection error, or a non-2xx status code will signal to BR-DGE that the delivery was unsuccessful. In these instances, BR-DGE will automatically trigger a retry of the notification according to our standard Notification Retry Policy.
To ensure efficient processing:
- Respond Promptly: Acknowledge the request as soon as verification is complete to avoid unnecessary retries.
- Reject Invalid Signatures: If a notification fails all verification attempts against your list of secret keys, you should reject the payload.
Signature Verification Code Example
The following example code shows how you can create and verify a notification signature locally using Java.
The example returns true if the notification can be verified with one of the secret keys in the list, and false if they all fail. If the result is true then the notification is safe to consume, otherwise you should reject it.
import com.google.common.collect.Lists;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.List;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class NotificationVerifier {
private static final String HMAC_SHA3_256_ALGORITHM = "HmacSHA3-256";
private static final String KEY_DELIMITER = "::";
public boolean isNotificationValid(String signature,
String timestamp,
String notificationBody,
List<String> secretList) {
for (String secret : secretList) {
try {
String generatedHmac = generateHmac(notificationBody, secret, timestamp);
if (generatedHmac.equals(signature)) {
return true;
}
} catch (Exception e) {
log.error("Exception thrown when verifying notification payload");
}
}
return false;
}
private String generateHmac(String notificationBody,
String secret,
String timestamp)
throws NoSuchAlgorithmException, InvalidKeyException {
String key = createKey(secret, timestamp);
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), HMAC_SHA3_256_ALGORITHM);
Mac mac = Mac.getInstance(HMAC_SHA3_256_ALGORITHM);
mac.init(secretKeySpec);
return bytesToBase64String(mac.doFinal(notificationBody.getBytes()));
}
private String createKey(String secret,
String timestamp) {
List<String> keyComponents = Lists.newArrayList(secret, timestamp);
return String.join(KEY_DELIMITER, keyComponents);
}
private String bytesToBase64String(byte[] data) {
return Base64.getEncoder().encodeToString(data);
}
}Support
For support with notification authentication, or to request this feature to be enabled on existing BR-DGE retail channels, please contact our support team.
Updated 1 day ago
