Webhook Verification
How to verify the authenticity of Passage Connect webhooks.
Overview
Webhooks are signed with ES256 (ECDSA with P-256 and SHA-256) as JWTs. Verify the signature to ensure the webhook was sent by Passage Connect.
Step 1: Extract the JWT
The webhook body is a signed JWT string.
Step 2: Decode the header
Parse the JWT header to get the kid (key ID):
const [headerB64] = webhookBody.split('.')
const header = JSON.parse(atob(headerB64))
const kid = header.kidStep 3: Fetch the public key
const res = await fetch('https://connect.passage.dev/webhook_verification_key/get', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ kid })
})
const jwk = await res.json()Step 4: Verify the signature
const key = await crypto.subtle.importKey(
'jwk', jwk,
{ name: 'ECDSA', namedCurve: 'P-256' },
false,
['verify']
)
// Use a JWT library to verify the full tokenSecurity notes
- Always verify webhook signatures before processing
- Cache the public key to avoid fetching on every webhook
- Reject webhooks with expired timestamps
Next steps
- Webhooks — Webhook overview
- Webhook Key API — Key endpoint reference
Last updated on