Skip to main content
Community Member
November 14, 2023
Solved

Why does the webhook callback signing key change with every call as opposed to using mine?

  • November 14, 2023
  • 3 replies
  • 490 views

I successfully used the webhook callback API with signing_key verification a few days ago. But now, for some reason, the signing key changes with every callback making me reject the call.

What could possibly be the cause? I did follow the docs @ https://calendly.stoplight.io/docs/api-docs/c1ddc06ce1f1b-create-webhook-subscription 

Below is my successful webhook I created:

    "collection": [

        {

            "callback_url": "https://TO_SOME_PLACE/",

            "created_at": "2023-11-14T18:45:52.610226Z",

            "creator": "https://api.calendly.com/users/USER_ID",

            "events": [

                "invitee.created",

                "invitee.canceled",

                "invitee_no_show.created"

            ],

            "organization": "https://api.calendly.com/organizations/ORG_ID",

            "retry_started_at": null,

            "scope": "user",

            "state": "active",

            "updated_at": "2023-11-14T18:45:52.610226Z",

            "uri": "https://api.calendly.com/webhook_subscriptions/SUB_ID",

            "user": "https://api.calendly.com/users/USE_ID"

        }

    ],

Thank you in advance

 

This topic has been closed for replies.
Best answer by anolson

Hey Andreas!

 

We don’t send the signing key with each webhook payload. What we send instead is signature that’s computed by:

  • Combining a timestamp and the request body 
  • Then generating a HMAC digest with the webhook signing key

 

You’ll need to do this same computation on your end to verify each payload. We have a few different code examples here:

https://developer.calendly.com/api-docs/4c305798a61d3-webhook-signatures

3 replies

anolsonAnswer
Employee
November 14, 2023

Hey Andreas!

 

We don’t send the signing key with each webhook payload. What we send instead is signature that’s computed by:

  • Combining a timestamp and the request body 
  • Then generating a HMAC digest with the webhook signing key

 

You’ll need to do this same computation on your end to verify each payload. We have a few different code examples here:

https://developer.calendly.com/api-docs/4c305798a61d3-webhook-signatures

AndreasBAuthor
Community Member
November 14, 2023

I somewhat skipped the code examples and simply assumed it’s a simple comparison but what you describe and actually do makes much more sense of course. I changed the code and it works as expected now. My earlier success stemmed from internal testing where I artificially fabricated the headers, thereby cheating.

Again, thank you for the speedy reply. Everything is now fully integrated as we’d like and works as expected. 

-Andreas

P.S. For those in need of a Python way to implement the HMAC digest verification, here it is:

#

# Assuming you got headers in dict form and body as byte

#

# Get your assigned signing key

webhook_signing_key = os.getenv("WEBHOOK_SIGNING_KEY")

# Split signature header by time and signature

signature_header = headers['Calendly-Webhook-Signature'].split(',')

t = signature_header[0].split('=')[1]

signature = signature_header[1].split('=')[1]

 

# Construct payload to sign

payload = t + '.' + body.decode('UTF-8')

 

# Generate signature with secret key

hexdigest = hmac.new(webhook_signing_key.encode('UTF-8'), payload.encode('UTF-8'), hashlib.sha256).hexdigest()

 

# Verify signatures

if hexdigest != signature:

    raise Exception(‘Invalid Signature’)

Employee
November 15, 2023

That’s great to hear!