Webhook Consumers: Signature Checks and Replay Attack Defense

If your hiring pipeline trusts unsigned or replayable webhooks, an attacker can flip risk decisions, bypass verification, or poison audit trails. This is how to harden webhook rs

If a webhook can change hiring state, it is a security control surface. Authenticate it, bound it in time, and make it provable.
Back to all posts

The failure mode auditors actually care about

A compromised or mis-validated webhook consumer can do three things that hurt you fast: - Flip a candidate from "Review" to "Verified" and let them into interviews or offers. - Create irreconcilable records between systems, forcing exceptions right when you need defensibility. - Poison your audit trail by injecting fake event history that looks machine-generated and therefore "trustworthy" to non-technical reviewers. CISOs and GCs feel this as reputational blast radius. The incident is not "we got a bad webhook". The incident is "we cannot prove who changed a hiring control, why, and with what evidence".

Why webhook verification is a hiring control, not an integration detail

Hiring workflows are state machines with real consequences: interview access, assessment invitations, offer generation, and downstream provisioning. If your webhook consumer can be spoofed or replayed, you have an integrity vulnerability in the exact place where you claim controls exist. Checkr reports 31% of hiring managers say they have interviewed a candidate who later turned out to be using a false identity. This implies identity integrity is already a known pain inside hiring teams, so bypass paths will be exploited. It does not prove webhooks were the cause in those cases, but it does support treating verification events as security-relevant changes that require authentication and tamper resistance.

  • Evidence: Can you show the exact payload that triggered the status change, with signature verification results?

  • Control: Can you demonstrate replay defense and idempotency under test?

  • Governance: Can you explain retention, access controls, and an appeal path if a candidate disputes a decision?

Anti-patterns that make fraud worse

  • Accepting unsigned webhooks "because they come from a vendor IP range" - Using timestamps but not enforcing skew or storing nonce/event IDs - Retrying by reprocessing the same event without idempotency, then "fixing" the ATS manually

Reference architecture for resilient, defensible webhook consumption

A secure consumer has five layers, each observable and testable: Resilient connectivity matters in hiring: when the ATS is down, you should still validate and store events, then apply them once connectivity returns. Do not accept and apply later without freshness checks, or you create a replay window that attackers can exploit.

  1. Transport: TLS, strict allowlist of HTTP methods, size limits, and rate limits per tenant.

  2. Authentication: signature validation using tenant-scoped secrets or public keys. No shared global secret across customers.

  3. Freshness: timestamp validation with a tight skew window and explicit replay cache keyed by (tenant, event_id).

  4. Idempotency: durable dedupe to prevent double-processing when the sender retries or your ATS is down.

  5. Evidence: immutable logs that tie candidateId, requestId, signature result, and downstream write operations into a single trace.

  • A correlation ID that follows the candidate through ATS, verification, interview, and assessment systems

  • A single "event ledger" table keyed by tenant_id + event_id

  • A quarantine queue for events that fail signature or conflict with current state

Step-by-step: signature verification and replay defense

  1. Define your trust envelope per event type. Only allow webhooks to write specific fields. For example: verification webhooks can update "identity_status" and "risk_tier", but cannot advance stage to "Offer".

  2. Verify the signature before you parse business fields. Use constant-time compare, and validate canonicalization rules (raw body bytes vs JSON re-serialization).

  3. Enforce freshness. Require a sender timestamp and reject if outside your skew window (example: 5 minutes). This limits the replay horizon if an event is captured.

  4. Enforce uniqueness. Require a globally unique event_id from the sender. Store (tenant_id, event_id) in a durable idempotency store with TTL aligned to your audit policy.

  5. Separate acknowledgement from acceptance. Return 2xx quickly only when the signature and freshness checks pass. If downstream systems fail (ATS outage), enqueue for later processing but do not re-accept stale events past your skew window.

  6. Build a kill switch and canary rollout. Start with "log-only" mode for stricter checks, then enforce for a small cohort of reqs or tenants, then expand. If candidate experience degrades, flip back instantly.

  7. Produce an Evidence Pack per material state change. Store the signature verification outcome, the hashed body, the decision, and the downstream write result. Do not store biometrics in webhook logs. Link to IntegrityLens "Zero-Retention Biometrics" controls if applicable.

  • Validate signature and timestamp at ingress and store the validated event with a received_at time.

  • Apply to the ATS asynchronously with retries and circuit breakers.

  • If application happens after the freshness window, apply only if the event was previously validated and recorded in your ledger.

Webhook consumer policy you can hand to audit

Use this as a starting point for a tenant-scoped policy. It encodes signature verification, timestamp skew, replay cache rules, and a rollback switch.

Where IntegrityLens fits

IntegrityLens AI is the first hiring pipeline that combines a full Applicant Tracking System with advanced biometric identity verification, AI screening, and technical assessments so teams stop juggling tools and still move fast. In this webhook context, IntegrityLens helps you make verification and fraud signals defensible and hard to spoof across the workflow. Used by TA leaders, recruiting ops, and CISOs, IntegrityLens supports: - ATS workflow from source to offer with controlled field writes - Risk-Tiered Verification with identity checks completed in 2-3 minutes typical (document + voice + face) before interviews - 24/7 AI screening interviews and 40+ language technical assessments tied to a candidate identity - Evidence Packs that link events, decisions, and artifacts for audit without storing biometric data in logs - Idempotent Webhooks and integration patterns designed for resilient connectivity and traceability

IntegrityLens promo

Audit questions to pre-answer in your control narrative

If you want Legal and Audit to stop asking for ad hoc screenshots, document these answers up front: - What cryptographic method is used (HMAC vs asymmetric) and how are keys rotated? - What is the allowed clock skew and how do you handle vendor outages? - What is your replay defense mechanism and how long is the dedupe window? - What evidence is retained, for how long, and who can access it? - What is the candidate dispute and correction flow when systems disagree?

  • A sample event ledger record with signature_result=pass and a trace ID that maps to the ATS update

  • A negative test: same event_id replayed and rejected

  • A rollback demo: kill switch toggled, events quarantined, and manual review path engaged

Sources

Related Resources

Key takeaways

  • Treat webhook consumption as an access control boundary, not a convenience integration.
  • Verify signatures with key rotation, enforce timestamp skew, and reject replays with idempotency storage.
  • Log an audit-grade "Evidence Pack" that links event, decision, and actor without storing biometrics.
  • Build resilient connectivity: buffer safely when the ATS is down, and make rollbacks and kill switches routine.
Webhook consumer hardening policy (tenant-scoped)YAML policy

Drop this into your integration gateway or webhook service config as an enforceable contract between Security and Recruiting Ops.

It is designed to be auditable: explicit allowed writes, signature requirements, replay defense, and a kill switch for safe rollbacks.

version: 1
service: hiring-webhook-consumer
mode: enforce  # canary | enforce | log-only

tenantDefaults:
  maxBodyBytes: 262144
  allowedMethods: ["POST"]
  allowedContentTypes: ["application/json"]
  tlsRequired: true
  rateLimitPerMinute: 600

verificationEvents:
  provider: "IntegrityLens"
  endpointPath: "/webhooks/verification"

  auth:
    scheme: "hmac-sha256"
    signatureHeader: "X-IntegrityLens-Signature"
    timestampHeader: "X-IntegrityLens-Timestamp"
    eventIdHeader: "X-IntegrityLens-Event-Id"
    secretRef: "kms://tenants/{tenant_id}/secrets/webhook_hmac_v3"
    constantTimeCompare: true
    bodyCanonicalization: "raw-bytes"  # do not re-serialize JSON

  freshness:
    allowedClockSkewSeconds: 300
    rejectIfTimestampMissing: true

  replayDefense:
    idempotencyKey: "{tenant_id}:{event_id}"
    store: "redis://webhook-dedupe"
    ttlSeconds: 604800  # 7 days
    onDuplicate: "reject_409_and_log"

  writeGuards:
    # Map of ATS fields that this webhook is permitted to update
    permittedAtsFields:
      - "integritylens.identity_status"
      - "integritylens.risk_tier"
      - "integritylens.verification_completed_at"
    deniedAtsFields:
      - "ats.stage"
      - "ats.offer_status"

  failureHandling:
    killSwitch:
      enabled: false
      behavior: "quarantine"  # quarantine | drop
    onSignatureFail: "quarantine"
    onFreshnessFail: "quarantine"
    onAtsDown:
      behavior: "enqueue"
      queue: "gcs://verified-events-buffer"
      retryPolicy:
        maxAttempts: 12
        backoff: "exponential"

  evidencePack:
    logFields:
      - "tenant_id"
      - "candidate_id"
      - "event_id"
      - "received_at"
      - "signature_result"
      - "freshness_result"
      - "body_sha256"
      - "downstream_write_result"
    retentionDays: 180
    access:
      roleBased: true
      breakGlassApproval: "Security"

Outcome proof: What changes

Before

Webhook consumer accepted events based on network assumptions and processed retries without durable dedupe. Recruiting Ops sometimes corrected ATS statuses manually when systems disagreed, creating inconsistent audit trails.

After

Webhook ingestion enforces signature verification, timestamp skew, and tenant-scoped idempotency. Conflicting or invalid events are quarantined with an Evidence Pack, and ATS writes are field-scoped. Rollbacks are handled via a kill switch and canary modes.

Governance Notes: Legal and Security sign-off is supported by privacy-first evidence retention (store only hashes and decision metadata, not biometric payloads), Zero-Retention Biometrics principles for sensitive data, role-based access to Evidence Packs with break-glass approval, defined retention windows, and an appeal flow that lets Recruiting Ops re-run verification without manual tampering of historical records.

Implementation checklist

  • Require HMAC or asymmetric signatures on every webhook.
  • Validate timestamp and enforce an allowed skew window.
  • Reject duplicate event IDs per tenant with a durable idempotency store.
  • Separate transport acknowledgement (2xx) from business acceptance (processed vs quarantined).
  • Implement a kill switch and canary rollout for new verification rules.
  • Create a minimal, immutable audit log with correlation IDs and decision reasons.

Questions we hear from teams

Is IP allowlisting enough for webhook security?
No. IP allowlists help reduce noise, but they do not prove authenticity and can fail with vendor infrastructure changes or shared cloud egress. Auditors typically expect cryptographic verification for integrity.
What if the sender retries the same webhook for hours?
Your consumer should be idempotent. Accept the first valid event, record (tenant_id, event_id), and reject duplicates. If the ATS is down, store the validated event and apply later, without re-validating stale timestamps.
Do replay protections slow down candidate experience?
Not if implemented correctly. Signature and timestamp checks are milliseconds. The only candidate-visible impact should be fewer manual holds caused by inconsistent system state.

Ready to secure your hiring pipeline?

Let IntegrityLens help you verify identity, stop proxy interviews, and standardize screening from first touch to final offer.

Try it free Book a demo

Watch IntegrityLens in action

See how IntegrityLens verifies identity, detects proxy interviewing, and standardizes screening with AI interviews and coding assessments.

Related resources