Verify webhook signatures
Capture the request body as raw bytes before any JSON parser runs. The signed input is <timestamp>.<exact raw body>.
import { createHmac, timingSafeEqual } from 'node:crypto'
export function verifyTeamGridWebhook({ rawBody, secret, signatureHeader, timestamp,}: { rawBody: Buffer secret: string signatureHeader: string timestamp: string}) { const supplied = signatureHeader.replace(/^v1=/, '') const expected = createHmac('sha256', secret) .update(timestamp) .update('.') .update(rawBody) .digest('hex')
const left = Buffer.from(supplied, 'hex') const right = Buffer.from(expected, 'hex') return left.length === right.length && timingSafeEqual(left, right)}Before accepting the payload, also reject stale timestamps and duplicate X-TeamGrid-Webhook-Id values. Store the signing secret separately from the API credential.
The current SDK prerelease documents this procedure but does not yet export a verification helper. Keep this implementation local and covered by receiver tests until that helper is published.