flashman
← All posts

Webhook JSON signatures: debug canonicalization 401s

Debug webhook signature 401s by checking raw JSON bodies, canonical strings, hash algorithms, timestamps, encodings, replay windows, and safe fixtures.

2026-07-18 · 6 min read · Rahul Chitturi

  • webhooks
  • json
  • security

Webhook signature failures often look like authentication bugs, but the mismatch is usually in the bytes being signed. A framework may parse and reserialize JSON, normalize whitespace, reorder fields, or decode the body before the verifier calculates its hash.

Start with a safe fixture from the provider documentation or a redacted test delivery. Keep the raw body, timestamp header, signature header, algorithm, and shared secret source separate so each assumption can be checked without exposing live credentials.

Compare the exact signing input

Most providers sign a canonical string such as timestamp plus raw body, not the pretty-printed JSON you see in logs. Rebuild that string exactly before changing middleware or rotating secrets.

  • Capture the raw request body before JSON parsing changes whitespace or key order
  • Confirm whether the timestamp, path, method, or query string is included
  • Match the provider hash algorithm and hex or Base64 output format
  • Check replay-window errors separately from digest mismatch errors

Make the reproduction safe

A useful ticket includes fake headers, a non-secret signing key, the raw body, and the expected digest. That lets reviewers prove whether the code signs the right bytes without copying customer payloads or production secrets into chat.

If the failure began after a framework upgrade, diff the request-body middleware and deployment config. Body parsers, edge runtimes, and serverless adapters all have different defaults for raw payload access.

A Flashman workflow

Use the JSON formatter to inspect payload shape, the hash generator to compare expected digests from safe strings, the timestamp converter to check replay headers, and the diff tool to review middleware changes.

When the fix is ready, document the invariant in tests: verification must use the provider's raw signing input before any parsing, formatting, or logging layer mutates the body.

Try these tools