Rotating secrets
POST /webhooks/{id}/rotate-secret returns a new plaintext secret and retires the old one.
To avoid a verification cliff while you redeploy, the retired secret keeps co-signing
alongside the new one for a grace window (WEBHOOK_SECRET_GRACE_HOURS, default 24h, capped
at 72h). During the window the Drazill-Webhook-Signature header contains both
candidates, so consumers on either secret verify.
Roll like this:
Rotate
Call POST /webhooks/{id}/rotate-secret and store the new secret. The plaintext is
returned once.
Because your verifier already accepts any matching candidate in a comma-separated
Drazill-Webhook-Signature header (see Signing & verification), you
need no special-casing for the rotation window — the same verify code handles one or two
candidates.
Drazill-Webhook-Secret-Version always reports the active secret’s version, even
during a two-candidate grace window (the retired co-signer’s version is not surfaced in a
header). Don’t assume the version maps one-to-one to which candidate verified — verify
against every candidate.
Backend and both SDK verifiers are tested against multi-candidate headers
(tests/test_webhooks.py::test_rotation_grace_window_signs_with_both_secrets,
sdks/python/tests/test_webhooks.py, sdks/typescript/src/__tests__/webhooks.test.ts).

