Skip to main content

Rotating Webhook Secrets

Your webhook secret is the shared secret DVS uses to HMAC-sign every webhook delivery. Rotating it periodically (or immediately after any suspected exposure) is good practice.

When to rotate

  • Routine rotation: every 12 months by OSIGU policy.
  • Immediate rotation: if you suspect the secret has been exposed (committed to a public repo, leaked in logs, employee offboarded with access).
  • OSIGU-initiated: if OSIGU's monitoring detects suspicious signing or delivery patterns.

How rotation works

  1. 1Request rotation

    Email support@osigu.com with subject Webhook secret rotation — <your tenant slug>. Include the reason and the webhook endpoint ID (if you have it).

  2. 2OSIGU issues a new secret

    OSIGU's operator runs the admin endpoint and sends you the new plaintext secret via a secure channel (1Password vault link, encrypted email, in-person handoff — never plain email).

  3. 324-hour grace period

    For 24 hours after rotation, DVS continues to accept signature verification on both the new and the previous secret. This avoids dropped messages on in-flight webhooks. After 24 hours, only the new secret is valid.

  4. 4Update your receiver

    Update your environment variable / secret store with the new value. We strongly recommend supporting both secrets simultaneously during the grace period.

Receiver pattern: support two secrets during rotation

This pattern lets you switch secrets without dropped webhooks. Add the previous secret as a fallback for 24 hours, then remove it.

SECRETS = [
os.environ["DVS_WEBHOOK_SECRET_CURRENT"],
os.environ.get("DVS_WEBHOOK_SECRET_PREVIOUS"), # optional, only during grace window
]

def verify_with_any(raw_body, signature_header, timestamp_header):
for secret in SECRETS:
if secret and verify_dvs_signature(raw_body, signature_header, timestamp_header, secret):
return True
return False

After 24 hours, remove DVS_WEBHOOK_SECRET_PREVIOUS from your environment.

What DVS does during rotation

  • DVS signs all new webhooks with the new secret immediately.
  • The previous secret hash is retained for 24h and accepted by your receiver (as long as you implement the fallback above).
  • After 24 hours, the previous secret is purged from DVS storage.

What rotation does NOT do

  • Doesn't change your webhook URL.
  • Doesn't change your endpoint ID.
  • Doesn't pause webhook delivery — events continue to flow.

Lost the secret?

If you no longer have the secret (e.g., the only person with access left the company), you can't recover it from DVS — secrets are bcrypt-hashed on our side, never stored in plaintext. Request a rotation; OSIGU issues a fresh one.