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:
POSTrequestsContent-Type: application/json- JSON payloads containing fields such as:
ideventcreated_atorganization_iddata
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:
| Field | Purpose |
|---|---|
token_endpoint | Your OAuth token endpoint |
client_id | OAuth client ID issued to Verdocs |
client_secret | OAuth client secret issued to Verdocs |
scope | Optional 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_inexp
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
| Question | Better 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
The Recipient Auth Ladder
You configure a recipient with several auth_methods, including: passcode, email, SMS, ID scan, and KBA
Send an envelope without a template
Walk through the process of creating and sending an envelope when you already have a PDF (or DOCX) and do not want to create a Verdocs `Template` first.