Skip to content

We recommend verifying all webhook events using the x-openfx-signature header.

Signature Verification

To verify the signature, generate a HMAC-SHA256 hash of the request payload using the webhook signing key and compare it with the value of the x-openfx-signature header.

JavaScript

function isValidSignature(request) {
  const signingKey = "Signing-key-provided-by-OpenFX"
  const headers = request.headers
  const signature = headers["x-openfx-signature"]

  const body = request.body
  const hmac = crypto.createHmac("sha256", signingKey) // Create a HMAC SHA256 hash using the key
  hmac.update(body) // Pass body as is, in json string format.
  const computedHash = hmac.digest("base64")

  return signature === computedHash // If signature equals your computed hash, return true
}

Python

import hmac
import hashlib
import base64

def is_valid_signature(request):
    signing_key = "Signing-key-provided-by-OpenFX"
    signature = request["headers"].get("x-openfx-signature")
    body = request["body"].encode("utf-8")

    hmac_obj = hmac.new(signing_key.encode("utf-8"), body, hashlib.sha256)
    computed_hash = base64.b64encode(hmac_obj.digest()).decode()

    return signature == computed_hash

Java

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class SignatureValidator {
    private static final String SIGNING_KEY = "Signing-key-provided-by-OpenFX";

    public static boolean isValidSignature(Request request) throws Exception {
        String signature = request.getHeaders().get("x-openfx-signature");
        String body = request.getBody();

        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(SIGNING_KEY.getBytes(), "HmacSHA256");
        mac.init(secretKeySpec);
        byte[] hmacBytes = mac.doFinal(body.getBytes());

        String computedHash = Base64.getEncoder().encodeToString(hmacBytes);
        return signature.equals(computedHash);
    }
}

GO

package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
)

func isValidSignature(request map[string]interface{}) bool {
	signingKey := "Signing-key-provided-by-OpenFX"
	headers := request["headers"].(map[string]string)
	signature := headers["x-openfx-signature"]
	body := request["body"].(string)

	h := hmac.New(sha256.New, []byte(signingKey))
	h.Write([]byte(body))
	computedHash := base64.StdEncoding.EncodeToString(h.Sum(nil))

	return signature == computedHash
}

func main() {
	request := map[string]interface{}{
		"headers": map[string]string{"x-openfx-signature": "expected_signature"},
		"body":    `{"example": "data"}`,
	}
	fmt.Println(isValidSignature(request))
}

PHP

<?php
function isValidSignature($request) {
    $signingKey = "Signing-key-provided-by-OpenFX";
    $headers = $request['headers'];
    $signature = $headers['x-openfx-signature'];
    $body = $request['body'];

    $computedHash = base64_encode(hash_hmac('sha256', $body, $signingKey, true));

    return hash_equals($signature, $computedHash);
}
?>