How to Secure and Verify Claude Webhooks with Hookdeck
Webhook security and verification are critical components of any integration, and Claude Managed Agent webhooks are no exception. An unverified webhook handler is an unauthenticated public endpoint that does work on receipt of an HTTP POST — exactly the kind of surface area attackers look for to trigger replay attacks, forge events, or fan out denial-of-service traffic.
Claude signs every outbound webhook with an HMAC, includes a timestamp to prevent replays, and requires you to verify both before trusting the payload. You can do this manually, or you can offload it to Hookdeck. This article walks through both. For a comprehensive overview of Claude webhook capabilities, see our guide to Claude webhooks.
How to manually secure Claude webhooks
When you create a webhook endpoint in the Claude Console, Claude generates a 32-byte signing secret prefixed whsec_ and shows it to you once. From that point on, every event delivered to your endpoint includes an X-Webhook-Signature header that's an HMAC of the payload computed with that secret.
The seven things you need to do on every request:
- Store the signing secret as an environment variable — Anthropic's SDKs use
ANTHROPIC_WEBHOOK_SIGNING_KEYby convention. Never check the secret into source control or hardcode it. - Read the raw, unparsed request body. If you parse JSON before you verify, the byte-for-byte input to the HMAC won't match what Claude signed and verification will always fail.
- Read the
X-Webhook-Signatureheader. - Compute an HMAC-SHA256 of the raw body using the signing secret and compare it to the signature header using a constant-time comparison function — never a plain string comparison, which leaks information through timing.
- Reject the request if the signatures don't match.
- Read the
created_atfield from the payload and reject anything older than five minutes. The freshness check is what protects against replay attacks: an attacker who captures a valid signed payload can't replay it later. - Enforce that the request used HTTPS, and that the URL hasn't been tampered with by a redirect. Claude doesn't follow 3xx responses (it treats them as failures) so your endpoint should never sit behind a redirect.
A minimal manual verification handler in Node.js looks like this:
const crypto = require('crypto');
const express = require('express');
const app = express();
const SIGNING_KEY = process.env.ANTHROPIC_WEBHOOK_SIGNING_KEY;
app.post('/webhooks/claude',
express.raw({ type: 'application/json' }),
(req, res) => {
const signature = req.headers['x-webhook-signature'];
const expected = crypto
.createHmac('sha256', SIGNING_KEY)
.update(req.body)
.digest('hex');
const valid = crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
if (!valid) return res.sendStatus(401);
const event = JSON.parse(req.body);
const ageSeconds = (Date.now() - new Date(event.created_at)) / 1000;
if (ageSeconds > 300) return res.sendStatus(400);
handleEvent(event);
res.sendStatus(200);
}
);
The Anthropic SDKs collapse this down to a single helper call — client.beta.webhooks.unwrap() — that's available in Python, TypeScript, Go, Java, C#, PHP, and Ruby:
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic();
app.post('/webhooks/claude',
express.raw({ type: 'application/json' }),
(req, res) => {
try {
const event = client.beta.webhooks.unwrap(
req.body,
req.headers,
process.env.ANTHROPIC_WEBHOOK_SIGNING_KEY
);
handleEvent(event);
res.sendStatus(200);
} catch (err) {
res.sendStatus(400);
}
}
);
The helper verifies the signature, enforces the freshness window, and returns a parsed event — all in one call.
But even with the helper, manual verification still leaves you with a list of operational responsibilities: rotating the signing secret without breaking deliveries, handling the case where your endpoint is auto-disabled after ~20 consecutive failures, ensuring every fleet of handlers shares the same secret, and re-verifying on every retry because Claude's at-least-once delivery means the same event arrives more than once. The work compounds the more endpoints, environments, and event types you handle.
How to secure and verify Claude webhooks with Hookdeck
Hookdeck Event Gateway centralizes signature verification at the edge, so your handler only ever sees pre-verified events. The setup is mostly point-and-click:
- Create a free Hookdeck Event Gateway account.
- In the Hookdeck dashboard, create a new Source and pick "Claude" — Hookdeck has the verification logic for
whsec_-prefixed secrets and theX-Webhook-Signatureheader built in. - Paste your Claude signing secret into the Source's authentication settings. Hookdeck stores it encrypted.
- Create a Connection from the Claude Source to a Destination (your application's webhook URL, or the Hookdeck CLI for local development).
- Configure the URL Hookdeck gave you as the webhook endpoint in the Claude Console under Manage > Webhooks.
- Subscribe to the event types you care about.
- Send a test event. Hookdeck verifies the signature, rejects anything older than five minutes, and only forwards verified payloads to your application.
- Optionally enable Hookdeck's own outbound signature verification so your application can verify that requests really came from Hookdeck and not a third party who guessed your endpoint.
Once that's wired up, the operational responsibilities collapse. Secret rotation is a dashboard change. Auto-disable doesn't happen because Hookdeck retries with backoff and absorbs the volatility. Every handler in every environment receives the same pre-verified event — no shared-secret distribution, no per-service verification code, no risk of one team forgetting the constant-time comparison.
Conclusion
Securing Claude Managed Agent webhooks means more than checking a signature once. It means rotating secrets, handling replay protection, surviving retries without re-running side effects, and keeping verification consistent across every service that consumes events. Manual verification is possible (and the Anthropic SDK helpers make it easier than it used to be) but it's still infrastructure work that doesn't differentiate your product.
Get started with Hookdeck to verify, queue, retry, and replay your Claude webhooks without writing the boilerplate yourself. For more, see our guide to Claude webhook features and best practices and how to test and replay Claude webhooks locally.