Unable to Verify GoHighLevel Webhook Signature with Public Key Using n8n

Hi everyone,

I’m trying to verify incoming webhook requests from GoHighLevel in n8n. These webhooks include a header called x-wh-signature, which contains a digital signature of the raw request body, signed with a public RSA key (not HMAC).

The goal is to verify the integrity and authenticity of the payload using the provided public key and the raw body.

:page_facing_up: GoHighLevel’s official documentation:
:point_right: Webhook Authentication Guide | Integrations API


:mag: The issue:

n8n doesn’t currently support verifying signatures using a public key (as in crypto.verify()) inside the Crypto or Code nodes. Here’s what I’ve tried so far:


:white_check_mark: Solutions Attempted:

  1. Webhook node with Raw Body enabled
  • Enabled Raw Body and tried accessing it via $binary.data.data.
  • Used Extract from File and Set nodes to decode and stringify the body.
  • Result: Either the body was null or altered, breaking signature validation.
  1. Crypto node (HMAC, Hash, Sign, etc.)
  • Tried all available options: HMAC, SHA256, Sign — none support verify with a public key.
  • Could not recreate the correct signature using these methods.
  1. Code node using Node.js crypto module
  • Attempted to use crypto.createVerify() — but crypto is not available inside the n8n Code node sandbox.
  1. JWT node
  • Tested JWT node as a workaround but it’s not relevant — GoHighLevel is not sending a JWT.
  1. Header Auth on Webhook node
  • Not usable in this case since it’s not a static header value but a cryptographic signature.

:test_tube: Environment:

  • Webhook source: GoHighLevel
  • n8n version: 1.82.3
  • Database: SQLite (default)
  • EXECUTIONS_PROCESS: own
  • Running via: Docker
  • OS: Ubuntu 22.04 (DigitalOcean droplet)

:bulb: Next Step (Possible Solution):

As a workaround, I’m considering deploying a separate Node.js microservice (in Docker, side-by-side with n8n) to handle the RSA signature verification using crypto.verify(). Once validated, it would forward the payload to another internal n8n webhook.

Before going that route, I wanted to ask the community:
Is there a native way in n8n to verify RSA signatures of raw webhook payloads using a public key?
Or has anyone implemented a similar flow?

Thanks a lot in advance! :pray:

You could add this to your docker environment

  NODE_FUNCTION_ALLOW_BUILTIN=crypto

and try option 3 again.

let crypto = require('crypto');

let verify = crypto.createVerify('RSA-SHA256');
1 Like

Hey @hubschrauber — just wanted to say thank you! :raised_hands:

Your suggestion to add NODE_FUNCTION_ALLOW_BUILTIN=crypto to the Docker environment worked perfectly. I was finally able to use crypto.createVerify() inside the Code node and verify GoHighLevel’s webhook signature using the public key. :dart:

Really appreciate you jumping in and pointing me in the right direction. You saved me from spinning up a separate microservice just for this!

Cheers,
Lucas

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.