Verdocs - Developer Documentation

Securing Your Webhooks: HMAC vs OAuth

Anyone on the internet can send an HTTP request to a public URL. Verdocs provides two ways to verify the caller is actually Verdocs: HMAC (shared-secret signatures) and OAuth client credentials (short-lived bearer tokens). Choose the model that best matches your platform’s existing security architecture.

The scenario

You expose: POST https://api.yourproduct.com/integrations/verdocs/events. A third party discovers the endpoint and sends a fake “envelope completed” event. Your backend trusts the payload and closes a deal automatically.

Or your security team mandates OAuth, but your gateway only supports static API-key validation and cannot validate rotating bearer tokens.

This guide focuses specifically on authenticating inbound webhook requests from Verdocs to your infrastructure.

It does not replace:

  • HTTPS/TLS
  • idempotency protection
  • payload validation
  • organization authorization checks

What Verdocs sends on the wire

Webhook deliveries are typically sent as:

  • POST requests
  • Content-Type: application/json
  • JSON payloads containing fields such as:
    • id
    • event
    • created_at
    • organization_id
    • data

Always treat the Webhooks reference as the source of truth for exact payload structures and field names.

Delivery expectations

Webhook handlers should respond quickly—typically within a few seconds.

Long-running tasks should be queued asynchronously after validation succeeds. Your endpoint should acknowledge receipt with a 2xx response once the request has been authenticated and accepted.

Do not block the response while downstream systems finish processing.


Option A — HMAC (shared secret)

Mental model

Verdocs and your application share a secret. Each webhook delivery includes a cryptographic signature derived from the payload. Your server recomputes the signature and verifies it matches. If an attacker does not know the secret, they cannot forge a valid request.


Configuration

In the Verdocs webhook configuration:

  • choose the HMAC authentication method
  • configure a shared secret

Store the same secret securely in your own infrastructure.


Verification flow

1. Read the raw request body

Read the request payload before modifying or reparsing it. Many integrations accidentally break verification by changing whitespace or serialization order before hashing.

2. Read the signature header

Verdocs sends a signature in: x-webhook-signature.

3. Recompute the HMAC

Use the documented signing algorithm (currently SHA-256 for modern integrations).

4. Compare securely

Use a constant-time comparison function to avoid timing attacks.

Reject requests when:

  • the header is missing
  • the signature does not match
  • the payload is malformed

Important implementation detail

The signature is tied to the event payload Verdocs defines in the webhook contract—not necessarily the entire outer request wrapper.

Always implement verification against the exact signing input documented in the Webhooks reference. If your computed hash disagrees with the reference behavior, the reference documentation is the contract.


Operational guidance

Rotate secrets periodically

Use the documented secret rotation workflow and coordinate deployment timing carefully.

Treat secrets like passwords

Never log secrets, commit them to source control, or expose them client-side


When HMAC fits well

HMAC is usually a good fit when:

  • your deployment model is simple
  • you want minimal infrastructure dependencies
  • you do not already operate OAuth token issuance infrastructure
  • your gateways validate static secrets more easily than bearer tokens

Option B — OAuth client credentials

Mental model

Verdocs acts as an OAuth client to your authorization server. Before sending webhooks, Verdocs requests an access token using the client_credentials grant.

Verdocs then calls your webhook endpoint using: Authorization: Bearer <token>


Configuration

Webhook settings include:

FieldPurpose
token_endpointYour OAuth token endpoint
client_idOAuth client ID issued to Verdocs
client_secretOAuth client secret issued to Verdocs
scopeOptional scope value if required by your issuer

The token request is typically sent as: application/x-www-form-urlencoded, using: grant_type=client_credentials.

Always confirm exact token request behavior against the current Webhooks reference if your OAuth provider has strict requirements.


Verification flow

1. Validate the bearer token

Use your normal API token validation path:

  • JWT signature verification
  • token introspection
  • API gateway enforcement
  • opaque token lookup

2. Verify audience or scope

Ensure the token is intended for:

  • the correct API
  • the correct route
  • the expected integration audience

3. Reject invalid requests

Reject requests with:

  • missing authorization headers
  • expired tokens
  • invalid signatures
  • insufficient scopes

Token reuse behavior

Verdocs may reuse tokens until expiration if your token response includes standard expiry metadata such as:

  • expires_in
  • exp

Short-lived access tokens are recommended for webhook integrations.

Very long-lived bearer tokens reduce the security benefits of OAuth mode.


When OAuth fits well

OAuth is often preferred when:

  • your organization already standardizes on OAuth2
  • security teams require centralized token issuance and auditing
  • your API platform already validates JWTs or opaque bearer tokens
  • you need audience, scope, or claims-based authorization

Choosing between them

QuestionBetter fit
Do we already issue OAuth clients to partners?OAuth
Do we want the simplest implementation possible?HMAC
Does our gateway only understand static secrets?HMAC
Do we require aud/scope-based authorization?OAuth

Many teams start with HMAC and later migrate to OAuth as platform maturity increases.

Both are supported webhook authentication patterns.


“None” is technically possible (but risky)

Some environments permit webhook endpoints with no additional authentication beyond HTTPS.

That may be acceptable for temporary development tunnels or local testing.

For production systems, assume URLs eventually leak and enable either:

  • HMAC authentication
  • OAuth authentication

Commonly asked questions

Should we validate organization_id?

Yes. Authentication proves who sent the request. Your application still needs authorization logic to ensure the event belongs to a recognized tenant or customer.


Is IP allowlisting enough?

IP allowlists should be treated as defense in depth, not the primary security mechanism. Cryptographic verification and bearer-token validation fail closed much more reliably.


Should webhook handlers be idempotent?

Strongly recommended. Retries and duplicate deliveries can occur. Use the webhook id or another stable event identifier to deduplicate processing.


Can we subscribe to only certain events?

Yes. Webhook configurations allow selecting specific event types. In production, subscribing narrowly reduces load and operational surprises.


Takeaway

  • HMAC uses a shared secret and request signature verification. It is operationally simple and works well for straightforward deployments.
  • OAuth client credentials uses short-lived bearer tokens issued by your authorization server. It fits best when OAuth is already your organization’s standard for machine-to-machine authentication.

Both approaches secure inbound webhook traffic effectively when implemented correctly.

Learn More: Webhooks · Web SDK v6.6.0 — webhook authentication

On this page