Validating Requests

The secret key is an optional field. Adding a secret key ensures that the webhook is a genuine webhook coming from the neeto product and not from somewhere else. You need to talk to your developer, who works on processing the webhook data, to see what the secret key should be.

There are many ways of generating secret keys. Here are two resources for your reference.

Website randomkeygen shows random values every single time you refresh the page. You can pick any value that you are comfortable with.

If you are familiar with the Ruby programming language, then you can execute the following command to generate a secret key.

ruby -rsecurerandom -e 'puts SecureRandom.hex(20)'

Setting up the secret key on the server

You should set up an environment variable on the server that stores this secret key. Typically, this is as simple as running the following command.


Validating requests are from your neeto product

When your secret key is set, your neeto product uses that secret key to create a hash signature with each payload. This hash signature is included with the headers of each request as x-neeto-hook-secret-sha-256.

You should calculate a hash using your SECRET_KEY, and ensure that the result matches the hash from your neeto product.

Your language and server implementations may differ from the following examples. However, there are a number of very important things to point out:

  • No matter which implementation you use, the hash signature starts with sha256=.

  • Using a plain == operator is not advised. A method like secure_compare performs a "constant time" string comparison, which helps mitigate certain timing attacks against regular equality operators.

Ruby example:

For example, you can define the following verify_signature function:

def verify_signature(payload_body)
  signature = 'sha256=' + OpenSSL::HMAC.hexdigest('sha256'), ENV['SECRET_KEY'], payload_body)
  return halt 500, "Signatures didn't match!" unless Rack::Utils.secure_compare(signature, request.env['HTTP_X_NEETO_CAL_SIGNATURE_256])

Then you can call it when you receive a webhook payload:

post '/payload' do
  payload_body =
  push = JSON.parse(payload_body)
  "I got some JSON: #{push.inspect}"

Python example:

For example, you can define the following verify_signature function and call it when you receive a webhook payload:

import hashlib
import hmac
def verify_signature(payload_body, secret_key, signature_header):
    """Verify that the payload was sent from your neeto product by validating SHA256.
    Raise and return 403 if not authorized.
        payload_body: original request body to verify (request.body())
        secret_key: neeto product webhook secret key (WEBHOOK_SECRET)
        signature_header: header received from neeto product (x-neeto-hook-secret-sha-256)
    if not signature_header:
        raise HTTPException(status_code=403, detail="x-neeto-hook-secret-sha-256 header is missing!")
    hash_object ='utf-8'), msg=payload_body, digestmod=hashlib.sha256)
    expected_signature = "sha256=" + hash_object.hexdigest()
    if not hmac.compare_digest(expected_signature, signature_header):
        raise HTTPException(status_code=403, detail="Request signatures didn't match!")

Can't find what you're looking for?